/[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

Annotation of /src/system/vt100.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide 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 dpavlin 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