source: trunk/termtv/js/parser.js@ 17948

Last change on this file since 17948 was 17948, checked in by tbretz, 10 years ago
Replaced octal characters with hex-characters to avoid clashes with the strict language standard.
File size: 25.2 KB
Line 
1'use strict';
2
3// todo: vt102 printing (vt102 user guide, chapter 5, "printing")
4/**
5 * @constructor
6 */
7function TTVParser(term_cb, dbg)
8{
9 var parser = this;
10
11 parser.debug = function(txt)
12 {
13 dbg ? dbg("parse.js: "+txt) : alert("parse.js: "+txt);
14 }
15 parser.emu = term_cb;
16 parser.buffer = '';
17
18 return parser;
19};
20
21TTVParser.prototype.parse = function(str)
22{
23 /*
24 // This version would work very nicely if browswers would
25 // already support the y-modifier
26 if (!this.pos)
27 this.pos = 0;
28
29 while (this.pos<pos)
30 {
31 for (var i=0; i<this.handlables.length; i++)
32 {
33 // Check regex
34 this.handlables[i][0].lastIndex = this.pos;
35 var match = this.handlables[i][0].exec(str);
36 if (match && match[0].length>0)
37 {
38 // Call corresponding (callback-)function to process the match
39 this.handlables[i][1].call(this, match);
40
41 // Remove match from buffer
42 //this.buffer = this.buffer.substr(match[0].length);
43
44 //alert("i="+this.handlables[i][0].lastIndex+" "+match[0].length);
45
46 this.pos += match[0].length;//this.handlables[i][0].lastIndex;
47 break;
48 }
49 }
50 }
51 */
52
53 this.buffer += str;
54 while (this.handleBuffer()) { };
55};
56
57TTVParser.prototype.getBuffer = function()
58{
59 return this.buffer;
60}
61
62TTVParser.prototype.setBuffer = function(obj)
63{
64 this.buffer = obj;
65}
66
67TTVParser.prototype.handleBuffer = function()
68{
69 for (var i=0; i<this.handlables.length; i++)
70 {
71 // Check regex
72 var match = this.handlables[i][0].exec(this.buffer);
73 if (!match || match[0].length==0)
74 continue;
75
76 // FIXME: It is most probably much more efficient to
77 // check for the first character and in case of an escape
78 // sequence only compare the remaining string.
79
80 // Call corresponding (callback-)function to process the match
81 this.handlables[i][1].call(this, match);
82
83 // Remove match from buffer
84 this.buffer = this.buffer.substr(match[0].length);
85
86 return true;
87 }
88
89 // If we have not yet found the right escape sequence and
90 // the first character is an escape character, remove it.
91 // Otherwise we get stuck. We could do that as last check
92 // in the loop over the handlabels, but maybe a sequence
93 // ot split into to chunks.
94 if (this.buffer.length>50 && this.buffer[0]=='\x1b')
95 {
96 this.debug("Unknown escape sequence: "+
97 this.buffer[1].charCodeAt(0).toString(16)+" "+
98 this.buffer[2].charCodeAt(0).toString(16)+" "+
99 this.buffer[3].charCodeAt(0).toString(16)+" "+
100 this.buffer[4].charCodeAt(0).toString(16)+" "+
101 this.buffer[5].charCodeAt(0).toString(16)+" "+
102 this.buffer[6].charCodeAt(0).toString(16)+" "+
103 this.buffer[7].charCodeAt(0).toString(16)+" "+
104 this.buffer[8].charCodeAt(0).toString(16)+" "+
105 this.buffer[9].charCodeAt(0).toString(16)+" ["+this.buffer+"]");
106 this.emu.ev_normalString('\0');
107
108 this.buffer = this.buffer.substr(1);
109 }
110
111 return false;
112}
113
114// Should be ordered by frequency of occurance
115TTVParser.prototype.handlables =
116[
117 ////////////////////////////////////////////////////////////////////////////////
118 // UTF-8
119 // 1 byte: 0xxxxxxx // standard ascii
120 // 2 byte: 110xxxxx 10xxxxxx // c0-c1
121 // 3 byte: 1110xxxx 10xxxxxx 10xxxxxx // f5-ff
122 // 4 byte: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
123
124 // ascii // Everything except escape, special chars and 1xxxx xxxx
125 // was: [/^[^\x1b\007\010\011\012\013\014\015\016\017\x80-\xFF]?/,
126 [/^[\x20-\x7F]+/, function (m) {
127 this.emu.ev_normalString(m[0]);
128 }],
129 //[/^([\x80-\xC1]|[\xF5-\xFF])/, function (m) {
130 // this.debug("Malformed unicode[1]: "+m[0].charCodeAt(0).toString(16));
131 // this.cb('normalString', '\0');
132 //}],
133
134 // was: [/^[\xC2\xDF][\x80-\xBF]/
135 [/^[\xC2-\xDF][\x80-\xBF]/, function (m) {
136 var p1 = m[0].charCodeAt(0) & 0x1f; // 0001 1111
137 var p2 = m[0].charCodeAt(1) & 0x3f; // 0011 1111
138 var code = (p1<<6) | p2;
139 this.emu.ev_normalString(String.fromCharCode(code));
140 }],
141 //[/^[\xC2-\xDF][\x00-\xFF]/, function (m) {
142 // this.debug("Malformed unicode[2]: "+m[0].charCodeAt(0).toString(16)+" "+m[0].charCodeAt(1).toString(16));
143 // this.cb('normalString', '\0');
144 //}],
145
146
147 ////////////////////////////////////////////////////////////////////////////////
148 // attributes (colors)
149 [/^\x1b\[([0-9;]*)m/, function (m) {
150 this.emu.ev_setAttribute(m[1].split(';'));
151 }],
152 ////////////////////////////////////////////////////////////////////////////////
153
154
155 // was: [/^(\xE0[\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|\xED[\x80-\x9F]|[\xEE-\xEF][\x80-\xBF])[\x80-\xBF]/
156 [/^[\xE0-\xEF][\x80-\xBF][\x80-\xBF]/, function (m) {
157 var p1 = m[0].charCodeAt(0) & 0x0f; // 0000 1111
158 var p2 = m[0].charCodeAt(1) & 0x3f; // 1000 0000
159 var p3 = m[0].charCodeAt(2) & 0x3f; // 1000 0000
160 var code = (p1<<12) | (p2<<6) | p3;
161 this.emu.ev_normalString(String.fromCharCode(code));
162 }],
163 //[/^[\xE0-\xEF][\x00-\xFF][\x00-\xFF]/, function (m) {
164 // this.debug("Malformed unicode[3]: "+m[0].charCodeAt(0).toString(16)+" "+m[0].charCodeAt(1).toString(16)+" "+m[0].charCodeAt(2).toString(16));
165 // this.cb('normalString', '\0');
166 //}],
167
168 // was: [/^(\xF0[\x90-\xBF]|[\xF1-\xF3][\x80-\xBF]|\xF4[\x80-\x8F])[\x80-\xBF][\x80-\xBF]/
169 [/^[\xF0-\xF4][\x80-\xBF][\x80-\xBF][\x80-\xBF]/, function (m) {
170 var p1 = m[0].charCodeAt(0) & 0x07; // 0000 0111
171 var p2 = m[0].charCodeAt(1) & 0x3f; // 0011 1111
172 var p3 = m[0].charCodeAt(2) & 0x3f; // 0011 1111
173 var p4 = m[0].charCodeAt(3) & 0x3f; // 0011 1111
174 var code = (p1<<18) | (p2<<12) | (p3<<6) | p4;
175 this.emu.ev_normalString(String.fromCharCode(code));
176 }],
177 //[/^[\xF0-\xF4][\x00-\xFF][\x00-\xFF][\x00-\xFF]/, function (m) {
178 // this.debug("Malformed unicode[4]: "+m[0].charCodeAt(0).toString(16)+" "+m[0].charCodeAt(1).toString(16)+" "+m[0].charCodeAt(3).toString(16)+" "+m[0].charCodeAt(4).toString(16));
179 // this.cb('normalString', '\0');
180 //}],
181
182 // This is how my shell processed unknown characters... if no proper unicode character
183 // is detected, the characters are interpreted one-by-one
184 [/^([\x80-\xFF])/, function (m) {
185 // The best thing we can do is to assume that this is
186 // 8bit ascii
187 this.emu.ev_normalString(m[0]);
188 // this.debug("Invalid code: "+m[0].charCodeAt(0).toString(16)+" ["+m[0]+"]");
189 // this.cb('normalString', '\0');
190 }],
191
192 ////////////////////////////////////////////////////////////////////////////////
193 // control characters
194 [/^\x07/, function (m) {
195 this.emu.ev_specialChar('bell');
196 }],
197 [/^\x08/, function (m) {
198 this.emu.ev_specialChar('backspace');
199 }],
200 [/^\x09/, function (m) {
201 this.emu.ev_specialChar('horizontalTab');
202 }],
203 [/^\x0a/, function (m) {
204 this.emu.ev_specialChar('lineFeed');
205 }],
206 [/^\x0b/, function (m) {
207 this.emu.ev_specialChar('verticalTab');
208 }],
209 [/^\x0c/, function (m) {
210 this.emu.ev_specialChar('formFeed');
211 }],
212 [/^\x0d/, function (m) {
213 this.emu.ev_specialChar('carriageReturn');
214 }],
215 [/^\x0e/, function (m) {
216 this.emu.ev_switchCharset('g1');
217 }],
218 [/^\x0f/, function (m) {
219 this.emu.ev_switchCharset('g0');
220 }],
221
222 [/^\x1bF/, function (m) { // vt52: enter graphics mode
223 //this.emu.ev_switchCharset('g0', 'line');
224 }],
225 [/^\x1bG/, function (m) { // vt52: exit graphics mode
226 //this.emu.ev_switchCharset('g0', 'us');
227 }],
228
229
230 ////////////////////////////////////////////////////////////////////////////////
231 // very often used: home and goto
232
233 [/^\x1b\[[Hf]/, function (m) {
234 this.emu.ev_goto( 1, 1 );
235 }],
236 [/^\x1b\[([0-9]*)G/, function (m) {
237 this.emu.ev_goto(parseInt(m[1] || '1', 10), -1); // y=-1 (keep line)
238 }],
239
240 // cursor set position
241 [/^\x1b\[([0-9]*);([0-9]*)[Hf]/, function (m) {
242 this.emu.ev_goto(parseInt(m[2] || '1', 10), parseInt(m[1] || '1', 10));
243 }],
244 [/^\x1b\[([0-9]*)d/, function (m) {
245 this.emu.ev_goto(1, parseInt(m[1] || '1', 10));
246
247 }],
248
249 ////////////////////////////////////////////////////////////////////////////////
250 // obsolete control characters
251
252 [/^[\x00-\x06]/, function() { } ],
253 [/^[\x10-\x1a]/, function() { } ],
254 [/^[\x1c-\x1f]/, function() { } ],
255/*
256 [/^\000/, function (m) {
257 this.cb('specialChar', 'null');
258 }],
259 [/^\001/, function (m) {
260 this.cb('specialChar', 'startOfHeading');
261 }],
262 [/^\002/, function (m) {
263 this.cb('specialChar', 'startOfText');
264 }],
265 [/^\003/, function (m) {
266 this.cb('specialChar', 'endOfText');
267 }],
268 [/^\004/, function (m) {
269 this.cb('specialChar', 'endOfTransmission');
270 }],
271 [/^\005/, function (m) {
272 this.cb('specialChar', 'enquiry');
273 }],
274 [/^\006/, function (m) {
275 this.cb('specialChar', 'acknoledge');
276 }],
277
278 [/^\020/, function (m) {
279 this.cb('specialChar', 'dataLinkEscape');
280 }],
281 [/^\021/, function (m) {
282 this.cb('specialChar', 'deviceControl1');
283 }],
284 [/^\022/, function (m) {
285 this.cb('specialChar', 'deviceControl2');
286 }],
287 [/^\023/, function (m) {
288 this.cb('specialChar', 'deviceControl3');
289 }],
290 [/^\024/, function (m) {
291 this.cb('specialChar', 'deviceControl4');
292 }],
293 [/^\025/, function (m) {
294 this.cb('specialChar', 'negativeAcknowledge');
295 }],
296 [/^\026/, function (m) {
297 this.cb('specialChar', 'synchronousIdle');
298 }],
299 [/^\027/, function (m) {
300 this.cb('specialChar', 'endOfTransmissionBlok');
301 }],
302 [/^\030/, function (m) {
303 this.cb('specialChar', 'cancel');
304 }],
305 [/^\031/, function (m) {
306 this.cb('specialChar', 'endOfMedium');
307 }],
308 [/^\032/, function (m) {
309 this.cb('specialChar', 'substitute');
310 }],
311 [/^\034/, function (m) {
312 this.cb('specialChar', 'fileSeparator');
313 }],
314 [/^\035/, function (m) {
315 this.cb('specialChar', 'groupSeparator');
316 }],
317 [/^\036/, function (m) {
318 this.cb('specialChar', 'recordSeparator');
319 }],
320 [/^\037/, function (m) {
321 this.cb('specialChar', 'unitSeparator');
322 }],
323 */
324
325 ////////////////////////////////////////////////////////////////////////////////
326
327 // erase in line
328 [/^\x1b\[0?K/, function (m) {
329 this.emu.ev_eraseInLine('toEnd');
330 }],
331 [/^\x1b\[1K/, function (m) {
332 this.emu.ev_eraseInLine('toStart');
333 }],
334 [/^\x1b\[2K/, function (m) {
335 this.emu.ev_eraseInLine('whole');
336 }],
337 [/^\x1bK/, function (m) { // vt52
338 this.emu.ev_eraseInLine('toEnd');
339 }],
340
341 // erase in display
342 [/^\x1b\[0?J/, function (m) {
343 this.emu.ev_eraseInDisplay('toEnd');
344 }],
345 [/^\x1b\[1J/, function (m) {
346 this.emu.ev_eraseInDisplay('toStart');
347 }],
348 [/^\x1b\[2J/, function (m) {
349 this.emu.ev_eraseInDisplay('whole');
350 }],
351 [/^\x1bJ/, function (m) { // vt52
352 this.emu.ev_eraseInDisplay('toEnd');
353 }],
354
355 // insertion and deletion
356 [/^\x1b\[([0-9]*)P/, function (m) {
357 this.emu.ev_deleteChars(parseInt(m[1] || '1', 10));
358 }],
359 [/^\x1b\[([0-9]*)X/, function (m) {
360 this.emu.ev_deleteChars(parseInt(m[1] || '1', 10));
361 }],
362 [/^\x1b\[([0-9]*)L/, function (m) {
363 this.emu.ev_insertLines(parseInt(m[1] ||'1', 10));
364 }],
365 [/^\x1b\[([0-9]*)M/, function (m) {
366 this.emu.ev_deleteLines(parseInt(m[1] || '1', 10));
367 }],
368 [/^\x1b\[([0-9])*@/, function (m) { // insert N characters
369 this.emu.ev_insertChars(parseInt(m[1] || '1', 10));
370 //this.emu.ev_mode('insertLimited', parseInt(m[1] || '1', 10));
371 }],
372
373 // margins
374 [/^\x1b\[([0-9]+);([0-9]+)r/, function (m) {
375 this.emu.ev_setMargins(parseInt(m[1], 10), parseInt(m[2], 10));
376 }],
377 [/^\x1b\[r/, function (m) {
378 this.emu.ev_resetMargins();
379 }],
380
381 ////////////////////////////////////////////////////////////////////////////////
382 // control sequences
383
384 // 3: italic (rxvt)
385 // 6: overline (eterm)
386 // 9: strikeout (gnome, guake, nautilus, terminator, xfce4, vte)
387 [/^\x1b\[\[([0-9;]*)m/, function (m) {
388 }],
389
390
391 // arrow keys
392 [/^\x1b\[([0-9]*)A/, function (m) {
393 this.emu.ev_arrow('up', parseInt(m[1] || '1', 10));
394 }],
395 [/^\x1b\[([0-9]*)B/, function (m) {
396 this.emu.ev_arrow('down', parseInt(m[1] || '1', 10));
397 }],
398 [/^\x1b\[([0-9]*)C/, function (m) {
399 this.emu.ev_arrow('right', parseInt(m[1] || '1', 10));
400 }],
401 [/^\x1b\[([0-9]*)D/, function (m) {
402 this.emu.ev_arrow('left', parseInt(m[1] || '1', 10));
403 }],
404 [/^\x1b\[([0-9]*)E/, function (m) {
405 this.emu.ev_index('nextLine', parseInt(m[1] || '1', 10));
406 }],
407 [/^\x1b\[([0-9]*)F/, function (m) {
408 this.emu.ev_index('prevLine', parseInt(m[1] || '1', 10));
409 }],
410
411 [/^\x1bA([\x20-\x7F]?)/, function (m) { // vt52
412 this.emu.ev_arrow('up', m[1] ? m[1].charCodeAt(0)-32+1 : 1);
413 }],
414 [/^\x1bB([\x20-\x7F]?)/, function (m) { // vt52
415 this.emu.ev_arrow('down', m[1] ? m[1].charCodeAt(0)-32+1 : 1);
416 }],
417 [/^\x1bC([\x20-\x7F]?)/, function (m) { // vt52
418 this.emu.ev_arrow('right', m[1] ? m[1].charCodeAt(0)-32+1 : 1);
419 }],
420 [/^\x1bD/, function (m) { // vt52
421 this.emu.ev_arrow('left', 1);
422 }],
423 [/^\x1bY(..)/, function (m) { // vt52
424 this.emu.ev_goto(m[1].charCodeAt(1)-32+1, m[1].charCodeAt(0)-32+1);
425 }],
426
427 // vt52: \x1bI reverse line feed
428 // \x1bl move to first line (keep x)
429
430 // cursor to lower left corner (vt100)
431 //[/^\x1bF/, function (m) {
432 //}],
433
434 // \x1b[{n}Z cursor back tab
435 // \x1b[{n}I cursor horizontal tab
436 // \x1b[{n}W cursor tab stop control
437 // \x1b[{n}Y cursor vertical tab
438 // \x1b[{n}P delete character
439 // \x1b#8 screen alignment display
440 // \x1b[H horizontal tab stop
441
442
443 // index and friends
444 [/^\x1bD/, function (m) {
445 this.emu.ev_index('down', 1);
446 }],
447 [/^\x1bM/, function (m) {
448 this.emu.ev_index('up', 1);
449 }],
450 [/^\x1bE/, function (m) {
451 this.emu.ev_index('nextLine', 1);
452 }],
453
454
455 // \x1b[6] back index
456 // \x1b[9] forward index
457
458 // cursor save/restore
459 // Saves in terminal memory the:
460 // cursor position
461 // graphic rendition
462 // character set shift state
463 // state of wrap flag
464 // state of origin mode
465 // state of selective erase
466 [/^\x1b[7]/, function (m) {
467 this.emu.ev_cursorStack('push', true);
468 }],
469 [/^\x1b[8]/, function (m) {
470 this.emu.ev_cursorStack('pop', true);
471 }],
472 // cursor save/restore position only
473 [/^\x1b\[s/, function (m) {
474 this.emu.ev_cursorStack('push', false);
475 }],
476 [/^\x1b\[u/, function (m) {
477 this.emu.ev_cursorStack('pop', false);
478 }],
479
480 // keypad
481 [/^\x1b=/, function (m) {
482 this.emu.ev_mode('keypad', 'cursor');
483 }],
484 [/^\x1b>/, function (m) {
485 this.emu.ev_mode('keypad', 'numeric');
486 }],
487
488 // mode set/reset
489 //[/^\x1b\[(\??)([^\x1b]*?)h/, function (m) {
490 [/^\x1b\[(\??)([0-9;]+)h/, function (m) {
491 var me = this;
492 m[2].split(';').forEach(function (sub) {
493 me.setMode(m[1] + sub);
494 });
495 }],
496 //[/^\x1b\[(\??)([^\x1b]*?)l/, function (m) {
497 [/^\x1b\[(\??)([0-9;]+)l/, function (m) {
498 var me = this;
499 m[2].split(';').forEach(function (sub) {
500 me.resetMode(m[1] + sub);
501 });
502 }],
503
504 // curser layout; '\x1b[?17;0;0c' hide cursor
505 [/^\x1b\[\?([0-9;]*)c/, function (m) {
506 this.debug("cursor layout"+m[1]);
507 }],
508
509 // horizontal tab stops
510 [/^\x1bH/, function (m) {
511 //this.emu.ev_tabStop('add'); // set a tab stop at the current position
512 this.emu.ev_goto( 1, 1); // vt52: home
513 }],
514 [/^\x1b\[0?g/, function (m) {
515 this.emu.ev_tabStop('remove'); // clear tabs at the current position
516 }],
517 [/^\x1b\[3g/, function (m) {
518 this.emu.ev_tabStop('clear'); // clear all tab stops
519 }],
520
521 // line attributes
522 [/^\x1b#3/, function (m) {
523 this.emu.ev_lineAttr('dwdhTopHalf');
524 }],
525 [/^\x1b#4/, function (m) {
526 this.emu.ev_lineAttr('dwdhBottomHalf');
527 }],
528 [/^\x1b#5/, function (m) {
529 this.emu.ev_lineAttr('swsh');
530 }],
531 [/^\x1b#6/, function (m) {
532 this.emu.ev_lineAttr('dwsh');
533 }],
534
535 // erase in area
536 // \x1b\[0?K toEnd
537 // \x1b\[1K toStart
538 // \x1b\[2K whole
539
540 // erase in field
541 // \x1b\[0?N toEnd
542 // \x1b\[1N toStart
543 // \x1b\[2N whole
544
545 // erase character
546 // \x1b[{N}X
547
548 // \x1b[{N}T scroll down
549 // \x1b[{N}S scroll up
550
551
552 // There is \x1b[?...J as well (erase "selective" in display)
553 // There is \x1b[?...K as well (erase "selective" in line)
554
555 // \x1bV Start of guarded area
556 // \x1bW End of guarded area
557
558 // \x1bl Lock memory above cursor
559 // \x1bm Unlock memory above cursor
560
561 // reset
562 [/^\x1b\[!p/, function (m) {
563 this.emu.ev_softReset();
564 }],
565 [/^\x1bc/, function (m) {
566 this.emu.ev_reset();
567 }],
568
569 // resize terminal: \e[8;{height};{width}t
570 [/^\x1b\[([0-9;]*)t/, function (m) {
571 }],
572
573 // xterm-style titles
574 [/^\x1b\]2;([^\x1b\x07]*)\x07/, function (m) {
575 this.emu.ev_setWindowTitle(m[1]);
576 }],
577 [/^\x1b\]1;([^\x1b\x07]*)\x07/, function (m) {
578 this.emu.ev_setIconTitle(m[1]);
579 }],
580 [/^\x1b\]0;([^\x1b\x07]*)\x07/, function (m) {
581 this.emu.ev_setWindowIconTitle(m[1]);
582 }],
583
584 // character set selection
585 // United kingdom: (A, )A, *A, +A [g0, g1, g2, g3]
586 // USASCII: (B, )B, *B, +B [g0, g1, g2, g3]
587 // graphics: (0, )0, *0, +0 [g0, g1, g2, g3]
588 // graphics: (1, )1, *1, +1 [g0, g1, g2, g3]
589 // graphics: (2, )2, *2, +2 [g0, g1, g2, g3]
590 [/^\x1b\$?([()*+-./])([ABCEHKQRYZ0124567=])/, function (m) {
591 this.emu.ev_setCharset(m[1], m[2]);
592 }],
593
594 // temporary character set
595 [/^\x1bN(a|[^a])/, function (m) {
596 this.emu.ev_g2char(m[1]);
597 }],
598 [/^\x1bO(a|[^a])/, function (m) {
599 this.emu.ev_g3char(m[1]);
600 }],
601
602 // reports (skipped, we are not emulating an interactive terminal)
603 [/^\x1b([0-9;?]*)n/, function (m) {
604 /*var me = this;
605 m[1].split(';').forEach(function (r) {
606 me.handleReportRequest(r);
607 });*/
608 }],
609 [/^\x1b(\[0?c|Z)/, function (m) {
610 //this.emu.ev_report('deviceAttributes');
611 }],
612 [/^\x1b\[>c/, function (m) {
613 //this.emu.ev_report('versionString');
614 }],
615
616 // LEDs
617 [/^\x1b\[([0-9;]*)q/, function (m) {
618 var me = this;
619 (m[1].length ? m[1] : '0').split(';').forEach(function (l) {
620 me.handleLED(l);
621 });
622 }],
623
624 // printing (we son't have to support that
625 // Print current screen, 1: print current line,
626 // 4: disable log, 5: enable log (echo to printer)
627 [/^\x1b\[[145]?i/, function (m) {
628 }],
629
630 //
631 [/^\x1b\[([0-9;]*)y/, function (m) {
632 this.emu.ev_hardware('selfTestRaw', m[1]);
633 }],
634 [/^\x1b#8/, function (m) {
635 this.emu.ev_hardware('screenAlignment');
636 }],
637
638 // xterm: select default character set (ISO8859-1)
639 [/^\x1b%@/, function (m) {
640 //enable utf8?
641 //this.cb('mode', 'utf8');
642 }],
643 // xterm: select default character set (ISO2022)
644 [/^\x1b%G/, function (m) {
645 //enable utf8?
646 //this.cb('mode', 'utf8');
647 }],
648
649 // screensaver control
650 [/^\x1b\[9;([0-9]+)\]/, function (m) {
651 //this.emu.ev_mode('borderColor', [ m[1], m[2] ]);
652 // \x1b[9;X] X in minutes (0 off)
653 }],
654
655 // My extension to control the 'border color'
656 [/^\x1b\[([0-9]+)(;[0-9]+)?\xb0/, function (m) {
657 this.emu.ev_mode('borderColor', [ m[1], m[2] ? m[2].substr(1) : null ]);
658 }]
659];
660
661TTVParser.prototype.setMode = function (mode)
662{
663 switch (mode)
664 {
665 // cursor keys in applications mode
666 case '?1':
667 this.emu.ev_mode('cursorKeyANSI', false);
668 break;
669
670 case '?3':
671 this.emu.ev_mode('width', 132);
672 break;
673
674 case '?4':
675 this.emu.ev_mode('scroll', 'smooth');
676 break;
677
678 case '?5':
679 this.emu.ev_mode('reverseScreen', true);
680 break;
681
682 case '?6':
683 this.emu.ev_mode('originMode', 'margin');
684 break;
685
686 case '?7':
687 this.emu.ev_mode('autoWrap', true);
688 break;
689
690 case '?8':
691 this.emu.ev_mode('autoRepeat', true);
692 break;
693
694 case '?9':
695 this.emu.ev_mode('mouseTrackingDown', true);
696 break;
697
698 case '?12':
699 this.emu.ev_mode('cursorBlink', true);
700 break;
701
702 case '?25':
703 this.emu.ev_mode('cursor', true);
704 break;
705
706 // xterm
707 // case '?34': // right to left mode
708 // case '?42': // hide/show scroll bar
709 // case '?43': // history on/off
710 // case '?44': // margin bell on/off
711 // case '?45': // reverse wrap around on/off
712 // case '?48': // reverse/normal status line
713 // case '?49': // page/normal scroll mode
714 // case '?E': // erase status line
715 // case '?F': // return from status line
716 // case '?H': // hide status line
717 // case '?S': // show status line
718 // case '?{N}T': // goto column {N} of status line
719
720
721 case '?47':
722 this.emu.ev_mode('currentScreen', 0);
723 break;
724
725 case '?69':
726 // Left right margin mode
727 //this.cb('mode', 'currentScreen', 1);
728 break;
729
730 case '?1000':
731 this.emu.ev_mode('mouseTrackingUp', true);
732 break;
733
734 case '?1034':
735 this.emu.ev_mode('metaKey', true);
736 break;
737
738 case '?1047':
739 this.emu.ev_mode('currentScreen', 0);
740 break;
741
742 case '?1048':
743 this.emu.ev_cursorStack('push', true);
744 break;
745
746 case '?1049':
747 this.emu.ev_cursorStack('push', true);
748 this.emu.ev_mode('currentScreen', 0);
749 this.emu.ev_eraseInLine('whole');
750 break;
751
752 case '2':
753 this.emu.ev_mode('keyboardLocked', true);
754 break;
755
756 case '4':
757 this.emu.ev_mode('insert', true);
758 break;
759
760 case '12':
761 this.emu.ev_mode('localEcho', false);
762 break;
763
764 case '20':
765 this.emu.ev_mode('newLineMode', 'crlf');
766 break;
767
768 default:
769 this.debug('Unhandled set mode: "' + mode + '"');
770 }
771};
772
773TTVParser.prototype.resetMode = function (mode)
774{
775 switch (mode)
776 {
777 // cursor keys in cursor positioning mode
778 case '?1':
779 this.emu.ev_mode('cursorKeyANSI', true);
780 break;
781
782 case '?2':
783 this.emu.ev_mode('vt52', true);
784 break;
785
786 case '?3':
787 this.emu.ev_mode('width', 80);
788 break;
789
790 case '?4':
791 this.emu.ev_mode('scroll', 'jump');
792 break;
793
794 case '?5':
795 this.emu.ev_mode('reverseScreen', false);
796 break;
797
798 case '?6':
799 this.emu.ev_mode('originMode', 'screen');
800 break;
801
802 case '?7':
803 this.emu.ev_mode('autoWrap', false);
804 break;
805
806 case '?8':
807 this.emu.ev_mode('autoRepeat', false);
808 break;
809
810 case '?9':
811 this.emu.ev_mode('mouseTrackingDown', false);
812 break;
813
814 case '?12':
815 this.emu.ev_mode('cursorBlink', false);
816 break;
817
818 case '?25':
819 this.emu.ev_mode('cursor', false);
820 break;
821
822 case '?47':
823 this.emu.ev_mode('currentScreen', 1);
824 break;
825
826 case '?69':
827 // Left right amrgin mode
828 //this.cb('mode', 'currentScreen', 1);
829 break;
830
831 case '?1000':
832 this.emu.ev_mode('mouseTrackingUp', false);
833 break;
834
835 case '?1034':
836 this.emu.ev_mode('metaKey', false);
837 break;
838
839 case '?1047':
840 this.emu.ev_eraseInLine('whole');
841 this.emu.ev_mode('currentScreen', 1);
842 break;
843
844 case '?1048':
845 this.emu.ev_cursorStack('pop', true);
846 break;
847
848 case '?1049':
849 this.emu.ev_mode('currentScreen', 1);
850 this.emu.ev_cursorStack('pop', true);
851 break;
852
853 case '2':
854 this.emu.ev_mode('keyboardLocked', false);
855 break;
856
857 case '4':
858 this.emu.ev_mode('insert', false);
859 break;
860
861 case '12':
862 this.emu.ev_mode('localEcho', true);
863 break;
864
865 case '20':
866 this.emu.ev_mode('newLineMode', 'cr');
867 break;
868
869 default:
870 this.debug('Unhandled reset mode: "' + mode + '"');
871 }
872};
873
874/*
875TTVParser.prototype.handleReportRequest = function (req)
876{
877 switch (req)
878 {
879 case '5':
880 this.emu.ev_report('status');
881 break;
882
883 case '?15':
884 this.emu.ev_report('printer');
885 break;
886
887 case '6':
888 this.emu.ev_report('cursorPosition');
889 break;
890
891 default:
892 this.debug('Unhandled report request: "' + req + '"');
893 }
894};*/
895
896TTVParser.prototype.handleLED = function (led)
897{
898 led = parseInt(led, 10);
899 if ( led == 0 ) {
900 this.emu.ev_led('off', 'all');
901 } else {
902 this.emu.ev_led('on', led);
903 }
904}
Note: See TracBrowser for help on using the repository browser.