1 |
|
2 |
|
3 |
|
4 |
|
5 | var normal = 0
|
6 | , escaped = 1
|
7 | , csi = 2
|
8 | , osc = 3
|
9 | , charset = 4
|
10 | , dcs = 5
|
11 | , ignore = 6;
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | var EventEmitter = require('events').EventEmitter;
|
18 |
|
19 | module.exports = Terminal;
|
20 | function Terminal(cols, rows, handler) {
|
21 | if (!(this instanceof Terminal)) return new Terminal(cols, rows, handler);
|
22 | EventEmitter.call(this);
|
23 |
|
24 | var options;
|
25 | if (typeof cols === 'object') {
|
26 | options = cols;
|
27 | cols = options.cols;
|
28 | rows = options.rows;
|
29 | handler = options.handler;
|
30 | }
|
31 | this._options = options || {};
|
32 |
|
33 | this.cols = cols || Terminal.geometry[0];
|
34 | this.rows = rows || Terminal.geometry[1];
|
35 |
|
36 | if (handler) {
|
37 | this.on('data', handler);
|
38 | }
|
39 |
|
40 | this.ybase = 0;
|
41 | this.ydisp = 0;
|
42 | this.x = 0;
|
43 | this.y = 0;
|
44 | this.cursorState = 0;
|
45 | this.cursorHidden = false;
|
46 | this.convertEol = false;
|
47 | this.state = 0;
|
48 | this.queue = '';
|
49 | this.scrollTop = 0;
|
50 | this.scrollBottom = this.rows - 1;
|
51 |
|
52 |
|
53 | this.applicationKeypad = false;
|
54 | this.originMode = false;
|
55 | this.insertMode = false;
|
56 | this.wraparoundMode = false;
|
57 | this.normal = null;
|
58 |
|
59 |
|
60 | this.charset = null;
|
61 | this.gcharset = null;
|
62 | this.glevel = 0;
|
63 | this.charsets = [null];
|
64 |
|
65 |
|
66 | this.decLocator;
|
67 | this.x10Mouse;
|
68 | this.vt200Mouse;
|
69 | this.vt300Mouse;
|
70 | this.normalMouse;
|
71 | this.mouseEvents;
|
72 | this.sendFocus;
|
73 | this.utfMouse;
|
74 | this.sgrMouse;
|
75 | this.urxvtMouse;
|
76 |
|
77 |
|
78 | this.element;
|
79 | this.children;
|
80 | this.refreshStart;
|
81 | this.refreshEnd;
|
82 | this.savedX;
|
83 | this.savedY;
|
84 | this.savedCols;
|
85 |
|
86 |
|
87 | this.readable = true;
|
88 | this.writable = true;
|
89 |
|
90 | this.defAttr = (257 << 9) | 256;
|
91 | this.curAttr = this.defAttr;
|
92 |
|
93 | this.params = [];
|
94 | this.currentParam = 0;
|
95 | this.prefix = '';
|
96 | this.postfix = '';
|
97 |
|
98 | this.lines = [];
|
99 | var i = this.rows;
|
100 | while (i--) {
|
101 | this.lines.push(this.blankLine());
|
102 | }
|
103 |
|
104 | this.tabs;
|
105 | this.setupStops();
|
106 | }
|
107 |
|
108 | inherits(Terminal, EventEmitter);
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 | Terminal.colors = [
|
116 |
|
117 | '#2e3436',
|
118 | '#cc0000',
|
119 | '#4e9a06',
|
120 | '#c4a000',
|
121 | '#3465a4',
|
122 | '#75507b',
|
123 | '#06989a',
|
124 | '#d3d7cf',
|
125 |
|
126 | '#555753',
|
127 | '#ef2929',
|
128 | '#8ae234',
|
129 | '#fce94f',
|
130 | '#729fcf',
|
131 | '#ad7fa8',
|
132 | '#34e2e2',
|
133 | '#eeeeec'
|
134 | ];
|
135 |
|
136 |
|
137 |
|
138 | Terminal.colors = (function() {
|
139 | var colors = Terminal.colors
|
140 | , r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]
|
141 | , i;
|
142 |
|
143 |
|
144 | i = 0;
|
145 | for (; i < 216; i++) {
|
146 | out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]);
|
147 | }
|
148 |
|
149 |
|
150 | i = 0;
|
151 | for (; i < 24; i++) {
|
152 | r = 8 + i * 10;
|
153 | out(r, r, r);
|
154 | }
|
155 |
|
156 | function out(r, g, b) {
|
157 | colors.push('#' + hex(r) + hex(g) + hex(b));
|
158 | }
|
159 |
|
160 | function hex(c) {
|
161 | c = c.toString(16);
|
162 | return c.length < 2 ? '0' + c : c;
|
163 | }
|
164 |
|
165 | return colors;
|
166 | })();
|
167 |
|
168 |
|
169 | Terminal.defaultColors = {
|
170 | bg: '#000000',
|
171 | fg: '#f0f0f0'
|
172 | };
|
173 |
|
174 | Terminal.colors[256] = Terminal.defaultColors.bg;
|
175 | Terminal.colors[257] = Terminal.defaultColors.fg;
|
176 |
|
177 |
|
178 |
|
179 |
|
180 |
|
181 | Terminal.termName = 'xterm';
|
182 | Terminal.geometry = [80, 24];
|
183 | Terminal.cursorBlink = true;
|
184 | Terminal.visualBell = false;
|
185 | Terminal.popOnBell = false;
|
186 | Terminal.scrollback = 1000;
|
187 | Terminal.screenKeys = false;
|
188 | Terminal.programFeatures = false;
|
189 | Terminal.debug = false;
|
190 |
|
191 |
|
192 |
|
193 |
|
194 |
|
195 | Terminal.focus = null;
|
196 |
|
197 | Terminal.prototype.focus = function() {
|
198 | if (Terminal.focus === this) return;
|
199 | if (Terminal.focus) {
|
200 | Terminal.focus.cursorState = 0;
|
201 | Terminal.focus.refresh(Terminal.focus.y, Terminal.focus.y);
|
202 | if (Terminal.focus.sendFocus) Terminal.focus.send('\x1b[O');
|
203 | }
|
204 | Terminal.focus = this;
|
205 | if (this.sendFocus) this.send('\x1b[I');
|
206 | this.showCursor();
|
207 | };
|
208 |
|
209 |
|
210 |
|
211 |
|
212 |
|
213 | Terminal.bindKeys = function() {
|
214 | if (Terminal.focus) return;
|
215 |
|
216 |
|
217 |
|
218 | on(document, 'keydown', function(ev) {
|
219 | return Terminal.focus.keyDown(ev);
|
220 | }, true);
|
221 |
|
222 | on(document, 'keypress', function(ev) {
|
223 | return Terminal.focus.keyPress(ev);
|
224 | }, true);
|
225 | };
|
226 |
|
227 |
|
228 |
|
229 |
|
230 |
|
231 | Terminal.prototype.open = function() {
|
232 | var self = this
|
233 | , i = 0
|
234 | , div;
|
235 |
|
236 | this.element = document.createElement('div');
|
237 | this.element.className = 'terminal';
|
238 | this.children = [];
|
239 |
|
240 | for (; i < this.rows; i++) {
|
241 | div = document.createElement('div');
|
242 | this.element.appendChild(div);
|
243 | this.children.push(div);
|
244 | }
|
245 |
|
246 |
|
247 |
|
248 | this.refresh(0, this.rows - 1);
|
249 |
|
250 |
|
251 | this.focus();
|
252 |
|
253 | this.startBlink();
|
254 |
|
255 | on(this.element, 'mousedown', function() {
|
256 | self.focus();
|
257 | });
|
258 |
|
259 |
|
260 |
|
261 |
|
262 | on(this.element, 'mousedown', function(ev) {
|
263 | var button = ev.button != null
|
264 | ? +ev.button
|
265 | : ev.which != null
|
266 | ? ev.which - 1
|
267 | : null;
|
268 |
|
269 |
|
270 | if (~navigator.userAgent.indexOf('MSIE')) {
|
271 | button = button === 1 ? 0 : button === 4 ? 1 : button;
|
272 | }
|
273 |
|
274 | if (button !== 2) return;
|
275 |
|
276 | self.element.contentEditable = 'true';
|
277 | setTimeout(function() {
|
278 | self.element.contentEditable = 'inherit';
|
279 | }, 1);
|
280 | }, true);
|
281 |
|
282 | on(this.element, 'paste', function(ev) {
|
283 | if (ev.clipboardData) {
|
284 | self.send(ev.clipboardData.getData('text/plain'));
|
285 | } else if (window.clipboardData) {
|
286 | self.send(window.clipboardData.getData('Text'));
|
287 | }
|
288 |
|
289 | self.element.contentEditable = 'inherit';
|
290 | return cancel(ev);
|
291 | });
|
292 |
|
293 | this.bindMouse();
|
294 |
|
295 |
|
296 | if (Terminal.brokenBold == null) {
|
297 | Terminal.brokenBold = isBoldBroken();
|
298 | }
|
299 |
|
300 |
|
301 | this.element.style.backgroundColor = Terminal.defaultColors.bg;
|
302 | this.element.style.color = Terminal.defaultColors.fg;
|
303 |
|
304 |
|
305 | };
|
306 |
|
307 |
|
308 |
|
309 |
|
310 |
|
311 |
|
312 |
|
313 |
|
314 |
|
315 | Terminal.prototype.bindMouse = function() {
|
316 | var el = this.element
|
317 | , self = this
|
318 | , pressed = 32;
|
319 |
|
320 | var wheelEvent = 'onmousewheel' in window
|
321 | ? 'mousewheel'
|
322 | : 'DOMMouseScroll';
|
323 |
|
324 |
|
325 |
|
326 |
|
327 | function sendButton(ev) {
|
328 | var button
|
329 | , pos;
|
330 |
|
331 |
|
332 | button = getButton(ev);
|
333 |
|
334 |
|
335 | pos = getCoords(ev);
|
336 | if (!pos) return;
|
337 |
|
338 | sendEvent(button, pos);
|
339 |
|
340 | switch (ev.type) {
|
341 | case 'mousedown':
|
342 | pressed = button;
|
343 | break;
|
344 | case 'mouseup':
|
345 |
|
346 |
|
347 | pressed = 32;
|
348 | break;
|
349 | case wheelEvent:
|
350 |
|
351 |
|
352 |
|
353 | break;
|
354 | }
|
355 | }
|
356 |
|
357 |
|
358 |
|
359 | function sendMove(ev) {
|
360 | var button = pressed
|
361 | , pos;
|
362 |
|
363 | pos = getCoords(ev);
|
364 | if (!pos) return;
|
365 |
|
366 |
|
367 |
|
368 | button += 32;
|
369 |
|
370 | sendEvent(button, pos);
|
371 | }
|
372 |
|
373 |
|
374 |
|
375 | function encode(data, ch) {
|
376 | if (!self.utfMouse) {
|
377 | if (ch === 255) return data.push(0);
|
378 | if (ch > 127) ch = 127;
|
379 | data.push(ch);
|
380 | } else {
|
381 | if (ch === 2047) return data.push(0);
|
382 | if (ch < 127) {
|
383 | data.push(ch);
|
384 | } else {
|
385 | if (ch > 2047) ch = 2047;
|
386 | data.push(0xC0 | (ch >> 6));
|
387 | data.push(0x80 | (ch & 0x3F));
|
388 | }
|
389 | }
|
390 | }
|
391 |
|
392 |
|
393 |
|
394 |
|
395 |
|
396 |
|
397 |
|
398 | function sendEvent(button, pos) {
|
399 |
|
400 |
|
401 |
|
402 |
|
403 |
|
404 |
|
405 | if (self.vt300Mouse) {
|
406 |
|
407 |
|
408 | button &= 3;
|
409 | pos.x -= 32;
|
410 | pos.y -= 32;
|
411 | var data = '\x1b[24';
|
412 | if (button === 0) data += '1';
|
413 | else if (button === 1) data += '3';
|
414 | else if (button === 2) data += '5';
|
415 | else if (button === 3) return;
|
416 | else data += '0';
|
417 | data += '~[' + pos.x + ',' + pos.y + ']\r';
|
418 | self.send(data);
|
419 | return;
|
420 | }
|
421 |
|
422 | if (self.decLocator) {
|
423 |
|
424 | button &= 3;
|
425 | pos.x -= 32;
|
426 | pos.y -= 32;
|
427 | if (button === 0) button = 2;
|
428 | else if (button === 1) button = 4;
|
429 | else if (button === 2) button = 6;
|
430 | else if (button === 3) button = 3;
|
431 | self.send('\x1b['
|
432 | + button
|
433 | + ';'
|
434 | + (button === 3 ? 4 : 0)
|
435 | + ';'
|
436 | + pos.y
|
437 | + ';'
|
438 | + pos.x
|
439 | + ';'
|
440 | + (pos.page || 0)
|
441 | + '&w');
|
442 | return;
|
443 | }
|
444 |
|
445 | if (self.urxvtMouse) {
|
446 | pos.x -= 32;
|
447 | pos.y -= 32;
|
448 | pos.x++;
|
449 | pos.y++;
|
450 | self.send('\x1b[' + button + ';' + pos.x + ';' + pos.y + 'M');
|
451 | return;
|
452 | }
|
453 |
|
454 | if (self.sgrMouse) {
|
455 | pos.x -= 32;
|
456 | pos.y -= 32;
|
457 | self.send('\x1b[<'
|
458 | + ((button & 3) === 3 ? button & ~3 : button)
|
459 | + ';'
|
460 | + pos.x
|
461 | + ';'
|
462 | + pos.y
|
463 | + ((button & 3) === 3 ? 'm' : 'M'));
|
464 | return;
|
465 | }
|
466 |
|
467 | var data = [];
|
468 |
|
469 | encode(data, button);
|
470 | encode(data, pos.x);
|
471 | encode(data, pos.y);
|
472 |
|
473 | self.send('\x1b[M' + String.fromCharCode.apply(String, data));
|
474 | }
|
475 |
|
476 | function getButton(ev) {
|
477 | var button
|
478 | , shift
|
479 | , meta
|
480 | , ctrl
|
481 | , mod;
|
482 |
|
483 |
|
484 |
|
485 |
|
486 |
|
487 |
|
488 |
|
489 |
|
490 | switch (ev.type) {
|
491 | case 'mousedown':
|
492 | button = ev.button != null
|
493 | ? +ev.button
|
494 | : ev.which != null
|
495 | ? ev.which - 1
|
496 | : null;
|
497 |
|
498 | if (~navigator.userAgent.indexOf('MSIE')) {
|
499 | button = button === 1 ? 0 : button === 4 ? 1 : button;
|
500 | }
|
501 | break;
|
502 | case 'mouseup':
|
503 | button = 3;
|
504 | break;
|
505 | case 'DOMMouseScroll':
|
506 | button = ev.detail < 0
|
507 | ? 64
|
508 | : 65;
|
509 | break;
|
510 | case 'mousewheel':
|
511 | button = ev.wheelDeltaY > 0
|
512 | ? 64
|
513 | : 65;
|
514 | break;
|
515 | }
|
516 |
|
517 |
|
518 |
|
519 | shift = ev.shiftKey ? 4 : 0;
|
520 | meta = ev.metaKey ? 8 : 0;
|
521 | ctrl = ev.ctrlKey ? 16 : 0;
|
522 | mod = shift | meta | ctrl;
|
523 |
|
524 |
|
525 | if (self.vt200Mouse) {
|
526 |
|
527 | mod &= ctrl;
|
528 | } else if (!self.normalMouse) {
|
529 | mod = 0;
|
530 | }
|
531 |
|
532 |
|
533 | button = (32 + (mod << 2)) + button;
|
534 |
|
535 | return button;
|
536 | }
|
537 |
|
538 |
|
539 | function getCoords(ev) {
|
540 | var x, y, w, h, el;
|
541 |
|
542 |
|
543 | if (ev.pageX == null) return;
|
544 |
|
545 | x = ev.pageX;
|
546 | y = ev.pageY;
|
547 | el = self.element;
|
548 |
|
549 |
|
550 |
|
551 | while (el !== document.documentElement) {
|
552 | x -= el.offsetLeft;
|
553 | y -= el.offsetTop;
|
554 | el = el.parentNode;
|
555 | }
|
556 |
|
557 |
|
558 | w = self.element.clientWidth;
|
559 | h = self.element.clientHeight;
|
560 | x = ((x / w) * self.cols) | 0;
|
561 | y = ((y / h) * self.rows) | 0;
|
562 |
|
563 |
|
564 |
|
565 | if (x < 0) x = 0;
|
566 | if (x > self.cols) x = self.cols;
|
567 | if (y < 0) y = 0;
|
568 | if (y > self.rows) y = self.rows;
|
569 |
|
570 |
|
571 |
|
572 | x += 32;
|
573 | y += 32;
|
574 |
|
575 | return {
|
576 | x: x,
|
577 | y: y,
|
578 | down: ev.type === 'mousedown',
|
579 | up: ev.type === 'mouseup',
|
580 | wheel: ev.type === wheelEvent,
|
581 | move: ev.type === 'mousemove'
|
582 | };
|
583 | }
|
584 |
|
585 | on(el, 'mousedown', function(ev) {
|
586 | if (!self.mouseEvents) return;
|
587 |
|
588 |
|
589 | sendButton(ev);
|
590 |
|
591 |
|
592 | self.focus();
|
593 |
|
594 |
|
595 | if (self.vt200Mouse) {
|
596 | sendButton({ __proto__: ev, type: 'mouseup' });
|
597 | return cancel(ev);
|
598 | }
|
599 |
|
600 |
|
601 | if (self.normalMouse) on(document, 'mousemove', sendMove);
|
602 |
|
603 |
|
604 | if (!self.x10Mouse) {
|
605 | on(document, 'mouseup', function up(ev) {
|
606 | sendButton(ev);
|
607 | if (self.normalMouse) off(document, 'mousemove', sendMove);
|
608 | off(document, 'mouseup', up);
|
609 | return cancel(ev);
|
610 | });
|
611 | }
|
612 |
|
613 | return cancel(ev);
|
614 | });
|
615 |
|
616 | on(el, wheelEvent, function(ev) {
|
617 | if (!self.mouseEvents) return;
|
618 | if (self.x10Mouse
|
619 | || self.vt300Mouse
|
620 | || self.decLocator) return;
|
621 | sendButton(ev);
|
622 | return cancel(ev);
|
623 | });
|
624 |
|
625 |
|
626 |
|
627 | on(el, wheelEvent, function(ev) {
|
628 | if (self.mouseEvents) return;
|
629 | if (self.applicationKeypad) return;
|
630 | if (ev.type === 'DOMMouseScroll') {
|
631 | self.scrollDisp(ev.detail < 0 ? -5 : 5);
|
632 | } else {
|
633 | self.scrollDisp(ev.wheelDeltaY > 0 ? -5 : 5);
|
634 | }
|
635 | return cancel(ev);
|
636 | });
|
637 | };
|
638 |
|
639 |
|
640 |
|
641 |
|
642 |
|
643 | Terminal.prototype.destroy = function() {
|
644 | this.readable = false;
|
645 | this.writable = false;
|
646 | this._events = {};
|
647 | this.handler = function() {};
|
648 | this.write = function() {};
|
649 |
|
650 | };
|
651 |
|
652 |
|
653 |
|
654 |
|
655 |
|
656 |
|
657 |
|
658 |
|
659 |
|
660 |
|
661 |
|
662 |
|
663 |
|
664 |
|
665 |
|
666 | Terminal.prototype.refresh = function(start, end) {
|
667 | var x
|
668 | , y
|
669 | , i
|
670 | , line
|
671 | , out
|
672 | , ch
|
673 | , width
|
674 | , data
|
675 | , attr
|
676 | , fgColor
|
677 | , bgColor
|
678 | , flags
|
679 | , row
|
680 | , parent;
|
681 |
|
682 | if (end - start >= this.rows / 2) {
|
683 | parent = this.element.parentNode;
|
684 | if (parent) parent.removeChild(this.element);
|
685 | }
|
686 |
|
687 | width = this.cols;
|
688 | y = start;
|
689 |
|
690 |
|
691 |
|
692 |
|
693 |
|
694 | for (; y <= end; y++) {
|
695 | row = y + this.ydisp;
|
696 |
|
697 | line = this.lines[row];
|
698 | out = '';
|
699 |
|
700 | if (y === this.y
|
701 | && this.cursorState
|
702 | && this.ydisp === this.ybase
|
703 | && !this.cursorHidden) {
|
704 | x = this.x;
|
705 | } else {
|
706 | x = -1;
|
707 | }
|
708 |
|
709 | attr = this.defAttr;
|
710 | i = 0;
|
711 |
|
712 | for (; i < width; i++) {
|
713 | data = line[i][0];
|
714 | ch = line[i][1];
|
715 |
|
716 | if (i === x) data = -1;
|
717 |
|
718 | if (data !== attr) {
|
719 | if (attr !== this.defAttr) {
|
720 | out += '</span>';
|
721 | }
|
722 | if (data !== this.defAttr) {
|
723 | if (data === -1) {
|
724 | out += '<span class="reverse-video">';
|
725 | } else {
|
726 | out += '<span style="';
|
727 |
|
728 | bgColor = data & 0x1ff;
|
729 | fgColor = (data >> 9) & 0x1ff;
|
730 | flags = data >> 18;
|
731 |
|
732 | if (flags & 1) {
|
733 | if (!Terminal.brokenBold) {
|
734 | out += 'font-weight:bold;';
|
735 | }
|
736 |
|
737 | if (fgColor < 8) fgColor += 8;
|
738 | }
|
739 |
|
740 | if (flags & 2) {
|
741 | out += 'text-decoration:underline;';
|
742 | }
|
743 |
|
744 | if (bgColor !== 256) {
|
745 | out += 'background-color:'
|
746 | + Terminal.colors[bgColor]
|
747 | + ';';
|
748 | }
|
749 |
|
750 | if (fgColor !== 257) {
|
751 | out += 'color:'
|
752 | + Terminal.colors[fgColor]
|
753 | + ';';
|
754 | }
|
755 |
|
756 | out += '">';
|
757 | }
|
758 | }
|
759 | }
|
760 |
|
761 | switch (ch) {
|
762 | case '&':
|
763 | out += '&';
|
764 | break;
|
765 | case '<':
|
766 | out += '<';
|
767 | break;
|
768 | case '>':
|
769 | out += '>';
|
770 | break;
|
771 | default:
|
772 | if (ch <= ' ') {
|
773 | out += ' ';
|
774 | } else {
|
775 | out += ch;
|
776 | }
|
777 | break;
|
778 | }
|
779 |
|
780 | attr = data;
|
781 | }
|
782 |
|
783 | if (attr !== this.defAttr) {
|
784 | out += '</span>';
|
785 | }
|
786 |
|
787 | this.children[y].innerHTML = out;
|
788 | }
|
789 |
|
790 | if (parent) parent.appendChild(this.element);
|
791 | };
|
792 |
|
793 | Terminal.prototype.cursorBlink = function() {
|
794 | if (Terminal.focus !== this) return;
|
795 | this.cursorState ^= 1;
|
796 | this.refresh(this.y, this.y);
|
797 | };
|
798 |
|
799 | Terminal.prototype.showCursor = function() {
|
800 | if (!this.cursorState) {
|
801 | this.cursorState = 1;
|
802 | this.refresh(this.y, this.y);
|
803 | } else {
|
804 |
|
805 |
|
806 | }
|
807 | };
|
808 |
|
809 | Terminal.prototype.startBlink = function() {
|
810 | if (!Terminal.cursorBlink) return;
|
811 | var self = this;
|
812 | this._blinker = function() {
|
813 | self.cursorBlink();
|
814 | };
|
815 | this._blink = setInterval(this._blinker, 500);
|
816 | };
|
817 |
|
818 | Terminal.prototype.refreshBlink = function() {
|
819 | if (!Terminal.cursorBlink) return;
|
820 | clearInterval(this._blink);
|
821 | this._blink = setInterval(this._blinker, 500);
|
822 | };
|
823 |
|
824 | Terminal.prototype.scroll = function() {
|
825 | var row;
|
826 |
|
827 | if (++this.ybase === Terminal.scrollback) {
|
828 | this.ybase = this.ybase / 2 | 0;
|
829 | this.lines = this.lines.slice(-(this.ybase + this.rows) + 1);
|
830 | }
|
831 |
|
832 | this.ydisp = this.ybase;
|
833 |
|
834 |
|
835 | row = this.ybase + this.rows - 1;
|
836 |
|
837 |
|
838 | row -= this.rows - 1 - this.scrollBottom;
|
839 |
|
840 | if (row === this.lines.length) {
|
841 |
|
842 |
|
843 |
|
844 |
|
845 | this.lines.push(this.blankLine());
|
846 | } else {
|
847 |
|
848 | this.lines.splice(row, 0, this.blankLine());
|
849 | }
|
850 |
|
851 | if (this.scrollTop !== 0) {
|
852 | if (this.ybase !== 0) {
|
853 | this.ybase--;
|
854 | this.ydisp = this.ybase;
|
855 | }
|
856 | this.lines.splice(this.ybase + this.scrollTop, 1);
|
857 | }
|
858 |
|
859 |
|
860 | this.updateRange(this.scrollTop);
|
861 | this.updateRange(this.scrollBottom);
|
862 | };
|
863 |
|
864 | Terminal.prototype.scrollDisp = function(disp) {
|
865 | this.ydisp += disp;
|
866 |
|
867 | if (this.ydisp > this.ybase) {
|
868 | this.ydisp = this.ybase;
|
869 | } else if (this.ydisp < 0) {
|
870 | this.ydisp = 0;
|
871 | }
|
872 |
|
873 | this.refresh(0, this.rows - 1);
|
874 | };
|
875 |
|
876 | Terminal.prototype.write = function(data) {
|
877 | var l = data.length
|
878 | , i = 0
|
879 | , cs
|
880 | , ch;
|
881 |
|
882 | this.refreshStart = this.y;
|
883 | this.refreshEnd = this.y;
|
884 |
|
885 | if (this.ybase !== this.ydisp) {
|
886 | this.ydisp = this.ybase;
|
887 | this.maxRange();
|
888 | }
|
889 |
|
890 |
|
891 |
|
892 | for (; i < l; i++) {
|
893 | ch = data[i];
|
894 | switch (this.state) {
|
895 | case normal:
|
896 | switch (ch) {
|
897 |
|
898 |
|
899 |
|
900 |
|
901 |
|
902 | case '\x07':
|
903 | this.bell();
|
904 | break;
|
905 |
|
906 |
|
907 | case '\n':
|
908 | case '\x0b':
|
909 | case '\x0c':
|
910 | if (this.convertEol) {
|
911 | this.x = 0;
|
912 | }
|
913 | this.y++;
|
914 | if (this.y > this.scrollBottom) {
|
915 | this.y--;
|
916 | this.scroll();
|
917 | }
|
918 | break;
|
919 |
|
920 |
|
921 | case '\r':
|
922 | this.x = 0;
|
923 | break;
|
924 |
|
925 |
|
926 | case '\x08':
|
927 | if (this.x > 0) {
|
928 | this.x--;
|
929 | }
|
930 | break;
|
931 |
|
932 |
|
933 | case '\t':
|
934 | this.x = this.nextStop();
|
935 | break;
|
936 |
|
937 |
|
938 | case '\x0e':
|
939 | this.setgLevel(1);
|
940 | break;
|
941 |
|
942 |
|
943 | case '\x0f':
|
944 | this.setgLevel(0);
|
945 | break;
|
946 |
|
947 |
|
948 | case '\x1b':
|
949 | this.state = escaped;
|
950 | break;
|
951 |
|
952 | default:
|
953 |
|
954 | if (ch >= ' ') {
|
955 | if (this.charset && this.charset[ch]) {
|
956 | ch = this.charset[ch];
|
957 | }
|
958 | if (this.x >= this.cols) {
|
959 | this.x = 0;
|
960 | this.y++;
|
961 | if (this.y > this.scrollBottom) {
|
962 | this.y--;
|
963 | this.scroll();
|
964 | }
|
965 | }
|
966 | this.lines[this.y + this.ybase][this.x] = [this.curAttr, ch];
|
967 | this.x++;
|
968 | this.updateRange(this.y);
|
969 | }
|
970 | break;
|
971 | }
|
972 | break;
|
973 | case escaped:
|
974 | switch (ch) {
|
975 |
|
976 | case '[':
|
977 | this.params = [];
|
978 | this.currentParam = 0;
|
979 | this.state = csi;
|
980 | break;
|
981 |
|
982 |
|
983 | case ']':
|
984 | this.params = [];
|
985 | this.currentParam = 0;
|
986 | this.state = osc;
|
987 | break;
|
988 |
|
989 |
|
990 | case 'P':
|
991 | this.params = [];
|
992 | this.currentParam = 0;
|
993 | this.state = dcs;
|
994 | break;
|
995 |
|
996 |
|
997 | case '_':
|
998 | this.stateType = 'apc';
|
999 | this.state = ignore;
|
1000 | break;
|
1001 |
|
1002 |
|
1003 | case '^':
|
1004 | this.stateType = 'pm';
|
1005 | this.state = ignore;
|
1006 | break;
|
1007 |
|
1008 |
|
1009 | case 'c':
|
1010 | this.reset();
|
1011 | break;
|
1012 |
|
1013 |
|
1014 |
|
1015 | case 'E':
|
1016 | this.x = 0;
|
1017 | ;
|
1018 | case 'D':
|
1019 | this.index();
|
1020 | break;
|
1021 |
|
1022 |
|
1023 | case 'M':
|
1024 | this.reverseIndex();
|
1025 | break;
|
1026 |
|
1027 |
|
1028 |
|
1029 | case '%':
|
1030 |
|
1031 | this.setgLevel(0);
|
1032 | this.setgCharset(0, Terminal.charsets.US);
|
1033 | this.state = normal;
|
1034 | i++;
|
1035 | break;
|
1036 |
|
1037 |
|
1038 | case '(':
|
1039 | case ')':
|
1040 | case '*':
|
1041 | case '+':
|
1042 | case '-':
|
1043 | case '.':
|
1044 | switch (ch) {
|
1045 | case '(':
|
1046 | this.gcharset = 0;
|
1047 | break;
|
1048 | case ')':
|
1049 | this.gcharset = 1;
|
1050 | break;
|
1051 | case '*':
|
1052 | this.gcharset = 2;
|
1053 | break;
|
1054 | case '+':
|
1055 | this.gcharset = 3;
|
1056 | break;
|
1057 | case '-':
|
1058 | this.gcharset = 1;
|
1059 | break;
|
1060 | case '.':
|
1061 | this.gcharset = 2;
|
1062 | break;
|
1063 | }
|
1064 | this.state = charset;
|
1065 | break;
|
1066 |
|
1067 |
|
1068 |
|
1069 |
|
1070 | case '/':
|
1071 | this.gcharset = 3;
|
1072 | this.state = charset;
|
1073 | i--;
|
1074 | break;
|
1075 |
|
1076 |
|
1077 |
|
1078 |
|
1079 | case 'N':
|
1080 | break;
|
1081 |
|
1082 |
|
1083 |
|
1084 | case 'O':
|
1085 | break;
|
1086 |
|
1087 |
|
1088 | case 'n':
|
1089 | this.setgLevel(2);
|
1090 | break;
|
1091 |
|
1092 |
|
1093 | case 'o':
|
1094 | this.setgLevel(3);
|
1095 | break;
|
1096 |
|
1097 |
|
1098 | case '|':
|
1099 | this.setgLevel(3);
|
1100 | break;
|
1101 |
|
1102 |
|
1103 | case '}':
|
1104 | this.setgLevel(2);
|
1105 | break;
|
1106 |
|
1107 |
|
1108 | case '~':
|
1109 | this.setgLevel(1);
|
1110 | break;
|
1111 |
|
1112 |
|
1113 | case '7':
|
1114 | this.saveCursor();
|
1115 | this.state = normal;
|
1116 | break;
|
1117 |
|
1118 |
|
1119 | case '8':
|
1120 | this.restoreCursor();
|
1121 | this.state = normal;
|
1122 | break;
|
1123 |
|
1124 |
|
1125 | case '#':
|
1126 | this.state = normal;
|
1127 | i++;
|
1128 | break;
|
1129 |
|
1130 |
|
1131 | case 'H':
|
1132 | this.tabSet();
|
1133 | break;
|
1134 |
|
1135 |
|
1136 | case '=':
|
1137 | this.log('Serial port requested application keypad.');
|
1138 | this.applicationKeypad = true;
|
1139 | this.state = normal;
|
1140 | break;
|
1141 |
|
1142 |
|
1143 | case '>':
|
1144 | this.log('Switching back to normal keypad.');
|
1145 | this.applicationKeypad = false;
|
1146 | this.state = normal;
|
1147 | break;
|
1148 |
|
1149 | default:
|
1150 | this.state = normal;
|
1151 | this.error('Unknown ESC control: %s.', ch);
|
1152 | break;
|
1153 | }
|
1154 | break;
|
1155 |
|
1156 | case charset:
|
1157 | switch (ch) {
|
1158 | case '0':
|
1159 | cs = Terminal.charsets.SCLD;
|
1160 | break;
|
1161 | case 'A':
|
1162 | cs = Terminal.charsets.UK;
|
1163 | break;
|
1164 | case 'B':
|
1165 | cs = Terminal.charsets.US;
|
1166 | break;
|
1167 | case '4':
|
1168 | cs = Terminal.charsets.Dutch;
|
1169 | break;
|
1170 | case 'C':
|
1171 | case '5':
|
1172 | cs = Terminal.charsets.Finnish;
|
1173 | break;
|
1174 | case 'R':
|
1175 | cs = Terminal.charsets.French;
|
1176 | break;
|
1177 | case 'Q':
|
1178 | cs = Terminal.charsets.FrenchCanadian;
|
1179 | break;
|
1180 | case 'K':
|
1181 | cs = Terminal.charsets.German;
|
1182 | break;
|
1183 | case 'Y':
|
1184 | cs = Terminal.charsets.Italian;
|
1185 | break;
|
1186 | case 'E':
|
1187 | case '6':
|
1188 | cs = Terminal.charsets.NorwegianDanish;
|
1189 | break;
|
1190 | case 'Z':
|
1191 | cs = Terminal.charsets.Spanish;
|
1192 | break;
|
1193 | case 'H':
|
1194 | case '7':
|
1195 | cs = Terminal.charsets.Swedish;
|
1196 | break;
|
1197 | case '=':
|
1198 | cs = Terminal.charsets.Swiss;
|
1199 | break;
|
1200 | case '/':
|
1201 | cs = Terminal.charsets.ISOLatin;
|
1202 | i++;
|
1203 | break;
|
1204 | default:
|
1205 | cs = Terminal.charsets.US;
|
1206 | break;
|
1207 | }
|
1208 | this.setgCharset(this.gcharset, cs);
|
1209 | this.gcharset = null;
|
1210 | this.state = normal;
|
1211 | break;
|
1212 |
|
1213 | case osc:
|
1214 |
|
1215 |
|
1216 |
|
1217 | if (ch === '\x1b' || ch === '\x07') {
|
1218 | if (ch === '\x1b') i++;
|
1219 |
|
1220 | this.params.push(this.currentParam);
|
1221 |
|
1222 | switch (this.params[0]) {
|
1223 | case 0:
|
1224 | case 1:
|
1225 | case 2:
|
1226 | if (this.params[1]) {
|
1227 | this.title = this.params[1];
|
1228 | this.handleTitle(this.title);
|
1229 | }
|
1230 | break;
|
1231 | case 3:
|
1232 |
|
1233 | break;
|
1234 | case 4:
|
1235 | case 5:
|
1236 |
|
1237 | break;
|
1238 | case 10:
|
1239 | case 11:
|
1240 | case 12:
|
1241 | case 13:
|
1242 | case 14:
|
1243 | case 15:
|
1244 | case 16:
|
1245 | case 17:
|
1246 | case 18:
|
1247 | case 19:
|
1248 |
|
1249 | break;
|
1250 | case 46:
|
1251 |
|
1252 | break;
|
1253 | case 50:
|
1254 |
|
1255 | break;
|
1256 | case 51:
|
1257 |
|
1258 | break;
|
1259 | case 52:
|
1260 |
|
1261 | break;
|
1262 | case 104:
|
1263 | case 105:
|
1264 | case 110:
|
1265 | case 111:
|
1266 | case 112:
|
1267 | case 113:
|
1268 | case 114:
|
1269 | case 115:
|
1270 | case 116:
|
1271 | case 117:
|
1272 | case 118:
|
1273 |
|
1274 | break;
|
1275 | }
|
1276 |
|
1277 | this.params = [];
|
1278 | this.currentParam = 0;
|
1279 | this.state = normal;
|
1280 | } else {
|
1281 | if (!this.params.length) {
|
1282 | if (ch >= '0' && ch <= '9') {
|
1283 | this.currentParam =
|
1284 | this.currentParam * 10 + ch.charCodeAt(0) - 48;
|
1285 | } else if (ch === ';') {
|
1286 | this.params.push(this.currentParam);
|
1287 | this.currentParam = '';
|
1288 | }
|
1289 | } else {
|
1290 | this.currentParam += ch;
|
1291 | }
|
1292 | }
|
1293 | break;
|
1294 |
|
1295 | case csi:
|
1296 |
|
1297 | if (ch === '?' || ch === '>' || ch === '!') {
|
1298 | this.prefix = ch;
|
1299 | break;
|
1300 | }
|
1301 |
|
1302 |
|
1303 | if (ch >= '0' && ch <= '9') {
|
1304 | this.currentParam = this.currentParam * 10 + ch.charCodeAt(0) - 48;
|
1305 | break;
|
1306 | }
|
1307 |
|
1308 |
|
1309 | if (ch === '$' || ch === '"' || ch === ' ' || ch === '\'') {
|
1310 | this.postfix = ch;
|
1311 | break;
|
1312 | }
|
1313 |
|
1314 | this.params.push(this.currentParam);
|
1315 | this.currentParam = 0;
|
1316 |
|
1317 |
|
1318 | if (ch === ';') break;
|
1319 |
|
1320 | this.state = normal;
|
1321 |
|
1322 | switch (ch) {
|
1323 |
|
1324 |
|
1325 | case 'A':
|
1326 | this.cursorUp(this.params);
|
1327 | break;
|
1328 |
|
1329 |
|
1330 |
|
1331 | case 'B':
|
1332 | this.cursorDown(this.params);
|
1333 | break;
|
1334 |
|
1335 |
|
1336 |
|
1337 | case 'C':
|
1338 | this.cursorForward(this.params);
|
1339 | break;
|
1340 |
|
1341 |
|
1342 |
|
1343 | case 'D':
|
1344 | this.cursorBackward(this.params);
|
1345 | break;
|
1346 |
|
1347 |
|
1348 |
|
1349 | case 'H':
|
1350 | this.cursorPos(this.params);
|
1351 | break;
|
1352 |
|
1353 |
|
1354 | case 'J':
|
1355 | this.eraseInDisplay(this.params);
|
1356 | break;
|
1357 |
|
1358 |
|
1359 | case 'K':
|
1360 | this.eraseInLine(this.params);
|
1361 | break;
|
1362 |
|
1363 |
|
1364 | case 'm':
|
1365 | this.charAttributes(this.params);
|
1366 | break;
|
1367 |
|
1368 |
|
1369 | case 'n':
|
1370 | this.deviceStatus(this.params);
|
1371 | break;
|
1372 |
|
1373 | |
1374 |
|
1375 |
|
1376 |
|
1377 |
|
1378 |
|
1379 | case '@':
|
1380 | this.insertChars(this.params);
|
1381 | break;
|
1382 |
|
1383 |
|
1384 |
|
1385 | case 'E':
|
1386 | this.cursorNextLine(this.params);
|
1387 | break;
|
1388 |
|
1389 |
|
1390 |
|
1391 | case 'F':
|
1392 | this.cursorPrecedingLine(this.params);
|
1393 | break;
|
1394 |
|
1395 |
|
1396 |
|
1397 | case 'G':
|
1398 | this.cursorCharAbsolute(this.params);
|
1399 | break;
|
1400 |
|
1401 |
|
1402 |
|
1403 | case 'L':
|
1404 | this.insertLines(this.params);
|
1405 | break;
|
1406 |
|
1407 |
|
1408 |
|
1409 | case 'M':
|
1410 | this.deleteLines(this.params);
|
1411 | break;
|
1412 |
|
1413 |
|
1414 |
|
1415 | case 'P':
|
1416 | this.deleteChars(this.params);
|
1417 | break;
|
1418 |
|
1419 |
|
1420 |
|
1421 | case 'X':
|
1422 | this.eraseChars(this.params);
|
1423 | break;
|
1424 |
|
1425 |
|
1426 |
|
1427 | case '`':
|
1428 | this.charPosAbsolute(this.params);
|
1429 | break;
|
1430 |
|
1431 |
|
1432 |
|
1433 | case 'a':
|
1434 | this.HPositionRelative(this.params);
|
1435 | break;
|
1436 |
|
1437 |
|
1438 |
|
1439 |
|
1440 |
|
1441 | case 'c':
|
1442 | this.sendDeviceAttributes(this.params);
|
1443 | break;
|
1444 |
|
1445 |
|
1446 |
|
1447 | case 'd':
|
1448 | this.linePosAbsolute(this.params);
|
1449 | break;
|
1450 |
|
1451 |
|
1452 | case 'e':
|
1453 | this.VPositionRelative(this.params);
|
1454 | break;
|
1455 |
|
1456 |
|
1457 |
|
1458 |
|
1459 | case 'f':
|
1460 | this.HVPosition(this.params);
|
1461 | break;
|
1462 |
|
1463 |
|
1464 |
|
1465 | case 'h':
|
1466 | this.setMode(this.params);
|
1467 | break;
|
1468 |
|
1469 |
|
1470 |
|
1471 | case 'l':
|
1472 | this.resetMode(this.params);
|
1473 | break;
|
1474 |
|
1475 |
|
1476 |
|
1477 |
|
1478 |
|
1479 | case 'r':
|
1480 | this.setScrollRegion(this.params);
|
1481 | break;
|
1482 |
|
1483 |
|
1484 |
|
1485 | case 's':
|
1486 | this.saveCursor(this.params);
|
1487 | break;
|
1488 |
|
1489 |
|
1490 |
|
1491 | case 'u':
|
1492 | this.restoreCursor(this.params);
|
1493 | break;
|
1494 |
|
1495 | |
1496 |
|
1497 |
|
1498 |
|
1499 |
|
1500 |
|
1501 | case 'I':
|
1502 | this.cursorForwardTab(this.params);
|
1503 | break;
|
1504 |
|
1505 |
|
1506 | case 'S':
|
1507 | this.scrollUp(this.params);
|
1508 | break;
|
1509 |
|
1510 |
|
1511 |
|
1512 |
|
1513 | case 'T':
|
1514 |
|
1515 |
|
1516 |
|
1517 |
|
1518 |
|
1519 |
|
1520 |
|
1521 |
|
1522 | if (this.params.length < 2 && !this.prefix) {
|
1523 | this.scrollDown(this.params);
|
1524 | }
|
1525 | break;
|
1526 |
|
1527 |
|
1528 |
|
1529 | case 'Z':
|
1530 | this.cursorBackwardTab(this.params);
|
1531 | break;
|
1532 |
|
1533 |
|
1534 | case 'b':
|
1535 | this.repeatPrecedingCharacter(this.params);
|
1536 | break;
|
1537 |
|
1538 |
|
1539 | case 'g':
|
1540 | this.tabClear(this.params);
|
1541 | break;
|
1542 |
|
1543 |
|
1544 |
|
1545 |
|
1546 |
|
1547 |
|
1548 |
|
1549 |
|
1550 |
|
1551 |
|
1552 |
|
1553 |
|
1554 |
|
1555 |
|
1556 |
|
1557 |
|
1558 |
|
1559 |
|
1560 |
|
1561 |
|
1562 |
|
1563 |
|
1564 |
|
1565 |
|
1566 |
|
1567 |
|
1568 |
|
1569 |
|
1570 |
|
1571 |
|
1572 |
|
1573 |
|
1574 |
|
1575 |
|
1576 | case 'p':
|
1577 | switch (this.prefix) {
|
1578 |
|
1579 |
|
1580 |
|
1581 | case '!':
|
1582 | this.softReset(this.params);
|
1583 | break;
|
1584 |
|
1585 |
|
1586 |
|
1587 |
|
1588 |
|
1589 |
|
1590 |
|
1591 |
|
1592 |
|
1593 |
|
1594 |
|
1595 |
|
1596 | }
|
1597 | break;
|
1598 |
|
1599 |
|
1600 |
|
1601 |
|
1602 |
|
1603 |
|
1604 |
|
1605 |
|
1606 |
|
1607 |
|
1608 |
|
1609 |
|
1610 |
|
1611 |
|
1612 |
|
1613 |
|
1614 |
|
1615 |
|
1616 |
|
1617 |
|
1618 |
|
1619 |
|
1620 |
|
1621 |
|
1622 |
|
1623 |
|
1624 |
|
1625 |
|
1626 |
|
1627 |
|
1628 |
|
1629 |
|
1630 |
|
1631 |
|
1632 |
|
1633 |
|
1634 |
|
1635 |
|
1636 |
|
1637 |
|
1638 |
|
1639 |
|
1640 |
|
1641 |
|
1642 |
|
1643 |
|
1644 |
|
1645 |
|
1646 |
|
1647 |
|
1648 |
|
1649 |
|
1650 |
|
1651 |
|
1652 |
|
1653 |
|
1654 |
|
1655 |
|
1656 |
|
1657 |
|
1658 |
|
1659 |
|
1660 |
|
1661 |
|
1662 |
|
1663 |
|
1664 |
|
1665 |
|
1666 |
|
1667 |
|
1668 |
|
1669 |
|
1670 |
|
1671 |
|
1672 |
|
1673 |
|
1674 |
|
1675 |
|
1676 |
|
1677 |
|
1678 |
|
1679 |
|
1680 |
|
1681 |
|
1682 |
|
1683 |
|
1684 |
|
1685 |
|
1686 |
|
1687 |
|
1688 |
|
1689 |
|
1690 |
|
1691 |
|
1692 |
|
1693 |
|
1694 |
|
1695 |
|
1696 |
|
1697 |
|
1698 |
|
1699 |
|
1700 |
|
1701 |
|
1702 |
|
1703 |
|
1704 |
|
1705 |
|
1706 |
|
1707 |
|
1708 |
|
1709 |
|
1710 |
|
1711 |
|
1712 |
|
1713 |
|
1714 |
|
1715 |
|
1716 |
|
1717 |
|
1718 |
|
1719 |
|
1720 |
|
1721 |
|
1722 |
|
1723 |
|
1724 |
|
1725 |
|
1726 |
|
1727 |
|
1728 |
|
1729 |
|
1730 |
|
1731 |
|
1732 |
|
1733 |
|
1734 |
|
1735 |
|
1736 | default:
|
1737 | this.error('Unknown CSI code: %s.', ch);
|
1738 | break;
|
1739 | }
|
1740 |
|
1741 | this.prefix = '';
|
1742 | this.postfix = '';
|
1743 | break;
|
1744 |
|
1745 | case dcs:
|
1746 | if (ch === '\x1b' || ch === '\x07') {
|
1747 | if (ch === '\x1b') i++;
|
1748 |
|
1749 | switch (this.prefix) {
|
1750 |
|
1751 | case '':
|
1752 | break;
|
1753 |
|
1754 |
|
1755 |
|
1756 | case '$q':
|
1757 | var pt = this.currentParam
|
1758 | , valid = false;
|
1759 |
|
1760 | switch (pt) {
|
1761 |
|
1762 | case '"q':
|
1763 | pt = '0"q';
|
1764 | break;
|
1765 |
|
1766 |
|
1767 | case '"p':
|
1768 | pt = '61"p';
|
1769 | break;
|
1770 |
|
1771 |
|
1772 | case 'r':
|
1773 | pt = ''
|
1774 | + (this.scrollTop + 1)
|
1775 | + ';'
|
1776 | + (this.scrollBottom + 1)
|
1777 | + 'r';
|
1778 | break;
|
1779 |
|
1780 |
|
1781 | case 'm':
|
1782 | pt = '0m';
|
1783 | break;
|
1784 |
|
1785 | default:
|
1786 | this.error('Unknown DCS Pt: %s.', pt);
|
1787 | pt = '';
|
1788 | break;
|
1789 | }
|
1790 |
|
1791 | this.send('\x1bP' + +valid + '$r' + pt + '\x1b\\');
|
1792 | break;
|
1793 |
|
1794 |
|
1795 | case '+p':
|
1796 | break;
|
1797 |
|
1798 |
|
1799 |
|
1800 |
|
1801 |
|
1802 | case '+q':
|
1803 | var pt = this.currentParam
|
1804 | , valid = false;
|
1805 |
|
1806 | this.send('\x1bP' + +valid + '+r' + pt + '\x1b\\');
|
1807 | break;
|
1808 |
|
1809 | default:
|
1810 | this.error('Unknown DCS prefix: %s.', this.prefix);
|
1811 | break;
|
1812 | }
|
1813 |
|
1814 | this.currentParam = 0;
|
1815 | this.prefix = '';
|
1816 | this.state = normal;
|
1817 | } else if (!this.currentParam) {
|
1818 | if (!this.prefix && ch !== '$' && ch !== '+') {
|
1819 | this.currentParam = ch;
|
1820 | } else if (this.prefix.length === 2) {
|
1821 | this.currentParam = ch;
|
1822 | } else {
|
1823 | this.prefix += ch;
|
1824 | }
|
1825 | } else {
|
1826 | this.currentParam += ch;
|
1827 | }
|
1828 | break;
|
1829 |
|
1830 | case ignore:
|
1831 |
|
1832 | if (ch === '\x1b' || ch === '\x07') {
|
1833 | if (ch === '\x1b') i++;
|
1834 | this.emit(this.stateType, this.stateData || '');
|
1835 | this.stateData = '';
|
1836 | this.state = normal;
|
1837 | } else {
|
1838 | if (!this.stateData) this.stateData = '';
|
1839 | this.stateData += ch;
|
1840 | }
|
1841 | break;
|
1842 | }
|
1843 | }
|
1844 |
|
1845 | this.updateRange(this.y);
|
1846 | this.refresh(this.refreshStart, this.refreshEnd);
|
1847 | };
|
1848 |
|
1849 | Terminal.prototype.writeln = function(data) {
|
1850 | this.write(data + '\r\n');
|
1851 | };
|
1852 |
|
1853 | Terminal.prototype.keyDown = function(ev) {
|
1854 | var key;
|
1855 |
|
1856 | switch (ev.keyCode) {
|
1857 |
|
1858 | case 8:
|
1859 | if (ev.shiftKey) {
|
1860 | key = '\x08';
|
1861 | break;
|
1862 | }
|
1863 | key = '\x7f';
|
1864 | break;
|
1865 |
|
1866 | case 9:
|
1867 | if (ev.shiftKey) {
|
1868 | key = '\x1b[Z';
|
1869 | break;
|
1870 | }
|
1871 | key = '\t';
|
1872 | break;
|
1873 |
|
1874 | case 13:
|
1875 | key = '\r';
|
1876 | break;
|
1877 |
|
1878 | case 27:
|
1879 | key = '\x1b';
|
1880 | break;
|
1881 |
|
1882 | case 37:
|
1883 | if (this.applicationKeypad) {
|
1884 | key = '\x1bOD';
|
1885 |
|
1886 | break;
|
1887 | }
|
1888 | key = '\x1b[D';
|
1889 | break;
|
1890 |
|
1891 | case 39:
|
1892 | if (this.applicationKeypad) {
|
1893 | key = '\x1bOC';
|
1894 | break;
|
1895 | }
|
1896 | key = '\x1b[C';
|
1897 | break;
|
1898 |
|
1899 | case 38:
|
1900 | if (this.applicationKeypad) {
|
1901 | key = '\x1bOA';
|
1902 | break;
|
1903 | }
|
1904 | if (ev.ctrlKey) {
|
1905 | this.scrollDisp(-1);
|
1906 | return cancel(ev);
|
1907 | } else {
|
1908 | key = '\x1b[A';
|
1909 | }
|
1910 | break;
|
1911 |
|
1912 | case 40:
|
1913 | if (this.applicationKeypad) {
|
1914 | key = '\x1bOB';
|
1915 | break;
|
1916 | }
|
1917 | if (ev.ctrlKey) {
|
1918 | this.scrollDisp(1);
|
1919 | return cancel(ev);
|
1920 | } else {
|
1921 | key = '\x1b[B';
|
1922 | }
|
1923 | break;
|
1924 |
|
1925 | case 46:
|
1926 | key = '\x1b[3~';
|
1927 | break;
|
1928 |
|
1929 | case 45:
|
1930 | key = '\x1b[2~';
|
1931 | break;
|
1932 |
|
1933 | case 36:
|
1934 | if (this.applicationKeypad) {
|
1935 | key = '\x1bOH';
|
1936 | break;
|
1937 | }
|
1938 | key = '\x1bOH';
|
1939 | break;
|
1940 |
|
1941 | case 35:
|
1942 | if (this.applicationKeypad) {
|
1943 | key = '\x1bOF';
|
1944 | break;
|
1945 | }
|
1946 | key = '\x1bOF';
|
1947 | break;
|
1948 |
|
1949 | case 33:
|
1950 | if (ev.shiftKey) {
|
1951 | this.scrollDisp(-(this.rows - 1));
|
1952 | return cancel(ev);
|
1953 | } else {
|
1954 | key = '\x1b[5~';
|
1955 | }
|
1956 | break;
|
1957 |
|
1958 | case 34:
|
1959 | if (ev.shiftKey) {
|
1960 | this.scrollDisp(this.rows - 1);
|
1961 | return cancel(ev);
|
1962 | } else {
|
1963 | key = '\x1b[6~';
|
1964 | }
|
1965 | break;
|
1966 |
|
1967 | case 112:
|
1968 | key = '\x1bOP';
|
1969 | break;
|
1970 |
|
1971 | case 113:
|
1972 | key = '\x1bOQ';
|
1973 | break;
|
1974 |
|
1975 | case 114:
|
1976 | key = '\x1bOR';
|
1977 | break;
|
1978 |
|
1979 | case 115:
|
1980 | key = '\x1bOS';
|
1981 | break;
|
1982 |
|
1983 | case 116:
|
1984 | key = '\x1b[15~';
|
1985 | break;
|
1986 |
|
1987 | case 117:
|
1988 | key = '\x1b[17~';
|
1989 | break;
|
1990 |
|
1991 | case 118:
|
1992 | key = '\x1b[18~';
|
1993 | break;
|
1994 |
|
1995 | case 119:
|
1996 | key = '\x1b[19~';
|
1997 | break;
|
1998 |
|
1999 | case 120:
|
2000 | key = '\x1b[20~';
|
2001 | break;
|
2002 |
|
2003 | case 121:
|
2004 | key = '\x1b[21~';
|
2005 | break;
|
2006 |
|
2007 | case 122:
|
2008 | key = '\x1b[23~';
|
2009 | break;
|
2010 |
|
2011 | case 123:
|
2012 | key = '\x1b[24~';
|
2013 | break;
|
2014 | default:
|
2015 |
|
2016 | if (ev.ctrlKey) {
|
2017 | if (ev.keyCode >= 65 && ev.keyCode <= 90) {
|
2018 | key = String.fromCharCode(ev.keyCode - 64);
|
2019 | } else if (ev.keyCode === 32) {
|
2020 |
|
2021 | key = String.fromCharCode(0);
|
2022 | } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {
|
2023 |
|
2024 | key = String.fromCharCode(ev.keyCode - 51 + 27);
|
2025 | } else if (ev.keyCode === 56) {
|
2026 |
|
2027 | key = String.fromCharCode(127);
|
2028 | } else if (ev.keyCode === 219) {
|
2029 |
|
2030 | key = String.fromCharCode(27);
|
2031 | } else if (ev.keyCode === 221) {
|
2032 |
|
2033 | key = String.fromCharCode(29);
|
2034 | }
|
2035 | } else if ((!isMac && ev.altKey) || (isMac && ev.metaKey)) {
|
2036 | if (ev.keyCode >= 65 && ev.keyCode <= 90) {
|
2037 | key = '\x1b' + String.fromCharCode(ev.keyCode + 32);
|
2038 | } else if (ev.keyCode === 192) {
|
2039 | key = '\x1b`';
|
2040 | } else if (ev.keyCode >= 48 && ev.keyCode <= 57) {
|
2041 | key = '\x1b' + (ev.keyCode - 48);
|
2042 | }
|
2043 | }
|
2044 | break;
|
2045 | }
|
2046 |
|
2047 | this.emit('keydown', ev);
|
2048 |
|
2049 | if (key) {
|
2050 | this.emit('key', key, ev);
|
2051 |
|
2052 | this.showCursor();
|
2053 | this.handler(key);
|
2054 |
|
2055 | return cancel(ev);
|
2056 | }
|
2057 |
|
2058 | return true;
|
2059 | };
|
2060 |
|
2061 | Terminal.prototype.setgLevel = function(g) {
|
2062 | this.glevel = g;
|
2063 | this.charset = this.charsets[g];
|
2064 | };
|
2065 |
|
2066 | Terminal.prototype.setgCharset = function(g, charset) {
|
2067 | this.charsets[g] = charset;
|
2068 | if (this.glevel === g) {
|
2069 | this.charset = charset;
|
2070 | }
|
2071 | };
|
2072 |
|
2073 | Terminal.prototype.keyPress = function(ev) {
|
2074 | var key;
|
2075 |
|
2076 | cancel(ev);
|
2077 |
|
2078 | if (ev.charCode) {
|
2079 | key = ev.charCode;
|
2080 | } else if (ev.which == null) {
|
2081 | key = ev.keyCode;
|
2082 | } else if (ev.which !== 0 && ev.charCode !== 0) {
|
2083 | key = ev.which;
|
2084 | } else {
|
2085 | return false;
|
2086 | }
|
2087 |
|
2088 | if (!key || ev.ctrlKey || ev.altKey || ev.metaKey) return false;
|
2089 |
|
2090 | key = String.fromCharCode(key);
|
2091 |
|
2092 | this.emit('keypress', key, ev);
|
2093 | this.emit('key', key, ev);
|
2094 |
|
2095 | this.showCursor();
|
2096 | this.handler(key);
|
2097 |
|
2098 | return false;
|
2099 | };
|
2100 |
|
2101 | Terminal.prototype.send = function(data) {
|
2102 | var self = this;
|
2103 |
|
2104 | if (!this.queue) {
|
2105 | setTimeout(function() {
|
2106 | self.handler(self.queue);
|
2107 | self.queue = '';
|
2108 | }, 1);
|
2109 | }
|
2110 |
|
2111 | this.queue += data;
|
2112 | };
|
2113 |
|
2114 | Terminal.prototype.bell = function() {
|
2115 | if (!Terminal.visualBell) return;
|
2116 | var self = this;
|
2117 | this.element.style.borderColor = 'white';
|
2118 | setTimeout(function() {
|
2119 | self.element.style.borderColor = '';
|
2120 | }, 10);
|
2121 | if (Terminal.popOnBell) this.focus();
|
2122 | };
|
2123 |
|
2124 | Terminal.prototype.log = function() {
|
2125 | if (!Terminal.debug) return;
|
2126 | if (!window.console || !window.console.log) return;
|
2127 | var args = Array.prototype.slice.call(arguments);
|
2128 | window.console.log.apply(window.console, args);
|
2129 | };
|
2130 |
|
2131 | Terminal.prototype.error = function() {
|
2132 | if (!Terminal.debug) return;
|
2133 | if (!window.console || !window.console.error) return;
|
2134 | var args = Array.prototype.slice.call(arguments);
|
2135 | window.console.error.apply(window.console, args);
|
2136 | };
|
2137 |
|
2138 | Terminal.prototype.resize = function(x, y) {
|
2139 | var line
|
2140 | , el
|
2141 | , i
|
2142 | , j
|
2143 | , ch;
|
2144 |
|
2145 | if (x < 1) x = 1;
|
2146 | if (y < 1) y = 1;
|
2147 |
|
2148 |
|
2149 | j = this.cols;
|
2150 | if (j < x) {
|
2151 | ch = [this.defAttr, ' '];
|
2152 | i = this.lines.length;
|
2153 | while (i--) {
|
2154 | while (this.lines[i].length < x) {
|
2155 | this.lines[i].push(ch);
|
2156 | }
|
2157 | }
|
2158 | } else if (j > x) {
|
2159 | i = this.lines.length;
|
2160 | while (i--) {
|
2161 | while (this.lines[i].length > x) {
|
2162 | this.lines[i].pop();
|
2163 | }
|
2164 | }
|
2165 | }
|
2166 | this.setupStops(j);
|
2167 | this.cols = x;
|
2168 |
|
2169 |
|
2170 | j = this.rows;
|
2171 | if (j < y) {
|
2172 | el = this.element;
|
2173 | while (j++ < y) {
|
2174 | if (this.lines.length < y + this.ybase) {
|
2175 | this.lines.push(this.blankLine());
|
2176 | }
|
2177 | if (this.children.length < y) {
|
2178 | line = document.createElement('div');
|
2179 | el.appendChild(line);
|
2180 | this.children.push(line);
|
2181 | }
|
2182 | }
|
2183 | } else if (j > y) {
|
2184 | while (j-- > y) {
|
2185 | if (this.lines.length > y + this.ybase) {
|
2186 | this.lines.pop();
|
2187 | }
|
2188 | if (this.children.length > y) {
|
2189 | el = this.children.pop();
|
2190 | if (!el) continue;
|
2191 | el.parentNode.removeChild(el);
|
2192 | }
|
2193 | }
|
2194 | }
|
2195 | this.rows = y;
|
2196 |
|
2197 | // make sure the cursor stays on screen
|
2198 | if (this.y >= y) this.y = y - 1;
|
2199 | if (this.x >= x) this.x = x - 1;
|
2200 |
|
2201 | this.scrollTop = 0;
|
2202 | this.scrollBottom = y - 1;
|
2203 |
|
2204 | this.refresh(0, this.rows - 1);
|
2205 |
|
2206 | // it's a real nightmare trying
|
2207 | // to resize the original
|
2208 | // screen buffer. just set it
|
2209 | // to null for now.
|
2210 | this.normal = null;
|
2211 | };
|
2212 |
|
2213 | Terminal.prototype.updateRange = function(y) {
|
2214 | if (y < this.refreshStart) this.refreshStart = y;
|
2215 | if (y > this.refreshEnd) this.refreshEnd = y;
|
2216 | // if (y > this.refreshEnd) {
|
2217 | // this.refreshEnd = y;
|
2218 | // if (y > this.rows - 1) {
|
2219 | // this.refreshEnd = this.rows - 1;
|
2220 | // }
|
2221 | // }
|
2222 | };
|
2223 |
|
2224 | Terminal.prototype.maxRange = function() {
|
2225 | this.refreshStart = 0;
|
2226 | this.refreshEnd = this.rows - 1;
|
2227 | };
|
2228 |
|
2229 | Terminal.prototype.setupStops = function(i) {
|
2230 | if (i != null) {
|
2231 | if (!this.tabs[i]) {
|
2232 | i = this.prevStop(i);
|
2233 | }
|
2234 | } else {
|
2235 | this.tabs = {};
|
2236 | i = 0;
|
2237 | }
|
2238 |
|
2239 | for (; i < this.cols; i += 8) {
|
2240 | this.tabs[i] = true;
|
2241 | }
|
2242 | };
|
2243 |
|
2244 | Terminal.prototype.prevStop = function(x) {
|
2245 | if (x == null) x = this.x;
|
2246 | while (!this.tabs[--x] && x > 0);
|
2247 | return x >= this.cols
|
2248 | ? this.cols - 1
|
2249 | : x < 0 ? 0 : x;
|
2250 | };
|
2251 |
|
2252 | Terminal.prototype.nextStop = function(x) {
|
2253 | if (x == null) x = this.x;
|
2254 | while (!this.tabs[++x] && x < this.cols);
|
2255 | return x >= this.cols
|
2256 | ? this.cols - 1
|
2257 | : x < 0 ? 0 : x;
|
2258 | };
|
2259 |
|
2260 | Terminal.prototype.eraseRight = function(x, y) {
|
2261 | var line = this.lines[this.ybase + y]
|
2262 | , ch = [this.curAttr, ' ']; // xterm
|
2263 |
|
2264 | for (; x < this.cols; x++) {
|
2265 | line[x] = ch;
|
2266 | }
|
2267 |
|
2268 | this.updateRange(y);
|
2269 | };
|
2270 |
|
2271 | Terminal.prototype.eraseLeft = function(x, y) {
|
2272 | var line = this.lines[this.ybase + y]
|
2273 | , ch = [this.curAttr, ' ']; // xterm
|
2274 |
|
2275 | x++;
|
2276 | while (x--) line[x] = ch;
|
2277 |
|
2278 | this.updateRange(y);
|
2279 | };
|
2280 |
|
2281 | Terminal.prototype.eraseLine = function(y) {
|
2282 | this.eraseRight(0, y);
|
2283 | };
|
2284 |
|
2285 | Terminal.prototype.blankLine = function(cur) {
|
2286 | var attr = cur
|
2287 | ? this.curAttr
|
2288 | : this.defAttr;
|
2289 |
|
2290 | var ch = [attr, ' ']
|
2291 | , line = []
|
2292 | , i = 0;
|
2293 |
|
2294 | for (; i < this.cols; i++) {
|
2295 | line[i] = ch;
|
2296 | }
|
2297 |
|
2298 | return line;
|
2299 | };
|
2300 |
|
2301 | Terminal.prototype.ch = function(cur) {
|
2302 | return cur
|
2303 | ? [this.curAttr, ' ']
|
2304 | : [this.defAttr, ' '];
|
2305 | };
|
2306 |
|
2307 | Terminal.prototype.is = function(term) {
|
2308 | var name = this.termName || Terminal.termName;
|
2309 | return (name + '').indexOf(term) === 0;
|
2310 | };
|
2311 |
|
2312 | Terminal.prototype.handler = function(data) {
|
2313 | this.emit('data', data);
|
2314 | };
|
2315 |
|
2316 | Terminal.prototype.handleTitle = function(title) {
|
2317 | this.emit('title', title);
|
2318 | };
|
2319 |
|
2320 | /**
|
2321 | * ESC
|
2322 | */
|
2323 |
|
2324 | // ESC D Index (IND is 0x84).
|
2325 | Terminal.prototype.index = function() {
|
2326 | this.y++;
|
2327 | if (this.y > this.scrollBottom) {
|
2328 | this.y--;
|
2329 | this.scroll();
|
2330 | }
|
2331 | this.state = normal;
|
2332 | };
|
2333 |
|
2334 | // ESC M Reverse Index (RI is 0x8d).
|
2335 | Terminal.prototype.reverseIndex = function() {
|
2336 | var j;
|
2337 | this.y--;
|
2338 | if (this.y < this.scrollTop) {
|
2339 | this.y++;
|
2340 | // possibly move the code below to term.reverseScroll();
|
2341 | // test: echo -ne '\e[1;1H\e[44m\eM\e[0m'
|
2342 | // blankLine(true) is xterm/linux behavior
|
2343 | this.lines.splice(this.y + this.ybase, 0, this.blankLine(true));
|
2344 | j = this.rows - 1 - this.scrollBottom;
|
2345 | this.lines.splice(this.rows - 1 + this.ybase - j + 1, 1);
|
2346 | // this.maxRange();
|
2347 | this.updateRange(this.scrollTop);
|
2348 | this.updateRange(this.scrollBottom);
|
2349 | }
|
2350 | this.state = normal;
|
2351 | };
|
2352 |
|
2353 | // ESC c Full Reset (RIS).
|
2354 | Terminal.prototype.reset = function() {
|
2355 | Terminal.call(this, this.cols, this.rows);
|
2356 | this.refresh(0, this.rows - 1);
|
2357 | };
|
2358 |
|
2359 | // ESC H Tab Set (HTS is 0x88).
|
2360 | Terminal.prototype.tabSet = function() {
|
2361 | this.tabs[this.x] = true;
|
2362 | this.state = normal;
|
2363 | };
|
2364 |
|
2365 | /**
|
2366 | * CSI
|
2367 | */
|
2368 |
|
2369 | // CSI Ps A
|
2370 | // Cursor Up Ps Times (default = 1) (CUU).
|
2371 | Terminal.prototype.cursorUp = function(params) {
|
2372 | var param = params[0];
|
2373 | if (param < 1) param = 1;
|
2374 | this.y -= param;
|
2375 | if (this.y < 0) this.y = 0;
|
2376 | };
|
2377 |
|
2378 | // CSI Ps B
|
2379 | // Cursor Down Ps Times (default = 1) (CUD).
|
2380 | Terminal.prototype.cursorDown = function(params) {
|
2381 | var param = params[0];
|
2382 | if (param < 1) param = 1;
|
2383 | this.y += param;
|
2384 | if (this.y >= this.rows) {
|
2385 | this.y = this.rows - 1;
|
2386 | }
|
2387 | };
|
2388 |
|
2389 | // CSI Ps C
|
2390 | // Cursor Forward Ps Times (default = 1) (CUF).
|
2391 | Terminal.prototype.cursorForward = function(params) {
|
2392 | var param = params[0];
|
2393 | if (param < 1) param = 1;
|
2394 | this.x += param;
|
2395 | if (this.x >= this.cols) {
|
2396 | this.x = this.cols - 1;
|
2397 | }
|
2398 | };
|
2399 |
|
2400 | // CSI Ps D
|
2401 | // Cursor Backward Ps Times (default = 1) (CUB).
|
2402 | Terminal.prototype.cursorBackward = function(params) {
|
2403 | var param = params[0];
|
2404 | if (param < 1) param = 1;
|
2405 | this.x -= param;
|
2406 | if (this.x < 0) this.x = 0;
|
2407 | };
|
2408 |
|
2409 | // CSI Ps ; Ps H
|
2410 | // Cursor Position [row;column] (default = [1,1]) (CUP).
|
2411 | Terminal.prototype.cursorPos = function(params) {
|
2412 | var row, col;
|
2413 |
|
2414 | row = params[0] - 1;
|
2415 |
|
2416 | if (params.length >= 2) {
|
2417 | col = params[1] - 1;
|
2418 | } else {
|
2419 | col = 0;
|
2420 | }
|
2421 |
|
2422 | if (row < 0) {
|
2423 | row = 0;
|
2424 | } else if (row >= this.rows) {
|
2425 | row = this.rows - 1;
|
2426 | }
|
2427 |
|
2428 | if (col < 0) {
|
2429 | col = 0;
|
2430 | } else if (col >= this.cols) {
|
2431 | col = this.cols - 1;
|
2432 | }
|
2433 |
|
2434 | this.x = col;
|
2435 | this.y = row;
|
2436 | };
|
2437 |
|
2438 | // CSI Ps J Erase in Display (ED).
|
2439 | // Ps = 0 -> Erase Below (default).
|
2440 | // Ps = 1 -> Erase Above.
|
2441 | // Ps = 2 -> Erase All.
|
2442 | // Ps = 3 -> Erase Saved Lines (xterm).
|
2443 | // CSI ? Ps J
|
2444 | // Erase in Display (DECSED).
|
2445 | // Ps = 0 -> Selective Erase Below (default).
|
2446 | // Ps = 1 -> Selective Erase Above.
|
2447 | // Ps = 2 -> Selective Erase All.
|
2448 | Terminal.prototype.eraseInDisplay = function(params) {
|
2449 | var j;
|
2450 | switch (params[0]) {
|
2451 | case 0:
|
2452 | this.eraseRight(this.x, this.y);
|
2453 | j = this.y + 1;
|
2454 | for (; j < this.rows; j++) {
|
2455 | this.eraseLine(j);
|
2456 | }
|
2457 | break;
|
2458 | case 1:
|
2459 | this.eraseLeft(this.x, this.y);
|
2460 | j = this.y;
|
2461 | while (j--) {
|
2462 | this.eraseLine(j);
|
2463 | }
|
2464 | break;
|
2465 | case 2:
|
2466 | j = this.rows;
|
2467 | while (j--) this.eraseLine(j);
|
2468 | break;
|
2469 | case 3:
|
2470 | ; // no saved lines
|
2471 | break;
|
2472 | }
|
2473 | this.emit('erase', {
|
2474 | 0: 'below',
|
2475 | 1: 'above',
|
2476 | 2: 'all',
|
2477 | 3: 'saved'
|
2478 | }[params]);
|
2479 | };
|
2480 |
|
2481 | // CSI Ps K Erase in Line (EL).
|
2482 | // Ps = 0 -> Erase to Right (default).
|
2483 | // Ps = 1 -> Erase to Left.
|
2484 | // Ps = 2 -> Erase All.
|
2485 | // CSI ? Ps K
|
2486 | // Erase in Line (DECSEL).
|
2487 | // Ps = 0 -> Selective Erase to Right (default).
|
2488 | // Ps = 1 -> Selective Erase to Left.
|
2489 | // Ps = 2 -> Selective Erase All.
|
2490 | Terminal.prototype.eraseInLine = function(params) {
|
2491 | switch (params[0]) {
|
2492 | case 0:
|
2493 | this.eraseRight(this.x, this.y);
|
2494 | break;
|
2495 | case 1:
|
2496 | this.eraseLeft(this.x, this.y);
|
2497 | break;
|
2498 | case 2:
|
2499 | this.eraseLine(this.y);
|
2500 | break;
|
2501 | }
|
2502 | };
|
2503 |
|
2504 | // CSI Pm m Character Attributes (SGR).
|
2505 | // Ps = 0 -> Normal (default).
|
2506 | // Ps = 1 -> Bold.
|
2507 | // Ps = 4 -> Underlined.
|
2508 | // Ps = 5 -> Blink (appears as Bold).
|
2509 | // Ps = 7 -> Inverse.
|
2510 | // Ps = 8 -> Invisible, i.e., hidden (VT300).
|
2511 | // Ps = 2 2 -> Normal (neither bold nor faint).
|
2512 | // Ps = 2 4 -> Not underlined.
|
2513 | // Ps = 2 5 -> Steady (not blinking).
|
2514 | // Ps = 2 7 -> Positive (not inverse).
|
2515 | // Ps = 2 8 -> Visible, i.e., not hidden (VT300).
|
2516 | // Ps = 3 0 -> Set foreground color to Black.
|
2517 | // Ps = 3 1 -> Set foreground color to Red.
|
2518 | // Ps = 3 2 -> Set foreground color to Green.
|
2519 | // Ps = 3 3 -> Set foreground color to Yellow.
|
2520 | // Ps = 3 4 -> Set foreground color to Blue.
|
2521 | // Ps = 3 5 -> Set foreground color to Magenta.
|
2522 | // Ps = 3 6 -> Set foreground color to Cyan.
|
2523 | // Ps = 3 7 -> Set foreground color to White.
|
2524 | // Ps = 3 9 -> Set foreground color to default (original).
|
2525 | // Ps = 4 0 -> Set background color to Black.
|
2526 | // Ps = 4 1 -> Set background color to Red.
|
2527 | // Ps = 4 2 -> Set background color to Green.
|
2528 | // Ps = 4 3 -> Set background color to Yellow.
|
2529 | // Ps = 4 4 -> Set background color to Blue.
|
2530 | // Ps = 4 5 -> Set background color to Magenta.
|
2531 | // Ps = 4 6 -> Set background color to Cyan.
|
2532 | // Ps = 4 7 -> Set background color to White.
|
2533 | // Ps = 4 9 -> Set background color to default (original).
|
2534 |
|
2535 | // If 16-color support is compiled, the following apply. Assume
|
2536 | // that xterm's resources are set so that the ISO color codes are
|
2537 | // the first 8 of a set of 16. Then the aixterm colors are the
|
2538 | // bright versions of the ISO colors:
|
2539 | // Ps = 9 0 -> Set foreground color to Black.
|
2540 | // Ps = 9 1 -> Set foreground color to Red.
|
2541 | // Ps = 9 2 -> Set foreground color to Green.
|
2542 | // Ps = 9 3 -> Set foreground color to Yellow.
|
2543 | // Ps = 9 4 -> Set foreground color to Blue.
|
2544 | // Ps = 9 5 -> Set foreground color to Magenta.
|
2545 | // Ps = 9 6 -> Set foreground color to Cyan.
|
2546 | // Ps = 9 7 -> Set foreground color to White.
|
2547 | // Ps = 1 0 0 -> Set background color to Black.
|
2548 | // Ps = 1 0 1 -> Set background color to Red.
|
2549 | // Ps = 1 0 2 -> Set background color to Green.
|
2550 | // Ps = 1 0 3 -> Set background color to Yellow.
|
2551 | // Ps = 1 0 4 -> Set background color to Blue.
|
2552 | // Ps = 1 0 5 -> Set background color to Magenta.
|
2553 | // Ps = 1 0 6 -> Set background color to Cyan.
|
2554 | // Ps = 1 0 7 -> Set background color to White.
|
2555 |
|
2556 | // If xterm is compiled with the 16-color support disabled, it
|
2557 | // supports the following, from rxvt:
|
2558 | // Ps = 1 0 0 -> Set foreground and background color to
|
2559 | // default.
|
2560 |
|
2561 | // If 88- or 256-color support is compiled, the following apply.
|
2562 | // Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second
|
2563 | // Ps.
|
2564 | // Ps = 4 8 ; 5 ; Ps -> Set background color to the second
|
2565 | // Ps.
|
2566 | Terminal.prototype.charAttributes = function(params) {
|
2567 | var l = params.length
|
2568 | , i = 0
|
2569 | , bg
|
2570 | , fg
|
2571 | , p;
|
2572 |
|
2573 | for (; i < l; i++) {
|
2574 | p = params[i];
|
2575 | if (p >= 30 && p <= 37) {
|
2576 | // fg color 8
|
2577 | this.curAttr = (this.curAttr & ~(0x1ff << 9)) | ((p - 30) << 9);
|
2578 | } else if (p >= 40 && p <= 47) {
|
2579 | // bg color 8
|
2580 | this.curAttr = (this.curAttr & ~0x1ff) | (p - 40);
|
2581 | } else if (p >= 90 && p <= 97) {
|
2582 | // fg color 16
|
2583 | p += 8;
|
2584 | this.curAttr = (this.curAttr & ~(0x1ff << 9)) | ((p - 90) << 9);
|
2585 | } else if (p >= 100 && p <= 107) {
|
2586 | // bg color 16
|
2587 | p += 8;
|
2588 | this.curAttr = (this.curAttr & ~0x1ff) | (p - 100);
|
2589 | } else if (p === 0) {
|
2590 | // default
|
2591 | this.curAttr = this.defAttr;
|
2592 | } else if (p === 1) {
|
2593 | // bold text
|
2594 | this.curAttr = this.curAttr | (1 << 18);
|
2595 | } else if (p === 4) {
|
2596 | // underlined text
|
2597 | this.curAttr = this.curAttr | (2 << 18);
|
2598 | } else if (p === 7 || p === 27) {
|
2599 | // inverse and positive
|
2600 | // test with: echo -e '\e[31m\e[42mhello\e[7mworld\e[27mhi\e[m'
|
2601 | if (p === 7) {
|
2602 | if ((this.curAttr >> 18) & 4) continue;
|
2603 | this.curAttr = this.curAttr | (4 << 18);
|
2604 | } else if (p === 27) {
|
2605 | if (~(this.curAttr >> 18) & 4) continue;
|
2606 | this.curAttr = this.curAttr & ~(4 << 18);
|
2607 | }
|
2608 |
|
2609 | bg = this.curAttr & 0x1ff;
|
2610 | fg = (this.curAttr >> 9) & 0x1ff;
|
2611 |
|
2612 | this.curAttr = (this.curAttr & ~0x3ffff) | ((bg << 9) | fg);
|
2613 | } else if (p === 22) {
|
2614 | // not bold
|
2615 | this.curAttr = this.curAttr & ~(1 << 18);
|
2616 | } else if (p === 24) {
|
2617 | // not underlined
|
2618 | this.curAttr = this.curAttr & ~(2 << 18);
|
2619 | } else if (p === 39) {
|
2620 | // reset fg
|
2621 | this.curAttr = this.curAttr & ~(0x1ff << 9);
|
2622 | this.curAttr = this.curAttr | (((this.defAttr >> 9) & 0x1ff) << 9);
|
2623 | } else if (p === 49) {
|
2624 | // reset bg
|
2625 | this.curAttr = this.curAttr & ~0x1ff;
|
2626 | this.curAttr = this.curAttr | (this.defAttr & 0x1ff);
|
2627 | } else if (p === 38) {
|
2628 | // fg color 256
|
2629 | if (params[i+1] !== 5) continue;
|
2630 | i += 2;
|
2631 | p = params[i] & 0xff;
|
2632 | // convert 88 colors to 256
|
2633 | // if (this.is('rxvt-unicode') && p < 88) p = p * 2.9090 | 0;
|
2634 | this.curAttr = (this.curAttr & ~(0x1ff << 9)) | (p << 9);
|
2635 | } else if (p === 48) {
|
2636 | // bg color 256
|
2637 | if (params[i+1] !== 5) continue;
|
2638 | i += 2;
|
2639 | p = params[i] & 0xff;
|
2640 | // convert 88 colors to 256
|
2641 | // if (this.is('rxvt-unicode') && p < 88) p = p * 2.9090 | 0;
|
2642 | this.curAttr = (this.curAttr & ~0x1ff) | p;
|
2643 | }
|
2644 | }
|
2645 | };
|
2646 |
|
2647 | // CSI Ps n Device Status Report (DSR).
|
2648 | // Ps = 5 -> Status Report. Result (``OK'') is
|
2649 | // CSI 0 n
|
2650 | // Ps = 6 -> Report Cursor Position (CPR) [row;column].
|
2651 | // Result is
|
2652 | // CSI r ; c R
|
2653 | // CSI ? Ps n
|
2654 | // Device Status Report (DSR, DEC-specific).
|
2655 | // Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI
|
2656 | // ? r ; c R (assumes page is zero).
|
2657 | // Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).
|
2658 | // or CSI ? 1 1 n (not ready).
|
2659 | // Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)
|
2660 | // or CSI ? 2 1 n (locked).
|
2661 | // Ps = 2 6 -> Report Keyboard status as
|
2662 | // CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).
|
2663 | // The last two parameters apply to VT400 & up, and denote key-
|
2664 | // board ready and LK01 respectively.
|
2665 | // Ps = 5 3 -> Report Locator status as
|
2666 | // CSI ? 5 3 n Locator available, if compiled-in, or
|
2667 | // CSI ? 5 0 n No Locator, if not.
|
2668 | Terminal.prototype.deviceStatus = function(params) {
|
2669 | if (!this.prefix) {
|
2670 | switch (params[0]) {
|
2671 | case 5:
|
2672 | // status report
|
2673 | this.send('\x1b[0n');
|
2674 | break;
|
2675 | case 6:
|
2676 | // cursor position
|
2677 | this.send('\x1b['
|
2678 | + (this.y + 1)
|
2679 | + ';'
|
2680 | + (this.x + 1)
|
2681 | + 'R');
|
2682 | break;
|
2683 | }
|
2684 | } else if (this.prefix === '?') {
|
2685 | // modern xterm doesnt seem to
|
2686 | // respond to any of these except ?6, 6, and 5
|
2687 | switch (params[0]) {
|
2688 | case 6:
|
2689 | // cursor position
|
2690 | this.send('\x1b[?'
|
2691 | + (this.y + 1)
|
2692 | + ';'
|
2693 | + (this.x + 1)
|
2694 | + 'R');
|
2695 | break;
|
2696 | case 15:
|
2697 | // no printer
|
2698 | // this.send('\x1b[?11n');
|
2699 | break;
|
2700 | case 25:
|
2701 | // dont support user defined keys
|
2702 | // this.send('\x1b[?21n');
|
2703 | break;
|
2704 | case 26:
|
2705 | // north american keyboard
|
2706 | // this.send('\x1b[?27;1;0;0n');
|
2707 | break;
|
2708 | case 53:
|
2709 | // no dec locator/mouse
|
2710 | // this.send('\x1b[?50n');
|
2711 | break;
|
2712 | }
|
2713 | }
|
2714 | };
|
2715 |
|
2716 | /**
|
2717 | * Additions
|
2718 | */
|
2719 |
|
2720 | // CSI Ps @
|
2721 | // Insert Ps (Blank) Character(s) (default = 1) (ICH).
|
2722 | Terminal.prototype.insertChars = function(params) {
|
2723 | var param, row, j, ch;
|
2724 |
|
2725 | param = params[0];
|
2726 | if (param < 1) param = 1;
|
2727 |
|
2728 | row = this.y + this.ybase;
|
2729 | j = this.x;
|
2730 | ch = [this.curAttr, ' ']; // xterm
|
2731 |
|
2732 | while (param-- && j < this.cols) {
|
2733 | this.lines[row].splice(j++, 0, ch);
|
2734 | this.lines[row].pop();
|
2735 | }
|
2736 | };
|
2737 |
|
2738 | // CSI Ps E
|
2739 | // Cursor Next Line Ps Times (default = 1) (CNL).
|
2740 | // same as CSI Ps B ?
|
2741 | Terminal.prototype.cursorNextLine = function(params) {
|
2742 | var param = params[0];
|
2743 | if (param < 1) param = 1;
|
2744 | this.y += param;
|
2745 | if (this.y >= this.rows) {
|
2746 | this.y = this.rows - 1;
|
2747 | }
|
2748 | this.x = 0;
|
2749 | };
|
2750 |
|
2751 | // CSI Ps F
|
2752 | // Cursor Preceding Line Ps Times (default = 1) (CNL).
|
2753 | // reuse CSI Ps A ?
|
2754 | Terminal.prototype.cursorPrecedingLine = function(params) {
|
2755 | var param = params[0];
|
2756 | if (param < 1) param = 1;
|
2757 | this.y -= param;
|
2758 | if (this.y < 0) this.y = 0;
|
2759 | this.x = 0;
|
2760 | };
|
2761 |
|
2762 | // CSI Ps G
|
2763 | // Cursor Character Absolute [column] (default = [row,1]) (CHA).
|
2764 | Terminal.prototype.cursorCharAbsolute = function(params) {
|
2765 | var param = params[0];
|
2766 | if (param < 1) param = 1;
|
2767 | this.x = param - 1;
|
2768 | };
|
2769 |
|
2770 | // CSI Ps L
|
2771 | // Insert Ps Line(s) (default = 1) (IL).
|
2772 | Terminal.prototype.insertLines = function(params) {
|
2773 | var param, row, j;
|
2774 |
|
2775 | param = params[0];
|
2776 | if (param < 1) param = 1;
|
2777 | row = this.y + this.ybase;
|
2778 |
|
2779 | j = this.rows - 1 - this.scrollBottom;
|
2780 | j = this.rows - 1 + this.ybase - j + 1;
|
2781 |
|
2782 | while (param--) {
|
2783 | // test: echo -e '\e[44m\e[1L\e[0m'
|
2784 | // blankLine(true) - xterm/linux behavior
|
2785 | this.lines.splice(row, 0, this.blankLine(true));
|
2786 | this.lines.splice(j, 1);
|
2787 | }
|
2788 |
|
2789 | // this.maxRange();
|
2790 | this.updateRange(this.y);
|
2791 | this.updateRange(this.scrollBottom);
|
2792 | };
|
2793 |
|
2794 | // CSI Ps M
|
2795 | // Delete Ps Line(s) (default = 1) (DL).
|
2796 | Terminal.prototype.deleteLines = function(params) {
|
2797 | var param, row, j;
|
2798 |
|
2799 | param = params[0];
|
2800 | if (param < 1) param = 1;
|
2801 | row = this.y + this.ybase;
|
2802 |
|
2803 | j = this.rows - 1 - this.scrollBottom;
|
2804 | j = this.rows - 1 + this.ybase - j;
|
2805 |
|
2806 | while (param--) {
|
2807 | // test: echo -e '\e[44m\e[1M\e[0m'
|
2808 | // blankLine(true) - xterm/linux behavior
|
2809 | this.lines.splice(j + 1, 0, this.blankLine(true));
|
2810 | this.lines.splice(row, 1);
|
2811 | }
|
2812 |
|
2813 | // this.maxRange();
|
2814 | this.updateRange(this.y);
|
2815 | this.updateRange(this.scrollBottom);
|
2816 | };
|
2817 |
|
2818 | // CSI Ps P
|
2819 | // Delete Ps Character(s) (default = 1) (DCH).
|
2820 | Terminal.prototype.deleteChars = function(params) {
|
2821 | var param, row, ch;
|
2822 |
|
2823 | param = params[0];
|
2824 | if (param < 1) param = 1;
|
2825 |
|
2826 | row = this.y + this.ybase;
|
2827 | ch = [this.curAttr, ' ']; // xterm
|
2828 |
|
2829 | while (param--) {
|
2830 | this.lines[row].splice(this.x, 1);
|
2831 | this.lines[row].push(ch);
|
2832 | }
|
2833 | };
|
2834 |
|
2835 | // CSI Ps X
|
2836 | // Erase Ps Character(s) (default = 1) (ECH).
|
2837 | Terminal.prototype.eraseChars = function(params) {
|
2838 | var param, row, j, ch;
|
2839 |
|
2840 | param = params[0];
|
2841 | if (param < 1) param = 1;
|
2842 |
|
2843 | row = this.y + this.ybase;
|
2844 | j = this.x;
|
2845 | ch = [this.curAttr, ' ']; // xterm
|
2846 |
|
2847 | while (param-- && j < this.cols) {
|
2848 | this.lines[row][j++] = ch;
|
2849 | }
|
2850 | };
|
2851 |
|
2852 | // CSI Pm ` Character Position Absolute
|
2853 | // [column] (default = [row,1]) (HPA).
|
2854 | Terminal.prototype.charPosAbsolute = function(params) {
|
2855 | var param = params[0];
|
2856 | if (param < 1) param = 1;
|
2857 | this.x = param - 1;
|
2858 | if (this.x >= this.cols) {
|
2859 | this.x = this.cols - 1;
|
2860 | }
|
2861 | };
|
2862 |
|
2863 | // 141 61 a * HPR -
|
2864 | // Horizontal Position Relative
|
2865 | // reuse CSI Ps C ?
|
2866 | Terminal.prototype.HPositionRelative = function(params) {
|
2867 | var param = params[0];
|
2868 | if (param < 1) param = 1;
|
2869 | this.x += param;
|
2870 | if (this.x >= this.cols) {
|
2871 | this.x = this.cols - 1;
|
2872 | }
|
2873 | };
|
2874 |
|
2875 | // CSI Ps c Send Device Attributes (Primary DA).
|
2876 | // Ps = 0 or omitted -> request attributes from terminal. The
|
2877 | // response depends on the decTerminalID resource setting.
|
2878 | // -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')
|
2879 | // -> CSI ? 1 ; 0 c (``VT101 with No Options'')
|
2880 | // -> CSI ? 6 c (``VT102'')
|
2881 | // -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')
|
2882 | // The VT100-style response parameters do not mean anything by
|
2883 | // themselves. VT220 parameters do, telling the host what fea-
|
2884 | // tures the terminal supports:
|
2885 | // Ps = 1 -> 132-columns.
|
2886 | // Ps = 2 -> Printer.
|
2887 | // Ps = 6 -> Selective erase.
|
2888 | // Ps = 8 -> User-defined keys.
|
2889 | // Ps = 9 -> National replacement character sets.
|
2890 | // Ps = 1 5 -> Technical characters.
|
2891 | // Ps = 2 2 -> ANSI color, e.g., VT525.
|
2892 | // Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).
|
2893 | // CSI > Ps c
|
2894 | // Send Device Attributes (Secondary DA).
|
2895 | // Ps = 0 or omitted -> request the terminal's identification
|
2896 | // code. The response depends on the decTerminalID resource set-
|
2897 | // ting. It should apply only to VT220 and up, but xterm extends
|
2898 | // this to VT100.
|
2899 | // -> CSI > Pp ; Pv ; Pc c
|
2900 | // where Pp denotes the terminal type
|
2901 | // Pp = 0 -> ``VT100''.
|
2902 | // Pp = 1 -> ``VT220''.
|
2903 | // and Pv is the firmware version (for xterm, this was originally
|
2904 | // the XFree86 patch number, starting with 95). In a DEC termi-
|
2905 | // nal, Pc indicates the ROM cartridge registration number and is
|
2906 | // always zero.
|
2907 | // More information:
|
2908 | // xterm/charproc.c - line 2012, for more information.
|
2909 | // vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)
|
2910 | Terminal.prototype.sendDeviceAttributes = function(params) {
|
2911 | if (params[0] > 0) return;
|
2912 |
|
2913 | if (!this.prefix) {
|
2914 | if (this.is('xterm')
|
2915 | || this.is('rxvt-unicode')
|
2916 | || this.is('screen')) {
|
2917 | this.send('\x1b[?1;2c');
|
2918 | } else if (this.is('linux')) {
|
2919 | this.send('\x1b[?6c');
|
2920 | }
|
2921 | } else if (this.prefix === '>') {
|
2922 | // xterm and urxvt
|
2923 | // seem to spit this
|
2924 | // out around ~370 times (?).
|
2925 | if (this.is('xterm')) {
|
2926 | this.send('\x1b[>0;276;0c');
|
2927 | } else if (this.is('rxvt-unicode')) {
|
2928 | this.send('\x1b[>85;95;0c');
|
2929 | } else if (this.is('linux')) {
|
2930 | // not supported by linux console.
|
2931 | // linux console echoes parameters.
|
2932 | this.send(params[0] + 'c');
|
2933 | } else if (this.is('screen')) {
|
2934 | this.send('\x1b[>83;40003;0c');
|
2935 | }
|
2936 | }
|
2937 | };
|
2938 |
|
2939 | // CSI Pm d
|
2940 | // Line Position Absolute [row] (default = [1,column]) (VPA).
|
2941 | Terminal.prototype.linePosAbsolute = function(params) {
|
2942 | var param = params[0];
|
2943 | if (param < 1) param = 1;
|
2944 | this.y = param - 1;
|
2945 | if (this.y >= this.rows) {
|
2946 | this.y = this.rows - 1;
|
2947 | }
|
2948 | };
|
2949 |
|
2950 | // 145 65 e * VPR - Vertical Position Relative
|
2951 | // reuse CSI Ps B ?
|
2952 | Terminal.prototype.VPositionRelative = function(params) {
|
2953 | var param = params[0];
|
2954 | if (param < 1) param = 1;
|
2955 | this.y += param;
|
2956 | if (this.y >= this.rows) {
|
2957 | this.y = this.rows - 1;
|
2958 | }
|
2959 | };
|
2960 |
|
2961 | // CSI Ps ; Ps f
|
2962 | // Horizontal and Vertical Position [row;column] (default =
|
2963 | // [1,1]) (HVP).
|
2964 | Terminal.prototype.HVPosition = function(params) {
|
2965 | if (params[0] < 1) params[0] = 1;
|
2966 | if (params[1] < 1) params[1] = 1;
|
2967 |
|
2968 | this.y = params[0] - 1;
|
2969 | if (this.y >= this.rows) {
|
2970 | this.y = this.rows - 1;
|
2971 | }
|
2972 |
|
2973 | this.x = params[1] - 1;
|
2974 | if (this.x >= this.cols) {
|
2975 | this.x = this.cols - 1;
|
2976 | }
|
2977 | };
|
2978 |
|
2979 | // CSI Pm h Set Mode (SM).
|
2980 | // Ps = 2 -> Keyboard Action Mode (AM).
|
2981 | // Ps = 4 -> Insert Mode (IRM).
|
2982 | // Ps = 1 2 -> Send/receive (SRM).
|
2983 | // Ps = 2 0 -> Automatic Newline (LNM).
|
2984 | // CSI ? Pm h
|
2985 | // DEC Private Mode Set (DECSET).
|
2986 | // Ps = 1 -> Application Cursor Keys (DECCKM).
|
2987 | // Ps = 2 -> Designate USASCII for character sets G0-G3
|
2988 | // (DECANM), and set VT100 mode.
|
2989 | // Ps = 3 -> 132 Column Mode (DECCOLM).
|
2990 | // Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).
|
2991 | // Ps = 5 -> Reverse Video (DECSCNM).
|
2992 | // Ps = 6 -> Origin Mode (DECOM).
|
2993 | // Ps = 7 -> Wraparound Mode (DECAWM).
|
2994 | // Ps = 8 -> Auto-repeat Keys (DECARM).
|
2995 | // Ps = 9 -> Send Mouse X & Y on button press. See the sec-
|
2996 | // tion Mouse Tracking.
|
2997 | // Ps = 1 0 -> Show toolbar (rxvt).
|
2998 | // Ps = 1 2 -> Start Blinking Cursor (att610).
|
2999 | // Ps = 1 8 -> Print form feed (DECPFF).
|
3000 | // Ps = 1 9 -> Set print extent to full screen (DECPEX).
|
3001 | // Ps = 2 5 -> Show Cursor (DECTCEM).
|
3002 | // Ps = 3 0 -> Show scrollbar (rxvt).
|
3003 | // Ps = 3 5 -> Enable font-shifting functions (rxvt).
|
3004 | // Ps = 3 8 -> Enter Tektronix Mode (DECTEK).
|
3005 | // Ps = 4 0 -> Allow 80 -> 132 Mode.
|
3006 | // Ps = 4 1 -> more(1) fix (see curses resource).
|
3007 | // Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-
|
3008 | // RCM).
|
3009 | // Ps = 4 4 -> Turn On Margin Bell.
|
3010 | // Ps = 4 5 -> Reverse-wraparound Mode.
|
3011 | // Ps = 4 6 -> Start Logging. This is normally disabled by a
|
3012 | // compile-time option.
|
3013 | // Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-
|
3014 | // abled by the titeInhibit resource).
|
3015 | // Ps = 6 6 -> Application keypad (DECNKM).
|
3016 | // Ps = 6 7 -> Backarrow key sends backspace (DECBKM).
|
3017 | // Ps = 1 0 0 0 -> Send Mouse X & Y on button press and
|
3018 | // release. See the section Mouse Tracking.
|
3019 | // Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.
|
3020 | // Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.
|
3021 | // Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.
|
3022 | // Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.
|
3023 | // Ps = 1 0 0 5 -> Enable Extended Mouse Mode.
|
3024 | // Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).
|
3025 | // Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).
|
3026 | // Ps = 1 0 3 4 -> Interpret "meta" key, sets eighth bit.
|
3027 | // (enables the eightBitInput resource).
|
3028 | // Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-
|
3029 | // Lock keys. (This enables the numLock resource).
|
3030 | // Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This
|
3031 | // enables the metaSendsEscape resource).
|
3032 | // Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete
|
3033 | // key.
|
3034 | // Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This
|
3035 | // enables the altSendsEscape resource).
|
3036 | // Ps = 1 0 4 0 -> Keep selection even if not highlighted.
|
3037 | // (This enables the keepSelection resource).
|
3038 | // Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables
|
3039 | // the selectToClipboard resource).
|
3040 | // Ps = 1 0 4 2 -> Enable Urgency window manager hint when
|
3041 | // Control-G is received. (This enables the bellIsUrgent
|
3042 | // resource).
|
3043 | // Ps = 1 0 4 3 -> Enable raising of the window when Control-G
|
3044 | // is received. (enables the popOnBell resource).
|
3045 | // Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be
|
3046 | // disabled by the titeInhibit resource).
|
3047 | // Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-
|
3048 | // abled by the titeInhibit resource).
|
3049 | // Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate
|
3050 | // Screen Buffer, clearing it first. (This may be disabled by
|
3051 | // the titeInhibit resource). This combines the effects of the 1
|
3052 | // 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based
|
3053 | // applications rather than the 4 7 mode.
|
3054 | // Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.
|
3055 | // Ps = 1 0 5 1 -> Set Sun function-key mode.
|
3056 | // Ps = 1 0 5 2 -> Set HP function-key mode.
|
3057 | // Ps = 1 0 5 3 -> Set SCO function-key mode.
|
3058 | // Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).
|
3059 | // Ps = 1 0 6 1 -> Set VT220 keyboard emulation.
|
3060 | // Ps = 2 0 0 4 -> Set bracketed paste mode.
|
3061 | // Modes:
|
3062 | // http://vt100.net/docs/vt220-rm/chapter4.html
|
3063 | Terminal.prototype.setMode = function(params) {
|
3064 | if (typeof params === 'object') {
|
3065 | var l = params.length
|
3066 | , i = 0;
|
3067 |
|
3068 | for (; i < l; i++) {
|
3069 | this.setMode(params[i]);
|
3070 | }
|
3071 |
|
3072 | return;
|
3073 | }
|
3074 |
|
3075 | if (!this.prefix) {
|
3076 | switch (params) {
|
3077 | case 4:
|
3078 | this.insertMode = true;
|
3079 | break;
|
3080 | case 20:
|
3081 | //this.convertEol = true;
|
3082 | break;
|
3083 | }
|
3084 | } else if (this.prefix === '?') {
|
3085 | switch (params) {
|
3086 | case 1:
|
3087 | this.applicationKeypad = true;
|
3088 | break;
|
3089 | case 2:
|
3090 | this.setgCharset(0, Terminal.charsets.US);
|
3091 | this.setgCharset(1, Terminal.charsets.US);
|
3092 | this.setgCharset(2, Terminal.charsets.US);
|
3093 | this.setgCharset(3, Terminal.charsets.US);
|
3094 | // set VT100 mode here
|
3095 | break;
|
3096 | case 3: // 132 col mode
|
3097 | this.savedCols = this.cols;
|
3098 | this.resize(132, this.rows);
|
3099 | break;
|
3100 | case 6:
|
3101 | this.originMode = true;
|
3102 | break;
|
3103 | case 7:
|
3104 | this.wraparoundMode = true;
|
3105 | break;
|
3106 | case 12:
|
3107 | // this.cursorBlink = true;
|
3108 | break;
|
3109 | case 9: // X10 Mouse
|
3110 | // no release, no motion, no wheel, no modifiers.
|
3111 | case 1000: // vt200 mouse
|
3112 | // no motion.
|
3113 | // no modifiers, except control on the wheel.
|
3114 | case 1002: // button event mouse
|
3115 | case 1003: // any event mouse
|
3116 | // any event - sends motion events,
|
3117 | // even if there is no button held down.
|
3118 | this.x10Mouse = params === 9;
|
3119 | this.vt200Mouse = params === 1000;
|
3120 | this.normalMouse = params > 1000;
|
3121 | this.mouseEvents = true;
|
3122 | this.element.style.cursor = 'default';
|
3123 | this.log('Binding to mouse events.');
|
3124 | break;
|
3125 | case 1004: // send focusin/focusout events
|
3126 | // focusin: ^[[I
|
3127 | // focusout: ^[[O
|
3128 | this.sendFocus = true;
|
3129 | break;
|
3130 | case 1005: // utf8 ext mode mouse
|
3131 | this.utfMouse = true;
|
3132 | // for wide terminals
|
3133 | // simply encodes large values as utf8 characters
|
3134 | break;
|
3135 | case 1006: // sgr ext mode mouse
|
3136 | this.sgrMouse = true;
|
3137 | // for wide terminals
|
3138 | // does not add 32 to fields
|
3139 | // press: ^[[<b;x;yM
|
3140 | // release: ^[[<b;x;ym
|
3141 | break;
|
3142 | case 1015: // urxvt ext mode mouse
|
3143 | this.urxvtMouse = true;
|
3144 | // for wide terminals
|
3145 | // numbers for fields
|
3146 | // press: ^[[b;x;yM
|
3147 | // motion: ^[[b;x;yT
|
3148 | break;
|
3149 | case 25: // show cursor
|
3150 | this.cursorHidden = false;
|
3151 | break;
|
3152 | case 1049: // alt screen buffer cursor
|
3153 | //this.saveCursor();
|
3154 | ; // FALL-THROUGH
|
3155 | case 47: // alt screen buffer
|
3156 | case 1047: // alt screen buffer
|
3157 | if (!this.normal) {
|
3158 | var normal = {
|
3159 | lines: this.lines,
|
3160 | ybase: this.ybase,
|
3161 | ydisp: this.ydisp,
|
3162 | x: this.x,
|
3163 | y: this.y,
|
3164 | scrollTop: this.scrollTop,
|
3165 | scrollBottom: this.scrollBottom,
|
3166 | tabs: this.tabs
|
3167 | // XXX save charset(s) here?
|
3168 | // charset: this.charset,
|
3169 | // glevel: this.glevel,
|
3170 | // charsets: this.charsets
|
3171 | };
|
3172 | this.reset();
|
3173 | this.normal = normal;
|
3174 | this.showCursor();
|
3175 | }
|
3176 | break;
|
3177 | }
|
3178 | }
|
3179 | };
|
3180 |
|
3181 | // CSI Pm l Reset Mode (RM).
|
3182 | // Ps = 2 -> Keyboard Action Mode (AM).
|
3183 | // Ps = 4 -> Replace Mode (IRM).
|
3184 | // Ps = 1 2 -> Send/receive (SRM).
|
3185 | // Ps = 2 0 -> Normal Linefeed (LNM).
|
3186 | // CSI ? Pm l
|
3187 | // DEC Private Mode Reset (DECRST).
|
3188 | // Ps = 1 -> Normal Cursor Keys (DECCKM).
|
3189 | // Ps = 2 -> Designate VT52 mode (DECANM).
|
3190 | // Ps = 3 -> 80 Column Mode (DECCOLM).
|
3191 | // Ps = 4 -> Jump (Fast) Scroll (DECSCLM).
|
3192 | // Ps = 5 -> Normal Video (DECSCNM).
|
3193 | // Ps = 6 -> Normal Cursor Mode (DECOM).
|
3194 | // Ps = 7 -> No Wraparound Mode (DECAWM).
|
3195 | // Ps = 8 -> No Auto-repeat Keys (DECARM).
|
3196 | // Ps = 9 -> Don't send Mouse X & Y on button press.
|
3197 | // Ps = 1 0 -> Hide toolbar (rxvt).
|
3198 | // Ps = 1 2 -> Stop Blinking Cursor (att610).
|
3199 | // Ps = 1 8 -> Don't print form feed (DECPFF).
|
3200 | // Ps = 1 9 -> Limit print to scrolling region (DECPEX).
|
3201 | // Ps = 2 5 -> Hide Cursor (DECTCEM).
|
3202 | // Ps = 3 0 -> Don't show scrollbar (rxvt).
|
3203 | // Ps = 3 5 -> Disable font-shifting functions (rxvt).
|
3204 | // Ps = 4 0 -> Disallow 80 -> 132 Mode.
|
3205 | // Ps = 4 1 -> No more(1) fix (see curses resource).
|
3206 | // Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-
|
3207 | // NRCM).
|
3208 | // Ps = 4 4 -> Turn Off Margin Bell.
|
3209 | // Ps = 4 5 -> No Reverse-wraparound Mode.
|
3210 | // Ps = 4 6 -> Stop Logging. (This is normally disabled by a
|
3211 | // compile-time option).
|
3212 | // Ps = 4 7 -> Use Normal Screen Buffer.
|
3213 | // Ps = 6 6 -> Numeric keypad (DECNKM).
|
3214 | // Ps = 6 7 -> Backarrow key sends delete (DECBKM).
|
3215 | // Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and
|
3216 | // release. See the section Mouse Tracking.
|
3217 | // Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.
|
3218 | // Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.
|
3219 | // Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.
|
3220 | // Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.
|
3221 | // Ps = 1 0 0 5 -> Disable Extended Mouse Mode.
|
3222 | // Ps = 1 0 1 0 -> Don't scroll to bottom on tty output
|
3223 | // (rxvt).
|
3224 | // Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).
|
3225 | // Ps = 1 0 3 4 -> Don't interpret "meta" key. (This disables
|
3226 | // the eightBitInput resource).
|
3227 | // Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-
|
3228 | // Lock keys. (This disables the numLock resource).
|
3229 | // Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.
|
3230 | // (This disables the metaSendsEscape resource).
|
3231 | // Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad
|
3232 | // Delete key.
|
3233 | // Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.
|
3234 | // (This disables the altSendsEscape resource).
|
3235 | // Ps = 1 0 4 0 -> Do not keep selection when not highlighted.
|
3236 | // (This disables the keepSelection resource).
|
3237 | // Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables
|
3238 | // the selectToClipboard resource).
|
3239 | // Ps = 1 0 4 2 -> Disable Urgency window manager hint when
|
3240 | // Control-G is received. (This disables the bellIsUrgent
|
3241 | // resource).
|
3242 | // Ps = 1 0 4 3 -> Disable raising of the window when Control-
|
3243 | // G is received. (This disables the popOnBell resource).
|
3244 | // Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen
|
3245 | // first if in the Alternate Screen. (This may be disabled by
|
3246 | // the titeInhibit resource).
|
3247 | // Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be
|
3248 | // disabled by the titeInhibit resource).
|
3249 | // Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor
|
3250 | // as in DECRC. (This may be disabled by the titeInhibit
|
3251 | // resource). This combines the effects of the 1 0 4 7 and 1 0
|
3252 | // 4 8 modes. Use this with terminfo-based applications rather
|
3253 | // than the 4 7 mode.
|
3254 | // Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.
|
3255 | // Ps = 1 0 5 1 -> Reset Sun function-key mode.
|
3256 | // Ps = 1 0 5 2 -> Reset HP function-key mode.
|
3257 | // Ps = 1 0 5 3 -> Reset SCO function-key mode.
|
3258 | // Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).
|
3259 | // Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.
|
3260 | // Ps = 2 0 0 4 -> Reset bracketed paste mode.
|
3261 | Terminal.prototype.resetMode = function(params) {
|
3262 | if (typeof params === 'object') {
|
3263 | var l = params.length
|
3264 | , i = 0;
|
3265 |
|
3266 | for (; i < l; i++) {
|
3267 | this.resetMode(params[i]);
|
3268 | }
|
3269 |
|
3270 | return;
|
3271 | }
|
3272 |
|
3273 | if (!this.prefix) {
|
3274 | switch (params) {
|
3275 | case 4:
|
3276 | this.insertMode = false;
|
3277 | break;
|
3278 | case 20:
|
3279 | //this.convertEol = false;
|
3280 | break;
|
3281 | }
|
3282 | } else if (this.prefix === '?') {
|
3283 | switch (params) {
|
3284 | case 1:
|
3285 | this.applicationKeypad = false;
|
3286 | break;
|
3287 | case 3:
|
3288 | if (this.cols === 132 && this.savedCols) {
|
3289 | this.resize(this.savedCols, this.rows);
|
3290 | }
|
3291 | delete this.savedCols;
|
3292 | break;
|
3293 | case 6:
|
3294 | this.originMode = false;
|
3295 | break;
|
3296 | case 7:
|
3297 | this.wraparoundMode = false;
|
3298 | break;
|
3299 | case 12:
|
3300 | // this.cursorBlink = false;
|
3301 | break;
|
3302 | case 9: // X10 Mouse
|
3303 | case 1000: // vt200 mouse
|
3304 | case 1002: // button event mouse
|
3305 | case 1003: // any event mouse
|
3306 | this.x10Mouse = false;
|
3307 | this.vt200Mouse = false;
|
3308 | this.normalMouse = false;
|
3309 | this.mouseEvents = false;
|
3310 | this.element.style.cursor = '';
|
3311 | break;
|
3312 | case 1004: // send focusin/focusout events
|
3313 | this.sendFocus = false;
|
3314 | break;
|
3315 | case 1005: // utf8 ext mode mouse
|
3316 | this.utfMouse = false;
|
3317 | break;
|
3318 | case 1006: // sgr ext mode mouse
|
3319 | this.sgrMouse = false;
|
3320 | break;
|
3321 | case 1015: // urxvt ext mode mouse
|
3322 | this.urxvtMouse = false;
|
3323 | break;
|
3324 | case 25: // hide cursor
|
3325 | this.cursorHidden = true;
|
3326 | break;
|
3327 | case 1049: // alt screen buffer cursor
|
3328 | ; // FALL-THROUGH
|
3329 | case 47: // normal screen buffer
|
3330 | case 1047: // normal screen buffer - clearing it first
|
3331 | if (this.normal) {
|
3332 | this.lines = this.normal.lines;
|
3333 | this.ybase = this.normal.ybase;
|
3334 | this.ydisp = this.normal.ydisp;
|
3335 | this.x = this.normal.x;
|
3336 | this.y = this.normal.y;
|
3337 | this.scrollTop = this.normal.scrollTop;
|
3338 | this.scrollBottom = this.normal.scrollBottom;
|
3339 | this.tabs = this.normal.tabs;
|
3340 | this.normal = null;
|
3341 | // if (params === 1049) {
|
3342 | // this.x = this.savedX;
|
3343 | // this.y = this.savedY;
|
3344 | // }
|
3345 | this.refresh(0, this.rows - 1);
|
3346 | this.showCursor();
|
3347 | }
|
3348 | break;
|
3349 | }
|
3350 | }
|
3351 | };
|
3352 |
|
3353 | // CSI Ps ; Ps r
|
3354 | // Set Scrolling Region [top;bottom] (default = full size of win-
|
3355 | // dow) (DECSTBM).
|
3356 | // CSI ? Pm r
|
3357 | Terminal.prototype.setScrollRegion = function(params) {
|
3358 | if (this.prefix) return;
|
3359 | this.scrollTop = (params[0] || 1) - 1;
|
3360 | this.scrollBottom = (params[1] || this.rows) - 1;
|
3361 | this.x = 0;
|
3362 | this.y = 0;
|
3363 | };
|
3364 |
|
3365 | // CSI s
|
3366 | // Save cursor (ANSI.SYS).
|
3367 | Terminal.prototype.saveCursor = function(params) {
|
3368 | this.savedX = this.x;
|
3369 | this.savedY = this.y;
|
3370 | };
|
3371 |
|
3372 | // CSI u
|
3373 | // Restore cursor (ANSI.SYS).
|
3374 | Terminal.prototype.restoreCursor = function(params) {
|
3375 | this.x = this.savedX || 0;
|
3376 | this.y = this.savedY || 0;
|
3377 | };
|
3378 |
|
3379 | /**
|
3380 | * Lesser Used
|
3381 | */
|
3382 |
|
3383 | // CSI Ps I
|
3384 | // Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).
|
3385 | Terminal.prototype.cursorForwardTab = function(params) {
|
3386 | var param = params[0] || 1;
|
3387 | while (param--) {
|
3388 | this.x = this.nextStop();
|
3389 | }
|
3390 | };
|
3391 |
|
3392 | // CSI Ps S Scroll up Ps lines (default = 1) (SU).
|
3393 | Terminal.prototype.scrollUp = function(params) {
|
3394 | var param = params[0] || 1;
|
3395 | while (param--) {
|
3396 | this.lines.splice(this.ybase + this.scrollTop, 1);
|
3397 | this.lines.splice(this.ybase + this.scrollBottom, 0, this.blankLine());
|
3398 | }
|
3399 | // this.maxRange();
|
3400 | this.updateRange(this.scrollTop);
|
3401 | this.updateRange(this.scrollBottom);
|
3402 | };
|
3403 |
|
3404 | // CSI Ps T Scroll down Ps lines (default = 1) (SD).
|
3405 | Terminal.prototype.scrollDown = function(params) {
|
3406 | var param = params[0] || 1;
|
3407 | while (param--) {
|
3408 | this.lines.splice(this.ybase + this.scrollBottom, 1);
|
3409 | this.lines.splice(this.ybase + this.scrollTop, 0, this.blankLine());
|
3410 | }
|
3411 | // this.maxRange();
|
3412 | this.updateRange(this.scrollTop);
|
3413 | this.updateRange(this.scrollBottom);
|
3414 | };
|
3415 |
|
3416 | // CSI Ps ; Ps ; Ps ; Ps ; Ps T
|
3417 | // Initiate highlight mouse tracking. Parameters are
|
3418 | // [func;startx;starty;firstrow;lastrow]. See the section Mouse
|
3419 | // Tracking.
|
3420 | Terminal.prototype.initMouseTracking = function(params) {
|
3421 | // Relevant: DECSET 1001
|
3422 | };
|
3423 |
|
3424 | // CSI > Ps; Ps T
|
3425 | // Reset one or more features of the title modes to the default
|
3426 | // value. Normally, "reset" disables the feature. It is possi-
|
3427 | // ble to disable the ability to reset features by compiling a
|
3428 | // different default for the title modes into xterm.
|
3429 | // Ps = 0 -> Do not set window/icon labels using hexadecimal.
|
3430 | // Ps = 1 -> Do not query window/icon labels using hexadeci-
|
3431 | // mal.
|
3432 | // Ps = 2 -> Do not set window/icon labels using UTF-8.
|
3433 | // Ps = 3 -> Do not query window/icon labels using UTF-8.
|
3434 | // (See discussion of "Title Modes").
|
3435 | Terminal.prototype.resetTitleModes = function(params) {
|
3436 | ;
|
3437 | };
|
3438 |
|
3439 | // CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).
|
3440 | Terminal.prototype.cursorBackwardTab = function(params) {
|
3441 | var param = params[0] || 1;
|
3442 | while (param--) {
|
3443 | this.x = this.prevStop();
|
3444 | }
|
3445 | };
|
3446 |
|
3447 | // CSI Ps b Repeat the preceding graphic character Ps times (REP).
|
3448 | Terminal.prototype.repeatPrecedingCharacter = function(params) {
|
3449 | var param = params[0] || 1
|
3450 | , line = this.lines[this.ybase + this.y]
|
3451 | , ch = line[this.x - 1] || [this.defAttr, ' '];
|
3452 |
|
3453 | while (param--) line[this.x++] = ch;
|
3454 | };
|
3455 |
|
3456 | // CSI Ps g Tab Clear (TBC).
|
3457 | // Ps = 0 -> Clear Current Column (default).
|
3458 | // Ps = 3 -> Clear All.
|
3459 | // Potentially:
|
3460 | // Ps = 2 -> Clear Stops on Line.
|
3461 | // http://vt100.net/annarbor/aaa-ug/section6.html
|
3462 | Terminal.prototype.tabClear = function(params) {
|
3463 | var param = params[0];
|
3464 | if (param <= 0) {
|
3465 | delete this.tabs[this.x];
|
3466 | } else if (param === 3) {
|
3467 | this.tabs = {};
|
3468 | }
|
3469 | };
|
3470 |
|
3471 | // CSI Pm i Media Copy (MC).
|
3472 | // Ps = 0 -> Print screen (default).
|
3473 | // Ps = 4 -> Turn off printer controller mode.
|
3474 | // Ps = 5 -> Turn on printer controller mode.
|
3475 | // CSI ? Pm i
|
3476 | // Media Copy (MC, DEC-specific).
|
3477 | // Ps = 1 -> Print line containing cursor.
|
3478 | // Ps = 4 -> Turn off autoprint mode.
|
3479 | // Ps = 5 -> Turn on autoprint mode.
|
3480 | // Ps = 1 0 -> Print composed display, ignores DECPEX.
|
3481 | // Ps = 1 1 -> Print all pages.
|
3482 | Terminal.prototype.mediaCopy = function(params) {
|
3483 | ;
|
3484 | };
|
3485 |
|
3486 | // CSI > Ps; Ps m
|
3487 | // Set or reset resource-values used by xterm to decide whether
|
3488 | // to construct escape sequences holding information about the
|
3489 | // modifiers pressed with a given key. The first parameter iden-
|
3490 | // tifies the resource to set/reset. The second parameter is the
|
3491 | // value to assign to the resource. If the second parameter is
|
3492 | // omitted, the resource is reset to its initial value.
|
3493 | // Ps = 1 -> modifyCursorKeys.
|
3494 | // Ps = 2 -> modifyFunctionKeys.
|
3495 | // Ps = 4 -> modifyOtherKeys.
|
3496 | // If no parameters are given, all resources are reset to their
|
3497 | // initial values.
|
3498 | Terminal.prototype.setResources = function(params) {
|
3499 | ;
|
3500 | };
|
3501 |
|
3502 | // CSI > Ps n
|
3503 | // Disable modifiers which may be enabled via the CSI > Ps; Ps m
|
3504 | // sequence. This corresponds to a resource value of "-1", which
|
3505 | // cannot be set with the other sequence. The parameter identi-
|
3506 | // fies the resource to be disabled:
|
3507 | // Ps = 1 -> modifyCursorKeys.
|
3508 | // Ps = 2 -> modifyFunctionKeys.
|
3509 | // Ps = 4 -> modifyOtherKeys.
|
3510 | // If the parameter is omitted, modifyFunctionKeys is disabled.
|
3511 | // When modifyFunctionKeys is disabled, xterm uses the modifier
|
3512 | // keys to make an extended sequence of functions rather than
|
3513 | // adding a parameter to each function key to denote the modi-
|
3514 | // fiers.
|
3515 | Terminal.prototype.disableModifiers = function(params) {
|
3516 | ;
|
3517 | };
|
3518 |
|
3519 | // CSI > Ps p
|
3520 | // Set resource value pointerMode. This is used by xterm to
|
3521 | // decide whether to hide the pointer cursor as the user types.
|
3522 | // Valid values for the parameter:
|
3523 | // Ps = 0 -> never hide the pointer.
|
3524 | // Ps = 1 -> hide if the mouse tracking mode is not enabled.
|
3525 | // Ps = 2 -> always hide the pointer. If no parameter is
|
3526 | // given, xterm uses the default, which is 1 .
|
3527 | Terminal.prototype.setPointerMode = function(params) {
|
3528 | ;
|
3529 | };
|
3530 |
|
3531 | // CSI ! p Soft terminal reset (DECSTR).
|
3532 | // http://vt100.net/docs/vt220-rm/table4-10.html
|
3533 | Terminal.prototype.softReset = function(params) {
|
3534 | this.cursorHidden = false;
|
3535 | this.insertMode = false;
|
3536 | this.originMode = false;
|
3537 | this.wraparoundMode = false; // autowrap
|
3538 | this.applicationKeypad = false; // ?
|
3539 | this.scrollTop = 0;
|
3540 | this.scrollBottom = this.rows - 1;
|
3541 | this.curAttr = this.defAttr;
|
3542 | this.x = this.y = 0; // ?
|
3543 | this.charset = null;
|
3544 | this.glevel = 0; // ??
|
3545 | this.charsets = [null]; // ??
|
3546 | };
|
3547 |
|
3548 | // CSI Ps$ p
|
3549 | // Request ANSI mode (DECRQM). For VT300 and up, reply is
|
3550 | // CSI Ps; Pm$ y
|
3551 | // where Ps is the mode number as in RM, and Pm is the mode
|
3552 | // value:
|
3553 | // 0 - not recognized
|
3554 | // 1 - set
|
3555 | // 2 - reset
|
3556 | // 3 - permanently set
|
3557 | // 4 - permanently reset
|
3558 | Terminal.prototype.requestAnsiMode = function(params) {
|
3559 | ;
|
3560 | };
|
3561 |
|
3562 | // CSI ? Ps$ p
|
3563 | // Request DEC private mode (DECRQM). For VT300 and up, reply is
|
3564 | // CSI ? Ps; Pm$ p
|
3565 | // where Ps is the mode number as in DECSET, Pm is the mode value
|
3566 | // as in the ANSI DECRQM.
|
3567 | Terminal.prototype.requestPrivateMode = function(params) {
|
3568 | ;
|
3569 | };
|
3570 |
|
3571 | // CSI Ps ; Ps " p
|
3572 | // Set conformance level (DECSCL). Valid values for the first
|
3573 | // parameter:
|
3574 | // Ps = 6 1 -> VT100.
|
3575 | // Ps = 6 2 -> VT200.
|
3576 | // Ps = 6 3 -> VT300.
|
3577 | // Valid values for the second parameter:
|
3578 | // Ps = 0 -> 8-bit controls.
|
3579 | // Ps = 1 -> 7-bit controls (always set for VT100).
|
3580 | // Ps = 2 -> 8-bit controls.
|
3581 | Terminal.prototype.setConformanceLevel = function(params) {
|
3582 | ;
|
3583 | };
|
3584 |
|
3585 | // CSI Ps q Load LEDs (DECLL).
|
3586 | // Ps = 0 -> Clear all LEDS (default).
|
3587 | // Ps = 1 -> Light Num Lock.
|
3588 | // Ps = 2 -> Light Caps Lock.
|
3589 | // Ps = 3 -> Light Scroll Lock.
|
3590 | // Ps = 2 1 -> Extinguish Num Lock.
|
3591 | // Ps = 2 2 -> Extinguish Caps Lock.
|
3592 | // Ps = 2 3 -> Extinguish Scroll Lock.
|
3593 | Terminal.prototype.loadLEDs = function(params) {
|
3594 | ;
|
3595 | };
|
3596 |
|
3597 | // CSI Ps SP q
|
3598 | // Set cursor style (DECSCUSR, VT520).
|
3599 | // Ps = 0 -> blinking block.
|
3600 | // Ps = 1 -> blinking block (default).
|
3601 | // Ps = 2 -> steady block.
|
3602 | // Ps = 3 -> blinking underline.
|
3603 | // Ps = 4 -> steady underline.
|
3604 | Terminal.prototype.setCursorStyle = function(params) {
|
3605 | ;
|
3606 | };
|
3607 |
|
3608 | // CSI Ps " q
|
3609 | // Select character protection attribute (DECSCA). Valid values
|
3610 | // for the parameter:
|
3611 | // Ps = 0 -> DECSED and DECSEL can erase (default).
|
3612 | // Ps = 1 -> DECSED and DECSEL cannot erase.
|
3613 | // Ps = 2 -> DECSED and DECSEL can erase.
|
3614 | Terminal.prototype.setCharProtectionAttr = function(params) {
|
3615 | ;
|
3616 | };
|
3617 |
|
3618 | // CSI ? Pm r
|
3619 | // Restore DEC Private Mode Values. The value of Ps previously
|
3620 | // saved is restored. Ps values are the same as for DECSET.
|
3621 | Terminal.prototype.restorePrivateValues = function(params) {
|
3622 | ;
|
3623 | };
|
3624 |
|
3625 | // CSI Pt; Pl; Pb; Pr; Ps$ r
|
3626 | // Change Attributes in Rectangular Area (DECCARA), VT400 and up.
|
3627 | // Pt; Pl; Pb; Pr denotes the rectangle.
|
3628 | // Ps denotes the SGR attributes to change: 0, 1, 4, 5, 7.
|
3629 | // NOTE: xterm doesn't enable this code by default.
|
3630 | Terminal.prototype.setAttrInRectangle = function(params) {
|
3631 | var t = params[0]
|
3632 | , l = params[1]
|
3633 | , b = params[2]
|
3634 | , r = params[3]
|
3635 | , attr = params[4];
|
3636 |
|
3637 | var line
|
3638 | , i;
|
3639 |
|
3640 | for (; t < b + 1; t++) {
|
3641 | line = this.lines[this.ybase + t];
|
3642 | for (i = l; i < r; i++) {
|
3643 | line[i] = [attr, line[i][1]];
|
3644 | }
|
3645 | }
|
3646 |
|
3647 | // this.maxRange();
|
3648 | this.updateRange(params[0]);
|
3649 | this.updateRange(params[2]);
|
3650 | };
|
3651 |
|
3652 | // CSI ? Pm s
|
3653 | // Save DEC Private Mode Values. Ps values are the same as for
|
3654 | // DECSET.
|
3655 | Terminal.prototype.savePrivateValues = function(params) {
|
3656 | ;
|
3657 | };
|
3658 |
|
3659 | // CSI Ps ; Ps ; Ps t
|
3660 | // Window manipulation (from dtterm, as well as extensions).
|
3661 | // These controls may be disabled using the allowWindowOps
|
3662 | // resource. Valid values for the first (and any additional
|
3663 | // parameters) are:
|
3664 | // Ps = 1 -> De-iconify window.
|
3665 | // Ps = 2 -> Iconify window.
|
3666 | // Ps = 3 ; x ; y -> Move window to [x, y].
|
3667 | // Ps = 4 ; height ; width -> Resize the xterm window to
|
3668 | // height and width in pixels.
|
3669 | // Ps = 5 -> Raise the xterm window to the front of the stack-
|
3670 | // ing order.
|
3671 | // Ps = 6 -> Lower the xterm window to the bottom of the
|
3672 | // stacking order.
|
3673 | // Ps = 7 -> Refresh the xterm window.
|
3674 | // Ps = 8 ; height ; width -> Resize the text area to
|
3675 | // [height;width] in characters.
|
3676 | // Ps = 9 ; 0 -> Restore maximized window.
|
3677 | // Ps = 9 ; 1 -> Maximize window (i.e., resize to screen
|
3678 | // size).
|
3679 | // Ps = 1 0 ; 0 -> Undo full-screen mode.
|
3680 | // Ps = 1 0 ; 1 -> Change to full-screen.
|
3681 | // Ps = 1 1 -> Report xterm window state. If the xterm window
|
3682 | // is open (non-iconified), it returns CSI 1 t . If the xterm
|
3683 | // window is iconified, it returns CSI 2 t .
|
3684 | // Ps = 1 3 -> Report xterm window position. Result is CSI 3
|
3685 | // ; x ; y t
|
3686 | // Ps = 1 4 -> Report xterm window in pixels. Result is CSI
|
3687 | // 4 ; height ; width t
|
3688 | // Ps = 1 8 -> Report the size of the text area in characters.
|
3689 | // Result is CSI 8 ; height ; width t
|
3690 | // Ps = 1 9 -> Report the size of the screen in characters.
|
3691 | // Result is CSI 9 ; height ; width t
|
3692 | // Ps = 2 0 -> Report xterm window's icon label. Result is
|
3693 | // OSC L label ST
|
3694 | // Ps = 2 1 -> Report xterm window's title. Result is OSC l
|
3695 | // label ST
|
3696 | // Ps = 2 2 ; 0 -> Save xterm icon and window title on
|
3697 | // stack.
|
3698 | // Ps = 2 2 ; 1 -> Save xterm icon title on stack.
|
3699 | // Ps = 2 2 ; 2 -> Save xterm window title on stack.
|
3700 | // Ps = 2 3 ; 0 -> Restore xterm icon and window title from
|
3701 | // stack.
|
3702 | // Ps = 2 3 ; 1 -> Restore xterm icon title from stack.
|
3703 | // Ps = 2 3 ; 2 -> Restore xterm window title from stack.
|
3704 | // Ps >= 2 4 -> Resize to Ps lines (DECSLPP).
|
3705 | Terminal.prototype.manipulateWindow = function(params) {
|
3706 | ;
|
3707 | };
|
3708 |
|
3709 | // CSI Pt; Pl; Pb; Pr; Ps$ t
|
3710 | // Reverse Attributes in Rectangular Area (DECRARA), VT400 and
|
3711 | // up.
|
3712 | // Pt; Pl; Pb; Pr denotes the rectangle.
|
3713 | // Ps denotes the attributes to reverse, i.e., 1, 4, 5, 7.
|
3714 | // NOTE: xterm doesn't enable this code by default.
|
3715 | Terminal.prototype.reverseAttrInRectangle = function(params) {
|
3716 | ;
|
3717 | };
|
3718 |
|
3719 | // CSI > Ps; Ps t
|
3720 | // Set one or more features of the title modes. Each parameter
|
3721 | // enables a single feature.
|
3722 | // Ps = 0 -> Set window/icon labels using hexadecimal.
|
3723 | // Ps = 1 -> Query window/icon labels using hexadecimal.
|
3724 | // Ps = 2 -> Set window/icon labels using UTF-8.
|
3725 | // Ps = 3 -> Query window/icon labels using UTF-8. (See dis-
|
3726 | // cussion of "Title Modes")
|
3727 | Terminal.prototype.setTitleModeFeature = function(params) {
|
3728 | ;
|
3729 | };
|
3730 |
|
3731 | // CSI Ps SP t
|
3732 | // Set warning-bell volume (DECSWBV, VT520).
|
3733 | // Ps = 0 or 1 -> off.
|
3734 | // Ps = 2 , 3 or 4 -> low.
|
3735 | // Ps = 5 , 6 , 7 , or 8 -> high.
|
3736 | Terminal.prototype.setWarningBellVolume = function(params) {
|
3737 | ;
|
3738 | };
|
3739 |
|
3740 | // CSI Ps SP u
|
3741 | // Set margin-bell volume (DECSMBV, VT520).
|
3742 | // Ps = 1 -> off.
|
3743 | // Ps = 2 , 3 or 4 -> low.
|
3744 | // Ps = 0 , 5 , 6 , 7 , or 8 -> high.
|
3745 | Terminal.prototype.setMarginBellVolume = function(params) {
|
3746 | ;
|
3747 | };
|
3748 |
|
3749 | // CSI Pt; Pl; Pb; Pr; Pp; Pt; Pl; Pp$ v
|
3750 | // Copy Rectangular Area (DECCRA, VT400 and up).
|
3751 | // Pt; Pl; Pb; Pr denotes the rectangle.
|
3752 | // Pp denotes the source page.
|
3753 | // Pt; Pl denotes the target location.
|
3754 | // Pp denotes the target page.
|
3755 | // NOTE: xterm doesn't enable this code by default.
|
3756 | Terminal.prototype.copyRectangle = function(params) {
|
3757 | ;
|
3758 | };
|
3759 |
|
3760 | // CSI Pt ; Pl ; Pb ; Pr ' w
|
3761 | // Enable Filter Rectangle (DECEFR), VT420 and up.
|
3762 | // Parameters are [top;left;bottom;right].
|
3763 | // Defines the coordinates of a filter rectangle and activates
|
3764 | // it. Anytime the locator is detected outside of the filter
|
3765 | // rectangle, an outside rectangle event is generated and the
|
3766 | // rectangle is disabled. Filter rectangles are always treated
|
3767 | // as "one-shot" events. Any parameters that are omitted default
|
3768 | // to the current locator position. If all parameters are omit-
|
3769 | // ted, any locator motion will be reported. DECELR always can-
|
3770 | // cels any prevous rectangle definition.
|
3771 | Terminal.prototype.enableFilterRectangle = function(params) {
|
3772 | ;
|
3773 | };
|
3774 |
|
3775 | // CSI Ps x Request Terminal Parameters (DECREQTPARM).
|
3776 | // if Ps is a "0" (default) or "1", and xterm is emulating VT100,
|
3777 | // the control sequence elicits a response of the same form whose
|
3778 | // parameters describe the terminal:
|
3779 | // Ps -> the given Ps incremented by 2.
|
3780 | // Pn = 1 <- no parity.
|
3781 | // Pn = 1 <- eight bits.
|
3782 | // Pn = 1 <- 2 8 transmit 38.4k baud.
|
3783 | // Pn = 1 <- 2 8 receive 38.4k baud.
|
3784 | // Pn = 1 <- clock multiplier.
|
3785 | // Pn = 0 <- STP flags.
|
3786 | Terminal.prototype.requestParameters = function(params) {
|
3787 | ;
|
3788 | };
|
3789 |
|
3790 | // CSI Ps x Select Attribute Change Extent (DECSACE).
|
3791 | // Ps = 0 -> from start to end position, wrapped.
|
3792 | // Ps = 1 -> from start to end position, wrapped.
|
3793 | // Ps = 2 -> rectangle (exact).
|
3794 | Terminal.prototype.selectChangeExtent = function(params) {
|
3795 | ;
|
3796 | };
|
3797 |
|
3798 | // CSI Pc; Pt; Pl; Pb; Pr$ x
|
3799 | // Fill Rectangular Area (DECFRA), VT420 and up.
|
3800 | // Pc is the character to use.
|
3801 | // Pt; Pl; Pb; Pr denotes the rectangle.
|
3802 | // NOTE: xterm doesn't enable this code by default.
|
3803 | Terminal.prototype.fillRectangle = function(params) {
|
3804 | var ch = params[0]
|
3805 | , t = params[1]
|
3806 | , l = params[2]
|
3807 | , b = params[3]
|
3808 | , r = params[4];
|
3809 |
|
3810 | var line
|
3811 | , i;
|
3812 |
|
3813 | for (; t < b + 1; t++) {
|
3814 | line = this.lines[this.ybase + t];
|
3815 | for (i = l; i < r; i++) {
|
3816 | line[i] = [line[i][0], String.fromCharCode(ch)];
|
3817 | }
|
3818 | }
|
3819 |
|
3820 | // this.maxRange();
|
3821 | this.updateRange(params[1]);
|
3822 | this.updateRange(params[3]);
|
3823 | };
|
3824 |
|
3825 | // CSI Ps ; Pu ' z
|
3826 | // Enable Locator Reporting (DECELR).
|
3827 | // Valid values for the first parameter:
|
3828 | // Ps = 0 -> Locator disabled (default).
|
3829 | // Ps = 1 -> Locator enabled.
|
3830 | // Ps = 2 -> Locator enabled for one report, then disabled.
|
3831 | // The second parameter specifies the coordinate unit for locator
|
3832 | // reports.
|
3833 | // Valid values for the second parameter:
|
3834 | // Pu = 0 <- or omitted -> default to character cells.
|
3835 | // Pu = 1 <- device physical pixels.
|
3836 | // Pu = 2 <- character cells.
|
3837 | Terminal.prototype.enableLocatorReporting = function(params) {
|
3838 | var val = params[0] > 0;
|
3839 | //this.mouseEvents = val;
|
3840 | //this.decLocator = val;
|
3841 | };
|
3842 |
|
3843 | // CSI Pt; Pl; Pb; Pr$ z
|
3844 | // Erase Rectangular Area (DECERA), VT400 and up.
|
3845 | // Pt; Pl; Pb; Pr denotes the rectangle.
|
3846 | // NOTE: xterm doesn't enable this code by default.
|
3847 | Terminal.prototype.eraseRectangle = function(params) {
|
3848 | var t = params[0]
|
3849 | , l = params[1]
|
3850 | , b = params[2]
|
3851 | , r = params[3];
|
3852 |
|
3853 | var line
|
3854 | , i
|
3855 | , ch;
|
3856 |
|
3857 | ch = [this.curAttr, ' ']; // xterm?
|
3858 |
|
3859 | for (; t < b + 1; t++) {
|
3860 | line = this.lines[this.ybase + t];
|
3861 | for (i = l; i < r; i++) {
|
3862 | line[i] = ch;
|
3863 | }
|
3864 | }
|
3865 |
|
3866 | // this.maxRange();
|
3867 | this.updateRange(params[0]);
|
3868 | this.updateRange(params[2]);
|
3869 | };
|
3870 |
|
3871 | // CSI Pm ' {
|
3872 | // Select Locator Events (DECSLE).
|
3873 | // Valid values for the first (and any additional parameters)
|
3874 | // are:
|
3875 | // Ps = 0 -> only respond to explicit host requests (DECRQLP).
|
3876 | // (This is default). It also cancels any filter
|
3877 | // rectangle.
|
3878 | // Ps = 1 -> report button down transitions.
|
3879 | // Ps = 2 -> do not report button down transitions.
|
3880 | // Ps = 3 -> report button up transitions.
|
3881 | // Ps = 4 -> do not report button up transitions.
|
3882 | Terminal.prototype.setLocatorEvents = function(params) {
|
3883 | ;
|
3884 | };
|
3885 |
|
3886 | // CSI Pt; Pl; Pb; Pr$ {
|
3887 | // Selective Erase Rectangular Area (DECSERA), VT400 and up.
|
3888 | // Pt; Pl; Pb; Pr denotes the rectangle.
|
3889 | Terminal.prototype.selectiveEraseRectangle = function(params) {
|
3890 | ;
|
3891 | };
|
3892 |
|
3893 | // CSI Ps ' |
|
3894 | // Request Locator Position (DECRQLP).
|
3895 | // Valid values for the parameter are:
|
3896 | // Ps = 0 , 1 or omitted -> transmit a single DECLRP locator
|
3897 | // report.
|
3898 |
|
3899 | // If Locator Reporting has been enabled by a DECELR, xterm will
|
3900 | // respond with a DECLRP Locator Report. This report is also
|
3901 | // generated on button up and down events if they have been
|
3902 | // enabled with a DECSLE, or when the locator is detected outside
|
3903 | // of a filter rectangle, if filter rectangles have been enabled
|
3904 | // with a DECEFR.
|
3905 |
|
3906 | // -> CSI Pe ; Pb ; Pr ; Pc ; Pp & w
|
3907 |
|
3908 | // Parameters are [event;button;row;column;page].
|
3909 | // Valid values for the event:
|
3910 | // Pe = 0 -> locator unavailable - no other parameters sent.
|
3911 | // Pe = 1 -> request - xterm received a DECRQLP.
|
3912 | // Pe = 2 -> left button down.
|
3913 | // Pe = 3 -> left button up.
|
3914 | // Pe = 4 -> middle button down.
|
3915 | // Pe = 5 -> middle button up.
|
3916 | // Pe = 6 -> right button down.
|
3917 | // Pe = 7 -> right button up.
|
3918 | // Pe = 8 -> M4 button down.
|
3919 | // Pe = 9 -> M4 button up.
|
3920 | // Pe = 1 0 -> locator outside filter rectangle.
|
3921 | // ``button'' parameter is a bitmask indicating which buttons are
|
3922 | // pressed:
|
3923 | // Pb = 0 <- no buttons down.
|
3924 | // Pb & 1 <- right button down.
|
3925 | // Pb & 2 <- middle button down.
|
3926 | // Pb & 4 <- left button down.
|
3927 | // Pb & 8 <- M4 button down.
|
3928 | // ``row'' and ``column'' parameters are the coordinates of the
|
3929 | // locator position in the xterm window, encoded as ASCII deci-
|
3930 | // mal.
|
3931 | // The ``page'' parameter is not used by xterm, and will be omit-
|
3932 | // ted.
|
3933 | Terminal.prototype.requestLocatorPosition = function(params) {
|
3934 | ;
|
3935 | };
|
3936 |
|
3937 | // CSI P m SP }
|
3938 | // Insert P s Column(s) (default = 1) (DECIC), VT420 and up.
|
3939 | // NOTE: xterm doesn't enable this code by default.
|
3940 | Terminal.prototype.insertColumns = function() {
|
3941 | var param = params[0]
|
3942 | , l = this.ybase + this.rows
|
3943 | , ch = [this.curAttr, ' '] // xterm?
|
3944 | , i;
|
3945 |
|
3946 | while (param--) {
|
3947 | for (i = this.ybase; i < l; i++) {
|
3948 | this.lines[i].splice(this.x + 1, 0, ch);
|
3949 | this.lines[i].pop();
|
3950 | }
|
3951 | }
|
3952 |
|
3953 | this.maxRange();
|
3954 | };
|
3955 |
|
3956 | // CSI P m SP ~
|
3957 | // Delete P s Column(s) (default = 1) (DECDC), VT420 and up
|
3958 | // NOTE: xterm doesn't enable this code by default.
|
3959 | Terminal.prototype.deleteColumns = function() {
|
3960 | var param = params[0]
|
3961 | , l = this.ybase + this.rows
|
3962 | , ch = [this.curAttr, ' '] // xterm?
|
3963 | , i;
|
3964 |
|
3965 | while (param--) {
|
3966 | for (i = this.ybase; i < l; i++) {
|
3967 | this.lines[i].splice(this.x, 1);
|
3968 | this.lines[i].push(ch);
|
3969 | }
|
3970 | }
|
3971 |
|
3972 | this.maxRange();
|
3973 | };
|
3974 |
|
3975 | /**
|
3976 | * Character Sets
|
3977 | */
|
3978 |
|
3979 | Terminal.charsets = {};
|
3980 |
|
3981 | // DEC Special Character and Line Drawing Set.
|
3982 | // http://vt100.net/docs/vt102-ug/table5-13.html
|
3983 | // A lot of curses apps use this if they see TERM=xterm.
|
3984 | // testing: echo -e '\e(0a\e(B'
|
3985 | // The xterm output sometimes seems to conflict with the
|
3986 | // reference above. xterm seems in line with the reference
|
3987 | // when running vttest however.
|
3988 | // The table below now uses xterm's output from vttest.
|
3989 | Terminal.charsets.SCLD = { // (0
|
3990 | '`': '\u25c6', // '◆'
|
3991 | 'a': '\u2592', // '▒'
|
3992 | 'b': '\u0009', // '\t'
|
3993 | 'c': '\u000c', // '\f'
|
3994 | 'd': '\u000d', // '\r'
|
3995 | 'e': '\u000a', // '\n'
|
3996 | 'f': '\u00b0', // '°'
|
3997 | 'g': '\u00b1', // '±'
|
3998 | 'h': '\u2424', // '\u2424' (NL)
|
3999 | 'i': '\u000b', // '\v'
|
4000 | 'j': '\u2518', // '┘'
|
4001 | 'k': '\u2510', // '┐'
|
4002 | 'l': '\u250c', // '┌'
|
4003 | 'm': '\u2514', // '└'
|
4004 | 'n': '\u253c', // '┼'
|
4005 | 'o': '\u23ba', // '⎺'
|
4006 | 'p': '\u23bb', // '⎻'
|
4007 | 'q': '\u2500', // '─'
|
4008 | 'r': '\u23bc', // '⎼'
|
4009 | 's': '\u23bd', // '⎽'
|
4010 | 't': '\u251c', // '├'
|
4011 | 'u': '\u2524', // '┤'
|
4012 | 'v': '\u2534', // '┴'
|
4013 | 'w': '\u252c', // '┬'
|
4014 | 'x': '\u2502', // '│'
|
4015 | 'y': '\u2264', // '≤'
|
4016 | 'z': '\u2265', // '≥'
|
4017 | '{': '\u03c0', // 'π'
|
4018 | '|': '\u2260', // '≠'
|
4019 | '}': '\u00a3', // '£'
|
4020 | '~': '\u00b7' // '·'
|
4021 | };
|
4022 |
|
4023 | Terminal.charsets.UK = null; // (A
|
4024 | Terminal.charsets.US = null; // (B (USASCII)
|
4025 | Terminal.charsets.Dutch = null; // (4
|
4026 | Terminal.charsets.Finnish = null; // (C or (5
|
4027 | Terminal.charsets.French = null; // (R
|
4028 | Terminal.charsets.FrenchCanadian = null; // (Q
|
4029 | Terminal.charsets.German = null; // (K
|
4030 | Terminal.charsets.Italian = null; // (Y
|
4031 | Terminal.charsets.NorwegianDanish = null; // (E or (6
|
4032 | Terminal.charsets.Spanish = null; // (Z
|
4033 | Terminal.charsets.Swedish = null; // (H or (7
|
4034 | Terminal.charsets.Swiss = null; // (=
|
4035 | Terminal.charsets.ISOLatin = null; // /A
|
4036 |
|
4037 | /**
|
4038 | * Helpers
|
4039 | */
|
4040 |
|
4041 | function on(el, type, handler, capture) {
|
4042 | el.addEventListener(type, handler, capture || false);
|
4043 | }
|
4044 |
|
4045 | function off(el, type, handler, capture) {
|
4046 | el.removeEventListener(type, handler, capture || false);
|
4047 | }
|
4048 |
|
4049 | function cancel(ev) {
|
4050 | if (ev.preventDefault) ev.preventDefault();
|
4051 | ev.returnValue = false;
|
4052 | if (ev.stopPropagation) ev.stopPropagation();
|
4053 | ev.cancelBubble = true;
|
4054 | return false;
|
4055 | }
|
4056 |
|
4057 | function inherits(child, parent) {
|
4058 | function f() {
|
4059 | this.constructor = child;
|
4060 | }
|
4061 | f.prototype = parent.prototype;
|
4062 | child.prototype = new f;
|
4063 | }
|
4064 |
|
4065 | var isMac = ~navigator.userAgent.indexOf('Mac');
|
4066 |
|
4067 | // if bold is broken, we can't
|
4068 | // use it in the terminal.
|
4069 | function isBoldBroken() {
|
4070 | var el = document.createElement('span');
|
4071 | el.innerHTML = 'hello world';
|
4072 | document.body.appendChild(el);
|
4073 | var w1 = el.scrollWidth;
|
4074 | el.style.fontWeight = 'bold';
|
4075 | var w2 = el.scrollWidth;
|
4076 | document.body.removeChild(el);
|
4077 | return w1 !== w2;
|
4078 | }
|
4079 |
|
4080 | var String = this.String;
|
4081 | var setTimeout = this.setTimeout;
|
4082 | var setInterval = this.setInterval;
|
4083 |
|
4084 | /**
|
4085 | * Expose
|
4086 | */
|
4087 |
|
4088 | Terminal.EventEmitter = EventEmitter;
|
4089 | Terminal.isMac = isMac;
|
4090 | Terminal.on = on;
|
4091 | Terminal.off = off;
|
4092 | Terminal.cancel = cancel;
|
4093 |
|
4094 | if (typeof module !== 'undefined') {
|
4095 | module.exports = Terminal;
|
4096 | } else {
|
4097 | this.Terminal = Terminal;
|
4098 | }
|