/[pearpc]/src/system/vt100.cc
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /src/system/vt100.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 7 months ago) by dpavlin
File size: 20392 byte(s)
import upstream CVS
1 /*
2 * HT Editor
3 * vt100.cc - VT100/102 emulator
4 *
5 * Copyright (C) 2003 Stefan Weyergraf
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include <cctype>
22 #include <cstdio>
23 #include <cstring>
24
25 #include "tools/debug.h"
26 #include "vt100.h"
27
28 //#define VTERM_LOG_SEQS
29
30 #ifdef VTERM_LOG_SEQS
31 #define VTERMLOG(a...) DPRINTF(a)
32 #else
33 #define VTERMLOG(a...)
34 #endif
35
36 static void readCSIParamsMax16(int Pn[], int &n, int &i, const char *buf, int buflen, bool allow_spaces)
37 {
38 n = 0;
39 char c = buf[i];
40 char f;
41 do {
42 f = c;
43 int p = 0;
44 while (isdigit(c) || (allow_spaces && (c ==' '))) {
45 if (!(allow_spaces && (c ==' '))) {
46 p *= 10;
47 p += c-'0';
48 }
49 i++;
50 if (i >= buflen) break;
51 c = buf[i];
52 }
53 if (!n && (f != ';') && !isdigit(f)) break;
54 Pn[n++] = isdigit(f) ? p : -1;
55 if (i >= buflen) break;
56 if (n == 16) break;
57 if (c != ';') break;
58 i++;
59 c = buf[i];
60 if (i >= buflen) break;
61 } while (1);
62 }
63
64 VT100Display::VT100Display(int width, int height, SystemDisplay *aDisplay, vcp initColor)
65 {
66 mDisplay = aDisplay;
67 x = 0;
68 y = 0;
69 w = width;
70 h = height;
71 mState = PLAIN;
72 mDefaultColor = initColor;
73 mColor = mDefaultColor;
74 mColorLight = false;
75 mG = 0;
76 // this is our default
77 mDECCKM = false;
78 mDECAWM = true;
79 mDECOM = false;
80 mLNM = false;
81 mIM = false;
82 mTermWriteBufLen = 0;
83 mTop = 0;
84 mBottom = h;
85 cursorx = cursory = 1;
86 gotoAbsXY(0, 0);
87
88 getCursor(mSaved_cursorx, mSaved_cursory);
89 mDisplay->fillAllVT(mColor, ' ');
90 }
91
92 void VT100Display::getCursor(int &x, int &y)
93 {
94 x = cursorx;
95 y = cursory;
96 }
97
98 void VT100Display::doLF()
99 {
100 VTERMLOG("LF\n");
101 if (cursory+1 == mBottom) {
102 scrollDown(mTop, mBottom, 1);
103 } else if (cursory < h-1) {
104 cursory++;
105 }
106 }
107
108 void VT100Display::doCR()
109 {
110 VTERMLOG("CR\n");
111 cursorx = 0;
112 }
113
114 void VT100Display::doBS()
115 {
116 VTERMLOG("BS\n");
117 if (cursorx) cursorx--;
118 }
119
120 void VT100Display::doRI()
121 {
122 VTERMLOG("RI\n");
123 if (cursory == mTop) {
124 scrollUp(mTop, mBottom, 1);
125 } else if (cursory > 0) {
126 cursory--;
127 }
128 }
129
130 void VT100Display::gotoXY(int ncx, int ncy)
131 {
132 int min_y, max_y;
133
134 if (ncx < 0) {
135 cursorx = 0;
136 } else if (ncx > w - 1) {
137 cursorx = w - 1;
138 } else {
139 cursorx = ncx;
140 }
141
142 if (mDECOM) {
143 min_y = mTop;
144 max_y = mBottom;
145 } else {
146 min_y = 0;
147 max_y = h;
148 }
149
150 if (ncy < min_y) {
151 cursory = min_y;
152 } else if (ncy >= max_y) {
153 cursory = max_y - 1;
154 } else {
155 cursory = ncy;
156 }
157 }
158
159 void VT100Display::gotoAbsXY(int ncx, int ncy)
160 {
161 gotoXY(ncx, mDECOM ? mTop+ncy : ncy);
162 }
163
164 void VT100Display::saveCursor()
165 {
166 getCursor(mSaved_cursorx, mSaved_cursory);
167 }
168
169 void VT100Display::restoreCursor()
170 {
171 gotoXY(mSaved_cursorx, mSaved_cursory);
172 }
173
174 void VT100Display::scrollDown(int mTop, int mBottom, int count)
175 {
176 int n = mBottom-mTop-1;
177 while (count--) {
178 memmove(mDisplay->buf+w*mTop, mDisplay->buf+w*(mTop+1), sizeof *mDisplay->buf * w*n);
179 mDisplay->fillVT(0, mBottom-1, w, 1, mColor, ' ');
180 }
181 }
182
183 void VT100Display::scrollUp(int mTop, int mBottom, int count)
184 {
185 int n = mBottom-mTop-1;
186 while (count--) {
187 memmove(mDisplay->buf+w*(mTop+1), mDisplay->buf+w*mTop, sizeof *mDisplay->buf * w*n);
188 mDisplay->fillVT(0, mTop, w, 1, mColor, ' ');
189 }
190 }
191
192 void VT100Display::termifyColor(int &mColor)
193 {
194 int fg = VCP_FOREGROUND(mColor);
195 int bg = VCP_BACKGROUND(mColor);
196 // light black != dark gray (but black) on VT100s
197 // if (fg == VC_LIGHT(VC_BLACK)) fg = VC_BLACK;
198 // if (bg == VC_LIGHT(VC_BLACK)) bg = VC_BLACK;
199 mColor = VCP(fg, bg);
200 }
201
202 void VT100Display::setBounds(int width, int height)
203 {
204 w = width;
205 h = height;
206 if (cursorx > w-1) cursorx = w-1;
207 if (cursory > h-1) cursory = h-1;
208 if (mSaved_cursorx > w-1) mSaved_cursorx = w-1;
209 if (mSaved_cursory > h-1) mSaved_cursory = h-1;
210 mTop = 0;
211 mBottom = h;
212 }
213
214 void VT100Display::setGraphicRendition(int r)
215 {
216 vc ctab[8] = { VC_BLACK, VC_RED, VC_GREEN, VC_YELLOW, VC_BLUE, VC_MAGENTA, VC_CYAN, VC_WHITE };
217 // VTERMLOG("setgr got %d\non entry: mColorf/g=%d/%d\n", r, VCP_FOREGROUND(mColor), VCP_BACKGROUND(mColor));
218 if ((r >= 30) && (r <= 37)) {
219 // set foreground ...
220 int i = r-30;
221 vc bg = VCP_BACKGROUND(mColor);
222 vc fg = mColorLight ? VC_LIGHT(ctab[i]) : ctab[i];
223 mColor = VCP(fg, bg);
224 termifyColor(mColor);
225 } else if ((r >= 40) && (r <= 47)) {
226 // set background ...
227 int i = r-40;
228 vc fg = VCP_FOREGROUND(mColor);
229 mColor = VCP(fg, ctab[i]);
230 // mColor = VCP(fg, VC_LIGHT(VC_WHITE));
231 termifyColor(mColor);
232 } else if (r == 0) {
233 // normal
234 mColor = mDefaultColor;
235 termifyColor(mColor);
236 // FIXME:
237 mColorLight = false;
238 /* } else if (r == 22) {
239 // normal
240 mColor = VCP(VC_WHITE, VC_BLACK);*/
241 } else if (r == 1) {
242 // bold
243 vc bg = VCP_BACKGROUND(mColor);
244 vc fg = VCP_FOREGROUND(mColor);
245 mColor = VCP(VC_LIGHT(fg), bg);
246 termifyColor(mColor);
247 mColorLight = true;
248 } else if (r == 39) {
249 // set foreground to default
250 vc bg = VCP_BACKGROUND(mColor);
251 vc fg = VCP_FOREGROUND(mDefaultColor);
252 fg = mColorLight ? VC_LIGHT(fg) : fg;
253 mColor = VCP(fg, bg);
254 termifyColor(mColor);
255 } else if (r == 49) {
256 // set background to default
257 vc fg = VCP_FOREGROUND(mColor);
258 mColor = VCP(fg, VCP_BACKGROUND(mDefaultColor));
259 termifyColor(mColor);
260 } else {
261 VTERMLOG("unsupported gr. rendition %d\n", r);
262 }
263 // VTERMLOG("on exit: mColorf/g=%d/%d\n", VCP_FOREGROUND(mColor), VCP_BACKGROUND(mColor));
264 }
265
266 void VT100Display::setMode(int p, bool newValue)
267 {
268 if (newValue) {
269 // SM - set mode
270 VTERMLOG("SM - set mode");
271 } else {
272 // RM - reset mode
273 VTERMLOG("RM - reset mode");
274 }
275 switch (p) {
276 case 4:
277 mIM = newValue;
278 break;
279 case 20:
280 mLNM = newValue;
281 break;
282 default:
283 VTERMLOG("unsupported set/reset mode %d (new value %d)\n", p, newValue);
284 }
285 }
286
287 void VT100Display::setPrivateMode(int p, bool newValue)
288 {
289 if (newValue) {
290 // DECSET - set private mode
291 VTERMLOG("DECSET - set private mode");
292 } else {
293 // DECRST - reset mode
294 VTERMLOG("DECRST - reset private mode");
295 }
296 switch (p) {
297 case 1:
298 mDECCKM = newValue;
299 break;
300 case 6:
301 mDECOM = newValue;
302 break;
303 case 7:
304 mDECAWM = newValue;
305 break;
306 case 25:
307 // setCursorMode(newValue ? CURSOR_NORMAL : CURSOR_OFF);
308 break;
309 default:
310 VTERMLOG("unsupported private set/reset mode %d (new value %d)\n", p, newValue);
311 }
312 }
313
314 void VT100Display::setAutoNewLine(bool b)
315 {
316 mLNM = b;
317 }
318
319 void VT100Display::termWrite(const void *aBuf, int buflen)
320 {
321 ASSERT(mTermWriteBufLen+buflen < (int)sizeof mTermWriteBuf);
322 memcpy(mTermWriteBuf+mTermWriteBufLen, aBuf, buflen);
323 buflen += mTermWriteBufLen;
324 const char *buf = mTermWriteBuf;
325 mTermWriteBufLen = 0;
326 int last_seq_start;
327 for (int i=0; i < buflen; i++) {
328 last_seq_start = i;
329 unsigned char c = buf[i];
330 switch (c) {
331 case 7:
332 VTERMLOG("BELL ignored\n");
333 continue;
334 case 8:
335 doBS();
336 continue;
337 case 9:
338 while (cursorx < w - 1) {
339 cursorx++;
340 if ((cursorx < 0) || (cursorx % 8==0)) break;
341 }
342 continue;
343 case 10:
344 case 11:
345 case 12:
346 doLF();
347 if (!mLNM) continue;
348 case 13:
349 doCR();
350 continue;
351 case 14:
352 // select G1
353 VTERMLOG("select G1\n");
354 mG = 1;
355 continue;
356 case 15:
357 // select G0
358 VTERMLOG("select G0\n");
359 mG = 0;
360 continue;
361 case 24: case 26:
362 VTERMLOG("24/26 ignored\n");
363 mState = PLAIN;
364 continue;
365 case 27:
366 mState = ESC;
367 continue;
368 }
369 switch (mState) {
370 case PLAIN:
371 if ((c >= 32) /* && (c <= 128)*/) {
372 // if (c <32) c = 'X';
373 // if (mG == 0) {
374 mDisplay->drawChar(cursorx, cursory, mColor, (byte)c);
375 // } else {
376 // mDisplay->drawChar(cursorx, cursory, mColor, gc2mygc((byte)c), CP_GRAPHICAL);
377 // }
378 if (cursorx < w-1) {
379 cursorx++;
380 } else {
381 if (mDECAWM) {
382 doCR();
383 doLF();
384 }
385 }
386 VTERMLOG("'%c' cxy=%d,%d colorf/b=%d/%d\n", c, cursorx, cursory, VCP_FOREGROUND(mColor), VCP_BACKGROUND(mColor));
387 } else {
388 // char buf[128];
389 // sprintf(buf, "unsupported PLAIN char %d/0x%0x\n", (byte)c, (byte)c);
390 // VTERMLOG(buf);
391 mDisplay->drawChar(cursorx, cursory, mColor, c-0x80);
392 // printChar(cursorx, cursory, mColor, ' ');
393 if (cursorx < w-1) {
394 cursorx++;
395 } else {
396 if (mDECAWM) {
397 doCR();
398 doLF();
399 }
400 }
401 }
402 break;
403 case ESC:
404 switch (c) {
405 case '[':
406 mState = CSI;
407 break;
408 case ']':
409 mState = OSC;
410 break;
411 case '7':
412 VTERMLOG("ESC-7: save cursor\n");
413 saveCursor();
414 mState = PLAIN;
415 break;
416 case '8':
417 VTERMLOG("ESC-8: restore cursor\n");
418 restoreCursor();
419 mState = PLAIN;
420 break;
421 case 'D': {
422 VTERMLOG("ESC-D: line feed\n");
423 doLF();
424 mState = PLAIN;
425 break;
426 }
427 case 'E': {
428 VTERMLOG("ESC-E: CR,LF\n");
429 doCR();
430 doLF();
431 mState = PLAIN;
432 break;
433 }
434 case 'M': {
435 VTERMLOG("ESC-M: cursor up\n");
436 doRI();
437 mState = PLAIN;
438 break;
439 }
440 case '(':
441 i++;
442 if (i >= buflen) break;
443 c = buf[i];
444 VTERMLOG("G0 set charset (%c)\n", c);
445 switch (c) {
446 case '0':
447 mColor = VCP(VC_WHITE, VC_BLUE);
448 break;
449 default:
450 mColor = VCP(VC_WHITE, VC_BLACK);
451 }
452 i++;
453 mState = PLAIN;
454 break;
455 case ')':
456 i++;
457 if (i >= buflen) break;
458 c = buf[i];
459 VTERMLOG("G1 set charset (%c)\n", c);
460 switch (c) {
461 case '0':
462 mColor = VCP(VC_WHITE, VC_BLUE);
463 break;
464 default:
465 mColor = VCP(VC_WHITE, VC_BLACK);
466 }
467 i++;
468 mState = PLAIN;
469 break;
470 case '*':
471 i++;
472 if (i >= buflen) break;
473 c = buf[i];
474 VTERMLOG("G2 set charset (%c)\n", c);
475 switch (c) {
476 case '0':
477 mColor = VCP(VC_WHITE, VC_BLUE);
478 break;
479 default:
480 mColor = VCP(VC_WHITE, VC_BLACK);
481 }
482 i++;
483 mState = PLAIN;
484 break;
485 case '+':
486 i++;
487 if (i >= buflen) break;
488 c = buf[i];
489 VTERMLOG("G3 set charset (%c)\n", c);
490 switch (c) {
491 case '0':
492 mColor = VCP(VC_WHITE, VC_BLUE);
493 break;
494 default:
495 mColor = VCP(VC_WHITE, VC_BLACK);
496 }
497 i++;
498 mState = PLAIN;
499 break;
500 case '=':
501 VTERMLOG("set decckm\n");
502 mDECCKM = true;
503 mState = PLAIN;
504 break;
505 case '>':
506 VTERMLOG("reset decckm\n");
507 mDECCKM = false;
508 mState = PLAIN;
509 break;
510 default: {
511 VTERMLOG("unsupported ESC-sequence '%c'\n", c);
512 mState = PLAIN;
513 }
514 }
515 break;
516 #define CSI_ARG(idx, defaultval) (((idx<n) && (Pn[idx] != -1)) ? Pn[idx] : defaultval)
517 case CSI_QM:
518 case CSI: {
519 int Pn[16];
520 int n;
521 // VTERMLOG("CSI-fmt: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", buf[i+0], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7], buf[i+8], buf[i+9], buf[i+10], buf[i+11], buf[i+12], buf[i+13], buf[i+14], buf[i+15]);
522 readCSIParamsMax16(Pn, n, i, buf, buflen, false);
523 if (i >= buflen) break;
524 c = buf[i];
525 switch (c) {
526 case 'A': {
527 // CUU - cursor up (stop at top)
528 VTERMLOG("CUU - cursor up\n");
529 int p = CSI_ARG(0, 1);
530 gotoXY(cursorx, cursory-p);
531 mState = PLAIN;
532 break;
533 }
534 case 'B': {
535 // CUD - cursor down (stop at bottom)
536 VTERMLOG("CUD - cursor down\n");
537 int p = CSI_ARG(0, 1);
538 gotoXY(cursorx, cursory+p);
539 mState = PLAIN;
540 break;
541 }
542 case 'C': {
543 // CUF - cursor forward/right (stop at far right)
544 VTERMLOG("CUF - cursor forward\n");
545 int p = CSI_ARG(0, 1);
546 gotoXY(cursorx+p, cursory);
547 mState = PLAIN;
548 break;
549 }
550 case 'D': {
551 // CUB - cursor backward/left (stop at far left)
552 VTERMLOG("CUB - cursor backward\n");
553 int p = CSI_ARG(0, 1);
554 gotoXY(cursorx-p, cursory);
555 mState = PLAIN;
556 break;
557 }
558 case 'E': {
559 // ? - cursor ?
560 VTERMLOG("? - cursor ? (1)\n");
561 int p = CSI_ARG(0, 1);
562 gotoXY(0, cursory+p);
563 mState = PLAIN;
564 break;
565 }
566 case 'F': {
567 // ? - cursor ?
568 VTERMLOG("? - cursor ? (2)\n");
569 int p = CSI_ARG(0, 1);
570 gotoXY(0, cursory-p);
571 mState = PLAIN;
572 break;
573 }
574 case '`':
575 case 'G': {
576 // CHA - cursor x position
577 VTERMLOG("CHA - set cursor x\n");
578 int p = CSI_ARG(0, 1);
579 gotoXY(p-1, cursory);
580 mState = PLAIN;
581 break;
582 }
583 case 'd': {
584 // VPA - cursor y position
585 VTERMLOG("VPA - set cursor y\n");
586 int p = CSI_ARG(0, 1);
587 gotoAbsXY(cursorx, p-1);
588 mState = PLAIN;
589 break;
590 }
591 case 'f':
592 case 'H': {
593 // CUP - cursor position
594 VTERMLOG("CUP - set cursor\n");
595 int py = CSI_ARG(0, 1);
596 int px = CSI_ARG(1, 1);
597 gotoAbsXY(px-1, py-1);
598 mState = PLAIN;
599 break;
600 }
601 case 'J': {
602 // ED - erase in screen (cursor does not move)
603 int p = CSI_ARG(0, 0);
604 switch (p) {
605 case 0:
606 // erase from cursor(inclusive) to end of screen
607 VTERMLOG("ED 0 - erase from cursor(inclusive) to end of screen\n");
608 mDisplay->fillVT(cursorx, cursory, w-cursorx, 1, mColor, ' ');
609 mDisplay->fillVT(0, cursory+1, w, h-cursory-1, mColor, ' ');
610 break;
611 case 1:
612 // erase from beginning of screen to cursor(inclusive)
613 VTERMLOG("ED 1 - erase from beginning of screen to cursor(inclusive)\n");
614 mDisplay->fillVT(0, 0, w, cursory, mColor, ' ');
615 mDisplay->fillVT(0, cursory, cursorx+1, 1, mColor, ' ');
616 break;
617 case 2:
618 // erase whole screen
619 VTERMLOG("ED 2 - erase whole screen\n");
620 mDisplay->fillVT(0, 0, w, h, mColor, ' ');
621 break;
622 default:
623 VTERMLOG("ED ? - unsupported !\n");
624 }
625 mState = PLAIN;
626 break;
627 }
628 case 'K': {
629 // EL - erase in line (cursor does not move)
630 int p = CSI_ARG(0, 0);
631 switch (p) {
632 case 0:
633 // erase from cursor(inclusive) to EOL
634 VTERMLOG("EL 0 - erase in line: from cursor to EOL\n");
635 mDisplay->fillVT(cursorx, cursory, w-cursorx, 1, mColor, ' ');
636 break;
637 case 1:
638 // erase from BOL to cursor(inclusive)
639 VTERMLOG("EL 1 - erase in line: from BOL to cursor\n");
640 mDisplay->fillVT(0, cursory, cursorx+1, 1, mColor, ' ');
641 break;
642 case 2:
643 // erase line containing cursor
644 VTERMLOG("EL 2 - erase line containing cursor\n");
645 mDisplay->fillVT(0, cursory, w, 1, mColor, ' ');
646 break;
647 default:
648 VTERMLOG("EL ? - unsupported !\n");
649 }
650 mState = PLAIN;
651 break;
652 }
653 case 'L': {
654 // IL - insert n lines (from cursor)
655 VTERMLOG("IL - insert n lines(s)\n");
656 int p = CSI_ARG(0, 1);
657 if (p > h-cursory) VTERMLOG("DL: sc1 !!!");
658 if (p > h-cursory) p = h-cursory;
659 if (p < 0) p = 0;
660 scrollUp(cursory, mBottom, p);
661 mState = PLAIN;
662 break;
663 }
664 case 'M': {
665 // DL - delete n lines (from cursor)
666 VTERMLOG("DL - delete n lines(s)\n");
667 int p = CSI_ARG(0, 1);
668 if (p > h-cursory) VTERMLOG("DL: sc1 !!!");
669 if (p > h-cursory) p = h-cursory;
670 if (p < 0) p = 0;
671 scrollDown(cursory, mBottom, p);
672 mState = PLAIN;
673 break;
674 }
675 case 'P': {
676 // DCH - delete n chars (from cursor)
677 VTERMLOG("DCH - delete n character(s)\n");
678 int p = CSI_ARG(0, 1);
679 if (p > w-cursorx) VTERMLOG("DCH: sc1 !!!");
680 if (p > w-cursorx) p = w-cursorx;
681 if (p < 0) p = 0;
682 BufferedChar *b = mDisplay->buf+w*cursory;
683 memmove(b+cursorx, b+cursorx+p, sizeof (BufferedChar) * (w-cursorx-p));
684 mDisplay->fillVT(w-p, cursory, p, 1, mColor, ' ');
685 mState = PLAIN;
686 break;
687 }
688 case 'X': {
689 // ECH - erase n chars (from cursor)
690 VTERMLOG("ECH - erase n character(s)\n");
691 int p = CSI_ARG(0, 1);
692 if (p > w-cursorx) VTERMLOG("ECH: sc1 !!!\n");
693 if (p > w-cursorx) p = w-cursorx;
694 if (p < 0) p = 0;
695 mDisplay->fillVT(cursorx, cursory, p, 1, mColor, ' ');
696 mState = PLAIN;
697 break;
698 }
699 case '@': {
700 // ICH - insert (blank) character(s)
701 VTERMLOG("ICH - insert (blank) character(s)\n");
702 int p = CSI_ARG(0, 1);
703 if (p > w-cursorx) VTERMLOG("ICH: sc1 !!!");
704 if (p > w-cursorx) p = w-cursorx;
705 if (p < 0) p = 0;
706 BufferedChar *b = mDisplay->buf+w*cursory;
707 memmove(b+cursorx+p, b+cursorx, sizeof (BufferedChar) * (w-cursorx-p));
708 mDisplay->fillVT(cursorx, cursory, p, 1, mColor, ' ');
709 mState = PLAIN;
710 break;
711 }
712 case 'r': {
713 // set scroll region
714 VTERMLOG("DECSTBM - set scroll region\n");
715 int r1 = CSI_ARG(0, 1);
716 int r2 = CSI_ARG(1, h);
717 if ((r1 > 0) && (r1 < r2) && (r2 <= h)) {
718 mTop = r1-1;
719 mBottom = r2;
720 gotoAbsXY(0, 0);
721 }
722 mState = PLAIN;
723 break;
724 }
725 case 's': {
726 // save cursor
727 VTERMLOG("? - save cursor\n");
728 saveCursor();
729 mState = PLAIN;
730 break;
731 }
732 case 'u': {
733 // restore cursor
734 VTERMLOG("? - restore cursor\n");
735 restoreCursor();
736 mState = PLAIN;
737 break;
738 }
739 case 'm': {
740 // SGR - select graphic rendition
741 VTERMLOG("SGR - set graphic rendition\n");
742 for (int k=0; k<n; k++) {
743 setGraphicRendition(CSI_ARG(k, 0));
744 }
745 if (n == 0) setGraphicRendition(0);
746 mState = PLAIN;
747 break;
748 }
749 case 'h':
750 case 'l': {
751 bool newValue = (c=='h');
752 int p = CSI_ARG(0, -1);
753 if (mState == CSI) {
754 setMode(p, newValue);
755 } else {
756 setPrivateMode(p, newValue);
757 }
758 mState = PLAIN;
759 break;
760 }
761 case '?': {
762 mState = CSI_QM;
763 break;
764 }
765 default:
766 VTERMLOG("unsupported CSI-sequence '%c' (", c);
767 for (int k=0; k<n; k++) {
768 VTERMLOG("%d", Pn[k]);
769 if (k+1<n) VTERMLOG(", ");
770 }
771 VTERMLOG(")\n");
772 mState = PLAIN;
773 }
774 VTERMLOG("(");
775 for (int k=0; k<n; k++) {
776 VTERMLOG("%d", Pn[k]);
777 if (k+1<n) VTERMLOG(", ");
778 }
779 VTERMLOG("), cxy=%d,%d\n", cursorx, cursory);
780 break;
781 }
782 #undef CSI_ARG
783 case OSC: {
784 int p = 0;
785 while ((i< buflen) && isdigit(c)) {
786 p *= 10;
787 p += c-'0';
788 c = buf[++i];
789 }
790 // skip ';'
791 c = buf[++i];
792 while ((i<buflen) && (c>=32)) {
793 c = buf[++i];
794 }
795 if (i >= buflen) break;
796 switch (p) {
797 case 0: {
798 VTERMLOG("OSC: set text params\n");
799 VTERMLOG("%c%c%c%c%c%c\n", buf[start], buf[start+1], buf[start+2], buf[start+3], buf[start+4], buf[start+5]);
800 mState = PLAIN;
801 break;
802 }
803 default:
804 VTERMLOG("unsupported OSC-sequence no. %d\n", p);
805 mState = PLAIN;
806 }
807 break;
808 }
809 }
810 if (i >= buflen) {
811 memmove(mTermWriteBuf, mTermWriteBuf+last_seq_start, buflen-last_seq_start);
812 mTermWriteBufLen = buflen-last_seq_start;
813 break;
814 }
815 }
816 }
817
818 static int vcToAnsi(char *buf, vc color, bool fg)
819 {
820 vc ctab[8] = { VC_BLACK, VC_RED, VC_GREEN, VC_YELLOW, VC_BLUE, VC_MAGENTA, VC_CYAN, VC_WHITE };
821 int ansi = -1;
822 for (int i=0; i<8; i++) if (ctab[i] == VC_GET_BASECOLOR(color)) {
823 ansi = i;
824 break;
825 }
826 if (ansi != -1) {
827 bool ansibold = VC_GET_LIGHT(color);
828 if (ansibold) {
829 return sprintf(buf, "%d;1", (fg?0:10)+30+ansi);
830 } else {
831 return sprintf(buf, "%d", (fg?0:10)+30+ansi);
832 }
833 }
834 return 0;
835 }
836
837 void vcpToAnsi(char *buf32, vcp color)
838 {
839 int i = 0;
840 i += sprintf(buf32+i, "\e[");
841 int fga = vcToAnsi(buf32+i, VCP_FOREGROUND(color), true);
842 i += fga;
843 if (fga) i += sprintf(buf32+i, ";");
844 int bga = vcToAnsi(buf32+i, VCP_BACKGROUND(color), false);
845 i += bga;
846 if (!bga && !fga) {
847 *buf32 = 0;
848 return;
849 }
850 if (!bga) i--;
851 i += sprintf(buf32+i, "m");
852 }
853

  ViewVC Help
Powered by ViewVC 1.1.26