]> git.proxmox.com Git - mirror_xterm.js.git/blame - src/InputHandler.ts
Convert more CSI codes
[mirror_xterm.js.git] / src / InputHandler.ts
CommitLineData
04b1ebf1 1import { IInputHandler, ITerminal } from './Interfaces';
db81c28b 2import { C0 } from './EscapeSequences';
04b1ebf1
DI
3
4export class InputHandler implements IInputHandler {
5 // TODO: We want to type _terminal when it's pulled into TS
6 constructor(private _terminal: any) { }
7
db81c28b
DI
8 /**
9 * BEL
10 * Bell (Ctrl-G).
11 */
04b1ebf1
DI
12 public bell(): void {
13 if (!this._terminal.visualBell) {
14 return;
15 }
16 this._terminal.element.style.borderColor = 'white';
17 setTimeout(() => this._terminal.element.style.borderColor = '', 10);
18 if (this._terminal.popOnBell) {
19 this._terminal.focus();
20 }
21 }
22
db81c28b
DI
23 /**
24 * LF
25 * Line Feed or New Line (NL). (LF is Ctrl-J).
26 */
04b1ebf1
DI
27 public lineFeed(): void {
28 if (this._terminal.convertEol) {
29 this._terminal.x = 0;
30 }
31 this._terminal.y++;
32 if (this._terminal.y > this._terminal.scrollBottom) {
33 this._terminal.y--;
34 this._terminal.scroll();
35 }
36 }
37
db81c28b
DI
38 /**
39 * CR
40 * Carriage Return (Ctrl-M).
41 */
04b1ebf1
DI
42 public carriageReturn(): void {
43 this._terminal.x = 0;
44 }
45
db81c28b
DI
46 /**
47 * BS
48 * Backspace (Ctrl-H).
49 */
04b1ebf1
DI
50 public backspace(): void {
51 if (this._terminal.x > 0) {
52 this._terminal.x--;
53 }
54 }
55
db81c28b
DI
56 /**
57 * TAB
58 * Horizontal Tab (HT) (Ctrl-I).
59 */
04b1ebf1
DI
60 public tab(): void {
61 this._terminal.x = this._terminal.nextStop();
62 }
63
db81c28b
DI
64 /**
65 * SO
66 * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the
67 * G1 character set.
68 */
04b1ebf1
DI
69 public shiftOut(): void {
70 this._terminal.setgLevel(1);
71 }
72
db81c28b
DI
73 /**
74 * SI
75 * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0
76 * character set (the default).
77 */
04b1ebf1
DI
78 public shiftIn(): void {
79 this._terminal.setgLevel(0);
80 }
9942477b 81
411b80cd
DI
82 /**
83 * CSI Ps @
84 * Insert Ps (Blank) Character(s) (default = 1) (ICH).
85 */
86 public insertChars(params: number[]): void {
87 let param, row, j, ch;
88
89 param = params[0];
90 if (param < 1) param = 1;
91
92 row = this._terminal.y + this._terminal.ybase;
93 j = this._terminal.x;
94 ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm
95
96 while (param-- && j < this._terminal.cols) {
97 this._terminal.lines.get(row).splice(j++, 0, ch);
98 this._terminal.lines.get(row).pop();
99 }
100 }
101
db81c28b
DI
102 /**
103 * CSI Ps A
104 * Cursor Up Ps Times (default = 1) (CUU).
105 */
9942477b
DI
106 public cursorUp(params: number[]): void {
107 let param = params[0];
108 if (param < 1) {
109 param = 1;
110 }
111 this._terminal.y -= param;
112 if (this._terminal.y < 0) {
113 this._terminal.y = 0;
114 }
115 }
116
db81c28b
DI
117 /**
118 * CSI Ps B
119 * Cursor Down Ps Times (default = 1) (CUD).
120 */
9942477b
DI
121 public cursorDown(params: number[]) {
122 let param = params[0];
123 if (param < 1) {
124 param = 1;
125 }
126 this._terminal.y += param;
127 if (this._terminal.y >= this._terminal.rows) {
128 this._terminal.y = this._terminal.rows - 1;
129 }
130 }
131
db81c28b
DI
132 /**
133 * CSI Ps C
134 * Cursor Forward Ps Times (default = 1) (CUF).
135 */
9942477b
DI
136 public cursorForward(params: number[]) {
137 let param = params[0];
138 if (param < 1) {
139 param = 1;
140 }
141 this._terminal.x += param;
142 if (this._terminal.x >= this._terminal.cols) {
143 this._terminal.x = this._terminal.cols - 1;
144 }
145 }
146
db81c28b
DI
147 /**
148 * CSI Ps D
149 * Cursor Backward Ps Times (default = 1) (CUB).
150 */
9942477b
DI
151 public cursorBackward(params: number[]) {
152 let param = params[0];
153 if (param < 1) {
154 param = 1;
155 }
156 this._terminal.x -= param;
157 if (this._terminal.x < 0) {
158 this._terminal.x = 0;
159 }
160 }
db81c28b 161
411b80cd
DI
162 /**
163 * CSI Ps E
164 * Cursor Next Line Ps Times (default = 1) (CNL).
165 * same as CSI Ps B ?
166 */
167 public cursorNextLine(params: number[]): void {
168 let param = params[0];
169 if (param < 1) {
170 param = 1;
171 }
172 this._terminal.y += param;
173 if (this._terminal.y >= this._terminal.rows) {
174 this._terminal.y = this._terminal.rows - 1;
175 }
176 this._terminal.x = 0;
177 };
178
179
180 /**
181 * CSI Ps F
182 * Cursor Preceding Line Ps Times (default = 1) (CNL).
183 * reuse CSI Ps A ?
184 */
185 public cursorPrecedingLine(params: number[]): void {
186 let param = params[0];
187 if (param < 1) {
188 param = 1;
189 }
190 this._terminal.y -= param;
191 if (this._terminal.y < 0) {
192 this._terminal.y = 0;
193 }
194 this._terminal.x = 0;
195 };
196
197
198 /**
199 * CSI Ps G
200 * Cursor Character Absolute [column] (default = [row,1]) (CHA).
201 */
202 public cursorCharAbsolute(params: number[]): void {
203 let param = params[0];
204 if (param < 1) {
205 param = 1;
206 }
207 this._terminal.x = param - 1;
208 }
209
db81c28b
DI
210 /**
211 * CSI Ps ; Ps H
212 * Cursor Position [row;column] (default = [1,1]) (CUP).
213 */
411b80cd 214 public cursorPosition(params: number[]): void {
db81c28b
DI
215 let row, col;
216
217 row = params[0] - 1;
218
219 if (params.length >= 2) {
220 col = params[1] - 1;
221 } else {
222 col = 0;
223 }
224
225 if (row < 0) {
226 row = 0;
227 } else if (row >= this._terminal.rows) {
228 row = this._terminal.rows - 1;
229 }
230
231 if (col < 0) {
232 col = 0;
233 } else if (col >= this._terminal.cols) {
234 col = this._terminal.cols - 1;
235 }
236
237 this._terminal.x = col;
238 this._terminal.y = row;
239 }
240
241 /**
242 * CSI Ps J Erase in Display (ED).
243 * Ps = 0 -> Erase Below (default).
244 * Ps = 1 -> Erase Above.
245 * Ps = 2 -> Erase All.
246 * Ps = 3 -> Erase Saved Lines (xterm).
247 * CSI ? Ps J
248 * Erase in Display (DECSED).
249 * Ps = 0 -> Selective Erase Below (default).
250 * Ps = 1 -> Selective Erase Above.
251 * Ps = 2 -> Selective Erase All.
252 */
411b80cd 253 public eraseInDisplay(params: number[]): void {
db81c28b
DI
254 let j;
255 switch (params[0]) {
256 case 0:
257 this._terminal.eraseRight(this._terminal.x, this._terminal.y);
258 j = this._terminal.y + 1;
259 for (; j < this._terminal.rows; j++) {
260 this._terminal.eraseLine(j);
261 }
262 break;
263 case 1:
264 this._terminal.eraseLeft(this._terminal.x, this._terminal.y);
265 j = this._terminal.y;
266 while (j--) {
267 this._terminal.eraseLine(j);
268 }
269 break;
270 case 2:
271 j = this._terminal.rows;
272 while (j--) this._terminal.eraseLine(j);
273 break;
274 case 3:
275 ; // no saved lines
276 break;
277 }
278 }
279
280 /**
281 * CSI Ps K Erase in Line (EL).
282 * Ps = 0 -> Erase to Right (default).
283 * Ps = 1 -> Erase to Left.
284 * Ps = 2 -> Erase All.
285 * CSI ? Ps K
286 * Erase in Line (DECSEL).
287 * Ps = 0 -> Selective Erase to Right (default).
288 * Ps = 1 -> Selective Erase to Left.
289 * Ps = 2 -> Selective Erase All.
290 */
411b80cd 291 public eraseInLine(params: number[]): void {
db81c28b
DI
292 switch (params[0]) {
293 case 0:
294 this._terminal.eraseRight(this._terminal.x, this._terminal.y);
295 break;
296 case 1:
297 this._terminal.eraseLeft(this._terminal.x, this._terminal.y);
298 break;
299 case 2:
300 this._terminal.eraseLine(this._terminal.y);
301 break;
302 }
303 }
304
f9a286a8
DI
305 /**
306 * CSI Ps L
307 * Insert Ps Line(s) (default = 1) (IL).
308 */
309 public insertLines(params: number[]): void {
310 let param, row, j;
311
312 param = params[0];
313 if (param < 1) {
314 param = 1;
315 }
316 row = this._terminal.y + this._terminal.ybase;
317
318 j = this._terminal.rows - 1 - this._terminal.scrollBottom;
319 j = this._terminal.rows - 1 + this._terminal.ybase - j + 1;
320
321 while (param--) {
322 if (this._terminal.lines.length === this._terminal.lines.maxLength) {
323 // Trim the start of lines to make room for the new line
324 this._terminal.lines.trimStart(1);
325 this._terminal.ybase--;
326 this._terminal.ydisp--;
327 row--;
328 j--;
329 }
330 // test: echo -e '\e[44m\e[1L\e[0m'
331 // blankLine(true) - xterm/linux behavior
332 this._terminal.lines.splice(row, 0, this._terminal.blankLine(true));
333 this._terminal.lines.splice(j, 1);
334 }
335
336 // this.maxRange();
337 this._terminal.updateRange(this._terminal.y);
338 this._terminal.updateRange(this._terminal.scrollBottom);
339 }
340
341 /**
342 * CSI Ps M
343 * Delete Ps Line(s) (default = 1) (DL).
344 */
345 public deleteLines(params: number[]): void {
346 let param, row, j;
347
348 param = params[0];
349 if (param < 1) {
350 param = 1;
351 }
352 row = this._terminal.y + this._terminal.ybase;
353
354 j = this._terminal.rows - 1 - this._terminal.scrollBottom;
355 j = this._terminal.rows - 1 + this._terminal.ybase - j;
356
357 while (param--) {
358 if (this._terminal.lines.length === this._terminal.lines.maxLength) {
359 // Trim the start of lines to make room for the new line
360 this._terminal.lines.trimStart(1);
361 this._terminal.ybase -= 1;
362 this._terminal.ydisp -= 1;
363 }
364 // test: echo -e '\e[44m\e[1M\e[0m'
365 // blankLine(true) - xterm/linux behavior
366 this._terminal.lines.splice(j + 1, 0, this._terminal.blankLine(true));
367 this._terminal.lines.splice(row, 1);
368 }
369
370 // this.maxRange();
371 this._terminal.updateRange(this._terminal.y);
372 this._terminal.updateRange(this._terminal.scrollBottom);
373 }
374
375 /**
376 * CSI Ps P
377 * Delete Ps Character(s) (default = 1) (DCH).
378 */
379 public deleteChars(params: number[]): void {
380 let param, row, ch;
381
382 param = params[0];
383 if (param < 1) {
384 param = 1;
385 }
386
387 row = this._terminal.y + this._terminal.ybase;
388 ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm
389
390 while (param--) {
391 this._terminal.lines.get(row).splice(this._terminal.x, 1);
392 this._terminal.lines.get(row).push(ch);
393 }
394 }
395
396 /**
397 * CSI Ps X
398 * Erase Ps Character(s) (default = 1) (ECH).
399 */
400 public eraseChars(params: number[]): void {
401 let param, row, j, ch;
402
403 param = params[0];
404 if (param < 1) {
405 param = 1;
406 }
407
408 row = this._terminal.y + this._terminal.ybase;
409 j = this._terminal.x;
410 ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm
411
412 while (param-- && j < this._terminal.cols) {
413 this._terminal.lines.get(row)[j++] = ch;
414 }
415 }
416
417 /**
418 * CSI Pm ` Character Position Absolute
419 * [column] (default = [row,1]) (HPA).
420 */
421 public charPosAbsolute(params: number[]): void {
422 let param = params[0];
423 if (param < 1) {
424 param = 1;
425 }
426 this._terminal.x = param - 1;
427 if (this._terminal.x >= this._terminal.cols) {
428 this._terminal.x = this._terminal.cols - 1;
429 }
430 }
431
432 /**
433 * CSI Pm a Character Position Relative
434 * [columns] (default = [row,col+1]) (HPR)
435 * reuse CSI Ps C ?
436 */
437 public HPositionRelative(params: number[]): void {
438 let param = params[0];
439 if (param < 1) {
440 param = 1;
441 }
442 this._terminal.x += param;
443 if (this._terminal.x >= this._terminal.cols) {
444 this._terminal.x = this._terminal.cols - 1;
445 }
446 }
447
448 /**
449 * CSI Ps c Send Device Attributes (Primary DA).
450 * Ps = 0 or omitted -> request attributes from terminal. The
451 * response depends on the decTerminalID resource setting.
452 * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')
453 * -> CSI ? 1 ; 0 c (``VT101 with No Options'')
454 * -> CSI ? 6 c (``VT102'')
455 * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')
456 * The VT100-style response parameters do not mean anything by
457 * themselves. VT220 parameters do, telling the host what fea-
458 * tures the terminal supports:
459 * Ps = 1 -> 132-columns.
460 * Ps = 2 -> Printer.
461 * Ps = 6 -> Selective erase.
462 * Ps = 8 -> User-defined keys.
463 * Ps = 9 -> National replacement character sets.
464 * Ps = 1 5 -> Technical characters.
465 * Ps = 2 2 -> ANSI color, e.g., VT525.
466 * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).
467 * CSI > Ps c
468 * Send Device Attributes (Secondary DA).
469 * Ps = 0 or omitted -> request the terminal's identification
470 * code. The response depends on the decTerminalID resource set-
471 * ting. It should apply only to VT220 and up, but xterm extends
472 * this to VT100.
473 * -> CSI > Pp ; Pv ; Pc c
474 * where Pp denotes the terminal type
475 * Pp = 0 -> ``VT100''.
476 * Pp = 1 -> ``VT220''.
477 * and Pv is the firmware version (for xterm, this was originally
478 * the XFree86 patch number, starting with 95). In a DEC termi-
479 * nal, Pc indicates the ROM cartridge registration number and is
480 * always zero.
481 * More information:
482 * xterm/charproc.c - line 2012, for more information.
483 * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)
484 */
485 public sendDeviceAttributes(params: number[]): void {
486 if (params[0] > 0) {
487 return;
488 }
489
490 if (!this._terminal.prefix) {
491 if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {
492 this._terminal.send(C0.ESC + '[?1;2c');
493 } else if (this._terminal.is('linux')) {
494 this._terminal.send(C0.ESC + '[?6c');
495 }
496 } else if (this._terminal.prefix === '>') {
497 // xterm and urxvt
498 // seem to spit this
499 // out around ~370 times (?).
500 if (this._terminal.is('xterm')) {
501 this._terminal.send(C0.ESC + '[>0;276;0c');
502 } else if (this._terminal.is('rxvt-unicode')) {
503 this._terminal.send(C0.ESC + '[>85;95;0c');
504 } else if (this._terminal.is('linux')) {
505 // not supported by linux console.
506 // linux console echoes parameters.
507 this._terminal.send(params[0] + 'c');
508 } else if (this._terminal.is('screen')) {
509 this._terminal.send(C0.ESC + '[>83;40003;0c');
510 }
511 }
512 }
513
db81c28b
DI
514 /**
515 * CSI Pm m Character Attributes (SGR).
516 * Ps = 0 -> Normal (default).
517 * Ps = 1 -> Bold.
518 * Ps = 4 -> Underlined.
519 * Ps = 5 -> Blink (appears as Bold).
520 * Ps = 7 -> Inverse.
521 * Ps = 8 -> Invisible, i.e., hidden (VT300).
522 * Ps = 2 2 -> Normal (neither bold nor faint).
523 * Ps = 2 4 -> Not underlined.
524 * Ps = 2 5 -> Steady (not blinking).
525 * Ps = 2 7 -> Positive (not inverse).
526 * Ps = 2 8 -> Visible, i.e., not hidden (VT300).
527 * Ps = 3 0 -> Set foreground color to Black.
528 * Ps = 3 1 -> Set foreground color to Red.
529 * Ps = 3 2 -> Set foreground color to Green.
530 * Ps = 3 3 -> Set foreground color to Yellow.
531 * Ps = 3 4 -> Set foreground color to Blue.
532 * Ps = 3 5 -> Set foreground color to Magenta.
533 * Ps = 3 6 -> Set foreground color to Cyan.
534 * Ps = 3 7 -> Set foreground color to White.
535 * Ps = 3 9 -> Set foreground color to default (original).
536 * Ps = 4 0 -> Set background color to Black.
537 * Ps = 4 1 -> Set background color to Red.
538 * Ps = 4 2 -> Set background color to Green.
539 * Ps = 4 3 -> Set background color to Yellow.
540 * Ps = 4 4 -> Set background color to Blue.
541 * Ps = 4 5 -> Set background color to Magenta.
542 * Ps = 4 6 -> Set background color to Cyan.
543 * Ps = 4 7 -> Set background color to White.
544 * Ps = 4 9 -> Set background color to default (original).
545 *
546 * If 16-color support is compiled, the following apply. Assume
547 * that xterm's resources are set so that the ISO color codes are
548 * the first 8 of a set of 16. Then the aixterm colors are the
549 * bright versions of the ISO colors:
550 * Ps = 9 0 -> Set foreground color to Black.
551 * Ps = 9 1 -> Set foreground color to Red.
552 * Ps = 9 2 -> Set foreground color to Green.
553 * Ps = 9 3 -> Set foreground color to Yellow.
554 * Ps = 9 4 -> Set foreground color to Blue.
555 * Ps = 9 5 -> Set foreground color to Magenta.
556 * Ps = 9 6 -> Set foreground color to Cyan.
557 * Ps = 9 7 -> Set foreground color to White.
558 * Ps = 1 0 0 -> Set background color to Black.
559 * Ps = 1 0 1 -> Set background color to Red.
560 * Ps = 1 0 2 -> Set background color to Green.
561 * Ps = 1 0 3 -> Set background color to Yellow.
562 * Ps = 1 0 4 -> Set background color to Blue.
563 * Ps = 1 0 5 -> Set background color to Magenta.
564 * Ps = 1 0 6 -> Set background color to Cyan.
565 * Ps = 1 0 7 -> Set background color to White.
566 *
567 * If xterm is compiled with the 16-color support disabled, it
568 * supports the following, from rxvt:
569 * Ps = 1 0 0 -> Set foreground and background color to
570 * default.
571 *
572 * If 88- or 256-color support is compiled, the following apply.
573 * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second
574 * Ps.
575 * Ps = 4 8 ; 5 ; Ps -> Set background color to the second
576 * Ps.
577 */
411b80cd 578 public charAttributes(params: number[]): void {
db81c28b
DI
579 // Optimize a single SGR0.
580 if (params.length === 1 && params[0] === 0) {
581 this._terminal.curAttr = this._terminal.defAttr;
582 return;
583 }
584
585 let l = params.length
586 , i = 0
587 , flags = this._terminal.curAttr >> 18
588 , fg = (this._terminal.curAttr >> 9) & 0x1ff
589 , bg = this._terminal.curAttr & 0x1ff
590 , p;
591
592 for (; i < l; i++) {
593 p = params[i];
594 if (p >= 30 && p <= 37) {
595 // fg color 8
596 fg = p - 30;
597 } else if (p >= 40 && p <= 47) {
598 // bg color 8
599 bg = p - 40;
600 } else if (p >= 90 && p <= 97) {
601 // fg color 16
602 p += 8;
603 fg = p - 90;
604 } else if (p >= 100 && p <= 107) {
605 // bg color 16
606 p += 8;
607 bg = p - 100;
608 } else if (p === 0) {
609 // default
610 flags = this._terminal.defAttr >> 18;
611 fg = (this._terminal.defAttr >> 9) & 0x1ff;
612 bg = this._terminal.defAttr & 0x1ff;
613 // flags = 0;
614 // fg = 0x1ff;
615 // bg = 0x1ff;
616 } else if (p === 1) {
617 // bold text
618 flags |= 1;
619 } else if (p === 4) {
620 // underlined text
621 flags |= 2;
622 } else if (p === 5) {
623 // blink
624 flags |= 4;
625 } else if (p === 7) {
626 // inverse and positive
627 // test with: echo -e '\e[31m\e[42mhello\e[7mworld\e[27mhi\e[m'
628 flags |= 8;
629 } else if (p === 8) {
630 // invisible
631 flags |= 16;
632 } else if (p === 22) {
633 // not bold
634 flags &= ~1;
635 } else if (p === 24) {
636 // not underlined
637 flags &= ~2;
638 } else if (p === 25) {
639 // not blink
640 flags &= ~4;
641 } else if (p === 27) {
642 // not inverse
643 flags &= ~8;
644 } else if (p === 28) {
645 // not invisible
646 flags &= ~16;
647 } else if (p === 39) {
648 // reset fg
649 fg = (this._terminal.defAttr >> 9) & 0x1ff;
650 } else if (p === 49) {
651 // reset bg
652 bg = this._terminal.defAttr & 0x1ff;
653 } else if (p === 38) {
654 // fg color 256
655 if (params[i + 1] === 2) {
656 i += 2;
657 fg = this._terminal.matchColor(
658 params[i] & 0xff,
659 params[i + 1] & 0xff,
660 params[i + 2] & 0xff);
661 if (fg === -1) fg = 0x1ff;
662 i += 2;
663 } else if (params[i + 1] === 5) {
664 i += 2;
665 p = params[i] & 0xff;
666 fg = p;
667 }
668 } else if (p === 48) {
669 // bg color 256
670 if (params[i + 1] === 2) {
671 i += 2;
672 bg = this._terminal.matchColor(
673 params[i] & 0xff,
674 params[i + 1] & 0xff,
675 params[i + 2] & 0xff);
676 if (bg === -1) bg = 0x1ff;
677 i += 2;
678 } else if (params[i + 1] === 5) {
679 i += 2;
680 p = params[i] & 0xff;
681 bg = p;
682 }
683 } else if (p === 100) {
684 // reset fg/bg
685 fg = (this._terminal.defAttr >> 9) & 0x1ff;
686 bg = this._terminal.defAttr & 0x1ff;
687 } else {
688 this._terminal.error('Unknown SGR attribute: %d.', p);
689 }
690 }
691
692 this._terminal.curAttr = (flags << 18) | (fg << 9) | bg;
693 }
694
695 /**
696 * CSI Ps n Device Status Report (DSR).
697 * Ps = 5 -> Status Report. Result (``OK'') is
698 * CSI 0 n
699 * Ps = 6 -> Report Cursor Position (CPR) [row;column].
700 * Result is
701 * CSI r ; c R
702 * CSI ? Ps n
703 * Device Status Report (DSR, DEC-specific).
704 * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI
705 * ? r ; c R (assumes page is zero).
706 * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).
707 * or CSI ? 1 1 n (not ready).
708 * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)
709 * or CSI ? 2 1 n (locked).
710 * Ps = 2 6 -> Report Keyboard status as
711 * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).
712 * The last two parameters apply to VT400 & up, and denote key-
713 * board ready and LK01 respectively.
714 * Ps = 5 3 -> Report Locator status as
715 * CSI ? 5 3 n Locator available, if compiled-in, or
716 * CSI ? 5 0 n No Locator, if not.
717 */
411b80cd 718 public deviceStatus(params: number[]): void {
db81c28b
DI
719 if (!this._terminal.prefix) {
720 switch (params[0]) {
721 case 5:
722 // status report
723 this._terminal.send(C0.ESC + '[0n');
724 break;
725 case 6:
726 // cursor position
727 this._terminal.send(C0.ESC + '['
728 + (this._terminal.y + 1)
729 + ';'
730 + (this._terminal.x + 1)
731 + 'R');
732 break;
733 }
734 } else if (this._terminal.prefix === '?') {
735 // modern xterm doesnt seem to
736 // respond to any of these except ?6, 6, and 5
737 switch (params[0]) {
738 case 6:
739 // cursor position
740 this._terminal.send(C0.ESC + '[?'
741 + (this._terminal.y + 1)
742 + ';'
743 + (this._terminal.x + 1)
744 + 'R');
745 break;
746 case 15:
747 // no printer
748 // this.send(C0.ESC + '[?11n');
749 break;
750 case 25:
751 // dont support user defined keys
752 // this.send(C0.ESC + '[?21n');
753 break;
754 case 26:
755 // north american keyboard
756 // this.send(C0.ESC + '[?27;1;0;0n');
757 break;
758 case 53:
759 // no dec locator/mouse
760 // this.send(C0.ESC + '[?50n');
761 break;
762 }
763 }
764 }
765
04b1ebf1 766}