21#include "Vt102Emulation.h"
34void scrolllock_set_off();
35void scrolllock_set_on();
52#include "KeyboardTranslator.h"
55using namespace Konsole;
60 , _titleUpdateTimer(new
QTimer(this))
61 , _reportFocusEvents(false)
70Vt102Emulation::~Vt102Emulation()
85 _primaryScreen->reset();
87 _alternateScreen->reset();
153#define TY_CONSTRUCT(T, A, N) (((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff))
155#define TY_CHR() TY_CONSTRUCT(0, 0, 0)
156#define TY_CTL(A) TY_CONSTRUCT(1, A, 0)
157#define TY_ESC(A) TY_CONSTRUCT(2, A, 0)
158#define TY_ESC_CS(A, B) TY_CONSTRUCT(3, A, B)
159#define TY_ESC_DE(A) TY_CONSTRUCT(4, A, 0)
160#define TY_CSI_PS(A, N) TY_CONSTRUCT(5, A, N)
161#define TY_CSI_PN(A) TY_CONSTRUCT(6, A, 0)
162#define TY_CSI_PR(A, N) TY_CONSTRUCT(7, A, N)
163#define TY_CSI_PS_SP(A, N) TY_CONSTRUCT(11, A, N)
165#define TY_VT52(A) TY_CONSTRUCT(8, A, 0)
166#define TY_CSI_PG(A) TY_CONSTRUCT(9, A, 0)
167#define TY_CSI_PE(A) TY_CONSTRUCT(10, A, 0)
169#define MAX_ARGUMENT 4096
180void Vt102Emulation::resetTokenizer()
189void Vt102Emulation::addDigit(
int digit)
191 if (argv[argc] < MAX_ARGUMENT)
192 argv[argc] = 10 * argv[argc] + digit;
195void Vt102Emulation::addArgument()
197 argc = qMin(argc + 1, MAXARGS - 1);
201void Vt102Emulation::addToCurrentToken(
char16_t cc)
203 tokenBuffer[tokenBufferPos] = cc;
204 tokenBufferPos = qMin(tokenBufferPos + 1, MAX_TOKEN_LENGTH - 1);
218void Vt102Emulation::initTokenizer()
222 for (i = 0; i < 256; ++i)
224 for (i = 0; i < 32; ++i)
226 for (i = 32; i < 256; ++i)
228 for (s = (quint8 *)
"@ABCDGHILMPSTXZbcdfry"; *s; ++s)
229 charClass[*s] |= CPN;
231 for (s = (quint8 *)
"t"; *s; ++s)
232 charClass[*s] |= CPS;
233 for (s = (quint8 *)
"0123456789"; *s; ++s)
234 charClass[*s] |= DIG;
235 for (s = (quint8 *)
"()+*%"; *s; ++s)
236 charClass[*s] |= SCS;
237 for (s = (quint8 *)
"()+*#[]%"; *s; ++s)
238 charClass[*s] |= GRP;
262#define lec(P, L, C) (p == (P) && s[(L)] == (C))
263#define lun() (p == 1 && cc >= 32)
264#define les(P, L, C) (p == (P) && s[L] < 256 && (charClass[s[(L)]] & (C)) == (C))
265#define eec(C) (p >= 3 && cc == (C))
266#define ees(C) (p >= 3 && cc < 256 && (charClass[cc] & (C)) == (C))
267#define eps(C) (p >= 3 && s[2] != '?' && s[2] != '!' && s[2] != '>' && cc < 256 && (charClass[cc] & (C)) == (C))
268#define epp() (p >= 3 && s[2] == '?')
269#define epe() (p >= 3 && s[2] == '!')
270#define egt() (p >= 3 && s[2] == '>')
271#define esp() (p == 4 && s[3] == ' ')
272#define Xpe (tokenBufferPos >= 2 && tokenBuffer[1] == ']')
273#define Xte (Xpe && (cc == 7 || (prevCC == 27 && cc == 92)))
274#define ces(C) (cc < 256 && (charClass[cc] & (C)) == (C) && !Xte)
276#define CNTL(c) ((c) - '@')
283 char16_t cc = character.
unicode();
300 if (cc == CNTL(
'X') || cc == CNTL(
'Z') || cc == ESC)
303 processToken(TY_CTL(cc +
'@'), 0, 0);
308 addToCurrentToken(cc);
310 char16_t *s = tokenBuffer;
311 int p = tokenBufferPos;
313 if (getMode(MODE_Ansi)) {
314 if (lec(1, 0, ESC)) {
317 if (lec(1, 0, ESC + 128)) {
322 if (les(2, 1, GRP)) {
326 processWindowAttributeChange();
334 if (lec(3, 2,
'?')) {
337 if (lec(3, 2,
'>')) {
340 if (lec(3, 2,
'!')) {
344 processToken(TY_CHR(), applyCharset(cc), 0);
348 if (lec(2, 0, ESC)) {
349 processToken(TY_ESC(s[1]), 0, 0);
353 if (les(3, 1, SCS)) {
354 processToken(TY_ESC_CS(s[1], s[2]), 0, 0);
358 if (lec(3, 1,
'#')) {
359 processToken(TY_ESC_DE(s[2]), 0, 0);
364 processToken(TY_CSI_PN(cc), argv[0], argv[1]);
371 if (lec(5, 4,
'q') && s[3] ==
' ') {
372 processToken(TY_CSI_PS_SP(cc, argv[0]), argv[0], 0);
379 processToken(TY_CSI_PS(cc, argv[0]), argv[1], argv[2]);
385 processToken(TY_CSI_PE(cc), 0, 0);
393 if (eec(
';') || eec(
':')) {
397 for (
int i = 0; i <= argc; i++) {
399 processToken(TY_CSI_PR(cc, argv[i]), 0, 0);
401 processToken(TY_CSI_PG(cc), 0, 0);
402 else if (cc ==
'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i + 1] == 2) {
405 processToken(TY_CSI_PS(cc, argv[i - 2]), COLOR_SPACE_RGB, (argv[i] << 16) | (argv[i + 1] << 8) | argv[i + 2]);
407 }
else if (cc ==
'm' && argc - i >= 2 && (argv[i] == 38 || argv[i] == 48) && argv[i + 1] == 5) {
410 processToken(TY_CSI_PS(cc, argv[i - 2]), COLOR_SPACE_256, argv[i]);
412 processToken(TY_CSI_PS(cc, argv[i]), 0, 0);
419 if (les(1, 0, CHR)) {
420 processToken(TY_CHR(), s[0], 0);
431 processToken(TY_VT52(s[1]), 0, 0);
435 processToken(TY_VT52(s[1]), s[2], s[3]);
440void Vt102Emulation::processWindowAttributeChange()
444 int attributeToChange = 0;
446 for (i = 2; i < tokenBufferPos && tokenBuffer[i] >=
'0' && tokenBuffer[i] <=
'9'; i++) {
447 attributeToChange = 10 * attributeToChange + (tokenBuffer[i] -
'0');
450 if (tokenBuffer[i] !=
';') {
451 reportDecodingError();
460 _pendingTitleUpdates[attributeToChange] = newValue;
461 _titleUpdateTimer->
start(20);
464void Vt102Emulation::updateTitle()
467 while (iter.hasNext()) {
468 int arg = iter.next();
471 _pendingTitleUpdates.
clear();
492void Vt102Emulation::processToken(
int token,
char16_t p,
int q)
496 _currentScreen->displayCharacter(p);
520 _currentScreen->backspace();
523 _currentScreen->tab();
526 _currentScreen->newLine();
529 _currentScreen->newLine();
532 _currentScreen->newLine();
535 _currentScreen->toStartOfLine();
562 _currentScreen->displayCharacter(
QChar(0x2592));
567 _currentScreen->displayCharacter(
QChar(0x2592));
581 _currentScreen->index();
584 _currentScreen->nextLine();
587 _currentScreen->changeTabStop(true);
590 _currentScreen->reverseIndex();
593 reportTerminalType();
613 setMode(MODE_AppKeyPad);
616 resetMode(MODE_AppKeyPad);
622 case TY_ESC_CS(
'(',
'0'):
625 case TY_ESC_CS(
'(',
'A'):
628 case TY_ESC_CS(
'(',
'B'):
632 case TY_ESC_CS(
')',
'0'):
635 case TY_ESC_CS(
')',
'A'):
638 case TY_ESC_CS(
')',
'B'):
642 case TY_ESC_CS(
'*',
'0'):
645 case TY_ESC_CS(
'*',
'A'):
648 case TY_ESC_CS(
'*',
'B'):
652 case TY_ESC_CS(
'+',
'0'):
655 case TY_ESC_CS(
'+',
'A'):
658 case TY_ESC_CS(
'+',
'B'):
662 case TY_ESC_CS(
'%',
'G'):
665 case TY_ESC_CS(
'%',
'@'):
670 _currentScreen->setLineProperty(LINE_DOUBLEWIDTH, true);
674 _currentScreen->setLineProperty(LINE_DOUBLEWIDTH, true);
678 _currentScreen->setLineProperty(LINE_DOUBLEWIDTH, false);
682 _currentScreen->setLineProperty(LINE_DOUBLEWIDTH, true);
686 _currentScreen->helpAlign();
690 case TY_CSI_PS(
't', 8):
696 case TY_CSI_PS(
't', 28):
700 case TY_CSI_PS(
'K', 0):
701 _currentScreen->clearToEndOfLine();
703 case TY_CSI_PS(
'K', 1):
704 _currentScreen->clearToBeginOfLine();
706 case TY_CSI_PS(
'K', 2):
707 _currentScreen->clearEntireLine();
709 case TY_CSI_PS(
'J', 0):
710 _currentScreen->clearToEndOfScreen();
712 case TY_CSI_PS(
'J', 1):
713 _currentScreen->clearToBeginOfScreen();
715 case TY_CSI_PS(
'J', 2):
718 case TY_CSI_PS(
'J', 3):
721 case TY_CSI_PS(
'g', 0):
722 _currentScreen->changeTabStop(false);
724 case TY_CSI_PS(
'g', 3):
725 _currentScreen->clearTabStops();
727 case TY_CSI_PS(
'h', 4):
728 _currentScreen->setMode(MODE_Insert);
730 case TY_CSI_PS(
'h', 20):
731 setMode(MODE_NewLine);
733 case TY_CSI_PS(
'i', 0):
735 case TY_CSI_PS(
'l', 4):
736 _currentScreen->resetMode(MODE_Insert);
738 case TY_CSI_PS(
'l', 20):
739 resetMode(MODE_NewLine);
741 case TY_CSI_PS(
's', 0):
744 case TY_CSI_PS(
'u', 0):
748 case TY_CSI_PS(
'm', 0):
749 _currentScreen->setDefaultRendition();
751 case TY_CSI_PS(
'm', 1):
752 _currentScreen->setRendition(RE_BOLD);
754 case TY_CSI_PS(
'm', 2):
755 _currentScreen->setRendition(RE_FAINT);
757 case TY_CSI_PS(
'm', 3):
758 _currentScreen->setRendition(RE_ITALIC);
760 case TY_CSI_PS(
'm', 4):
761 _currentScreen->setRendition(RE_UNDERLINE);
763 case TY_CSI_PS(
'm', 5):
764 _currentScreen->setRendition(RE_BLINK);
766 case TY_CSI_PS(
'm', 7):
767 _currentScreen->setRendition(RE_REVERSE);
769 case TY_CSI_PS(
'm', 8):
770 _currentScreen->setRendition(RE_CONCEAL);
772 case TY_CSI_PS(
'm', 9):
773 _currentScreen->setRendition(RE_STRIKEOUT);
775 case TY_CSI_PS(
'm', 53):
776 _currentScreen->setRendition(RE_OVERLINE);
778 case TY_CSI_PS(
'm', 10):
780 case TY_CSI_PS(
'm', 11):
782 case TY_CSI_PS(
'm', 12):
784 case TY_CSI_PS(
'm', 21):
785 _currentScreen->resetRendition(RE_BOLD);
787 case TY_CSI_PS(
'm', 22):
788 _currentScreen->resetRendition(RE_BOLD);
791 case TY_CSI_PS(
'm', 23):
792 _currentScreen->resetRendition(RE_ITALIC);
794 case TY_CSI_PS(
'm', 24):
795 _currentScreen->resetRendition(RE_UNDERLINE);
797 case TY_CSI_PS(
'm', 25):
798 _currentScreen->resetRendition(RE_BLINK);
800 case TY_CSI_PS(
'm', 27):
801 _currentScreen->resetRendition(RE_REVERSE);
803 case TY_CSI_PS(
'm', 28):
804 _currentScreen->resetRendition(RE_CONCEAL);
806 case TY_CSI_PS(
'm', 29):
807 _currentScreen->resetRendition(RE_STRIKEOUT);
809 case TY_CSI_PS(
'm', 55):
810 _currentScreen->resetRendition(RE_OVERLINE);
813 case TY_CSI_PS(
'm', 30):
814 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 0);
816 case TY_CSI_PS(
'm', 31):
817 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 1);
819 case TY_CSI_PS(
'm', 32):
820 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 2);
822 case TY_CSI_PS(
'm', 33):
823 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 3);
825 case TY_CSI_PS(
'm', 34):
826 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 4);
828 case TY_CSI_PS(
'm', 35):
829 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 5);
831 case TY_CSI_PS(
'm', 36):
832 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 6);
834 case TY_CSI_PS(
'm', 37):
835 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 7);
838 case TY_CSI_PS(
'm', 38):
839 _currentScreen->setForeColor(p, q);
842 case TY_CSI_PS(
'm', 39):
843 _currentScreen->setForeColor(COLOR_SPACE_DEFAULT, 0);
846 case TY_CSI_PS(
'm', 40):
847 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 0);
849 case TY_CSI_PS(
'm', 41):
850 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 1);
852 case TY_CSI_PS(
'm', 42):
853 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 2);
855 case TY_CSI_PS(
'm', 43):
856 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 3);
858 case TY_CSI_PS(
'm', 44):
859 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 4);
861 case TY_CSI_PS(
'm', 45):
862 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 5);
864 case TY_CSI_PS(
'm', 46):
865 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 6);
867 case TY_CSI_PS(
'm', 47):
868 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 7);
871 case TY_CSI_PS(
'm', 48):
872 _currentScreen->setBackColor(p, q);
875 case TY_CSI_PS(
'm', 49):
876 _currentScreen->setBackColor(COLOR_SPACE_DEFAULT, 1);
879 case TY_CSI_PS(
'm', 90):
880 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 8);
882 case TY_CSI_PS(
'm', 91):
883 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 9);
885 case TY_CSI_PS(
'm', 92):
886 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 10);
888 case TY_CSI_PS(
'm', 93):
889 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 11);
891 case TY_CSI_PS(
'm', 94):
892 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 12);
894 case TY_CSI_PS(
'm', 95):
895 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 13);
897 case TY_CSI_PS(
'm', 96):
898 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 14);
900 case TY_CSI_PS(
'm', 97):
901 _currentScreen->setForeColor(COLOR_SPACE_SYSTEM, 15);
904 case TY_CSI_PS(
'm', 100):
905 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 8);
907 case TY_CSI_PS(
'm', 101):
908 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 9);
910 case TY_CSI_PS(
'm', 102):
911 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 10);
913 case TY_CSI_PS(
'm', 103):
914 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 11);
916 case TY_CSI_PS(
'm', 104):
917 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 12);
919 case TY_CSI_PS(
'm', 105):
920 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 13);
922 case TY_CSI_PS(
'm', 106):
923 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 14);
925 case TY_CSI_PS(
'm', 107):
926 _currentScreen->setBackColor(COLOR_SPACE_SYSTEM, 15);
929 case TY_CSI_PS(
'n', 5):
932 case TY_CSI_PS(
'n', 6):
933 reportCursorPosition();
935 case TY_CSI_PS(
'q', 0):
937 case TY_CSI_PS(
'q', 1):
939 case TY_CSI_PS(
'q', 2):
941 case TY_CSI_PS(
'q', 3):
943 case TY_CSI_PS(
'q', 4):
945 case TY_CSI_PS(
'x', 0):
946 reportTerminalParms(2);
948 case TY_CSI_PS(
'x', 1):
949 reportTerminalParms(3);
952 case TY_CSI_PS_SP(
'q', 0):
953 case TY_CSI_PS_SP(
'q', 1):
956 case TY_CSI_PS_SP(
'q', 2):
959 case TY_CSI_PS_SP(
'q', 3):
962 case TY_CSI_PS_SP(
'q', 4):
965 case TY_CSI_PS_SP(
'q', 5):
968 case TY_CSI_PS_SP(
'q', 6):
973 _currentScreen->insertChars(p);
976 _currentScreen->cursorUp(p);
979 _currentScreen->cursorDown(p);
982 _currentScreen->cursorRight(p);
985 _currentScreen->cursorLeft(p);
992 _currentScreen->setCursorX(p);
995 _currentScreen->setCursorYX(p, q);
998 _currentScreen->tab(p);
1000 case TY_CSI_PN(
'L'):
1001 _currentScreen->insertLines(p);
1003 case TY_CSI_PN(
'M'):
1004 _currentScreen->deleteLines(p);
1006 case TY_CSI_PN(
'P'):
1007 _currentScreen->deleteChars(p);
1009 case TY_CSI_PN(
'S'):
1010 _currentScreen->scrollUp(p);
1012 case TY_CSI_PN(
'T'):
1013 _currentScreen->scrollDown(p);
1015 case TY_CSI_PN(
'X'):
1016 _currentScreen->eraseChars(p);
1018 case TY_CSI_PN(
'Z'):
1019 _currentScreen->backtab(p);
1021 case TY_CSI_PN(
'b'):
1022 _currentScreen->repeatChars(p);
1024 case TY_CSI_PN(
'c'):
1025 reportTerminalType();
1027 case TY_CSI_PN(
'd'):
1028 _currentScreen->setCursorY(p);
1030 case TY_CSI_PN(
'f'):
1031 _currentScreen->setCursorYX(p, q);
1033 case TY_CSI_PN(
'r'):
1036 case TY_CSI_PN(
'y'):
1039 case TY_CSI_PR(
'h', 1):
1040 setMode(MODE_AppCuKeys);
1042 case TY_CSI_PR(
'l', 1):
1043 resetMode(MODE_AppCuKeys);
1045 case TY_CSI_PR(
's', 1):
1046 saveMode(MODE_AppCuKeys);
1048 case TY_CSI_PR(
'r', 1):
1049 restoreMode(MODE_AppCuKeys);
1052 case TY_CSI_PR(
'l', 2):
1053 resetMode(MODE_Ansi);
1056 case TY_CSI_PR(
'h', 3):
1057 setMode(MODE_132Columns);
1059 case TY_CSI_PR(
'l', 3):
1060 resetMode(MODE_132Columns);
1063 case TY_CSI_PR(
'h', 4):
1065 case TY_CSI_PR(
'l', 4):
1068 case TY_CSI_PR(
'h', 5):
1069 _currentScreen->setMode(MODE_Screen);
1071 case TY_CSI_PR(
'l', 5):
1072 _currentScreen->resetMode(MODE_Screen);
1075 case TY_CSI_PR(
'h', 6):
1076 _currentScreen->setMode(MODE_Origin);
1078 case TY_CSI_PR(
'l', 6):
1079 _currentScreen->resetMode(MODE_Origin);
1081 case TY_CSI_PR(
's', 6):
1082 _currentScreen->saveMode(MODE_Origin);
1084 case TY_CSI_PR(
'r', 6):
1085 _currentScreen->restoreMode(MODE_Origin);
1088 case TY_CSI_PR(
'h', 7):
1089 _currentScreen->setMode(MODE_Wrap);
1091 case TY_CSI_PR(
'l', 7):
1092 _currentScreen->resetMode(MODE_Wrap);
1094 case TY_CSI_PR(
's', 7):
1095 _currentScreen->saveMode(MODE_Wrap);
1097 case TY_CSI_PR(
'r', 7):
1098 _currentScreen->restoreMode(MODE_Wrap);
1101 case TY_CSI_PR(
'h', 8):
1103 case TY_CSI_PR(
'l', 8):
1105 case TY_CSI_PR(
's', 8):
1107 case TY_CSI_PR(
'r', 8):
1110 case TY_CSI_PR(
'h', 9):
1112 case TY_CSI_PR(
'l', 9):
1114 case TY_CSI_PR(
's', 9):
1116 case TY_CSI_PR(
'r', 9):
1119 case TY_CSI_PR(
'h', 12):
1121 case TY_CSI_PR(
'l', 12):
1123 case TY_CSI_PR(
's', 12):
1125 case TY_CSI_PR(
'r', 12):
1128 case TY_CSI_PR(
'h', 25):
1129 setMode(MODE_Cursor);
1131 case TY_CSI_PR(
'l', 25):
1132 resetMode(MODE_Cursor);
1134 case TY_CSI_PR(
's', 25):
1135 saveMode(MODE_Cursor);
1137 case TY_CSI_PR(
'r', 25):
1138 restoreMode(MODE_Cursor);
1141 case TY_CSI_PR(
'h', 40):
1142 setMode(MODE_Allow132Columns);
1144 case TY_CSI_PR(
'l', 40):
1145 resetMode(MODE_Allow132Columns);
1148 case TY_CSI_PR(
'h', 41):
1150 case TY_CSI_PR(
'l', 41):
1152 case TY_CSI_PR(
's', 41):
1154 case TY_CSI_PR(
'r', 41):
1157 case TY_CSI_PR(
'h', 47):
1158 setMode(MODE_AppScreen);
1160 case TY_CSI_PR(
'l', 47):
1161 resetMode(MODE_AppScreen);
1163 case TY_CSI_PR(
's', 47):
1164 saveMode(MODE_AppScreen);
1166 case TY_CSI_PR(
'r', 47):
1167 restoreMode(MODE_AppScreen);
1170 case TY_CSI_PR(
'h', 67):
1172 case TY_CSI_PR(
'l', 67):
1174 case TY_CSI_PR(
's', 67):
1176 case TY_CSI_PR(
'r', 67):
1193 case TY_CSI_PR(
'h', 1000):
1194 setMode(MODE_Mouse1000);
1196 case TY_CSI_PR(
'l', 1000):
1197 resetMode(MODE_Mouse1000);
1199 case TY_CSI_PR(
's', 1000):
1200 saveMode(MODE_Mouse1000);
1202 case TY_CSI_PR(
'r', 1000):
1203 restoreMode(MODE_Mouse1000);
1206 case TY_CSI_PR(
'h', 1001):
1208 case TY_CSI_PR(
'l', 1001):
1209 resetMode(MODE_Mouse1001);
1211 case TY_CSI_PR(
's', 1001):
1213 case TY_CSI_PR(
'r', 1001):
1216 case TY_CSI_PR(
'h', 1002):
1217 setMode(MODE_Mouse1002);
1219 case TY_CSI_PR(
'l', 1002):
1220 resetMode(MODE_Mouse1002);
1222 case TY_CSI_PR(
's', 1002):
1223 saveMode(MODE_Mouse1002);
1225 case TY_CSI_PR(
'r', 1002):
1226 restoreMode(MODE_Mouse1002);
1229 case TY_CSI_PR(
'h', 1003):
1230 setMode(MODE_Mouse1003);
1232 case TY_CSI_PR(
'l', 1003):
1233 resetMode(MODE_Mouse1003);
1235 case TY_CSI_PR(
's', 1003):
1236 saveMode(MODE_Mouse1003);
1238 case TY_CSI_PR(
'r', 1003):
1239 restoreMode(MODE_Mouse1003);
1242 case TY_CSI_PR(
'h', 1004):
1243 _reportFocusEvents = true;
1245 case TY_CSI_PR(
'l', 1004):
1246 _reportFocusEvents = false;
1249 case TY_CSI_PR(
'h', 1005):
1250 setMode(MODE_Mouse1005);
1252 case TY_CSI_PR(
'l', 1005):
1253 resetMode(MODE_Mouse1005);
1255 case TY_CSI_PR(
's', 1005):
1256 saveMode(MODE_Mouse1005);
1258 case TY_CSI_PR(
'r', 1005):
1259 restoreMode(MODE_Mouse1005);
1262 case TY_CSI_PR(
'h', 1006):
1263 setMode(MODE_Mouse1006);
1265 case TY_CSI_PR(
'l', 1006):
1266 resetMode(MODE_Mouse1006);
1268 case TY_CSI_PR(
's', 1006):
1269 saveMode(MODE_Mouse1006);
1271 case TY_CSI_PR(
'r', 1006):
1272 restoreMode(MODE_Mouse1006);
1275 case TY_CSI_PR(
'h', 1015):
1276 setMode(MODE_Mouse1015);
1278 case TY_CSI_PR(
'l', 1015):
1279 resetMode(MODE_Mouse1015);
1281 case TY_CSI_PR(
's', 1015):
1282 saveMode(MODE_Mouse1015);
1284 case TY_CSI_PR(
'r', 1015):
1285 restoreMode(MODE_Mouse1015);
1288 case TY_CSI_PR(
'h', 1034):
1291 case TY_CSI_PR(
'h', 1047):
1292 setMode(MODE_AppScreen);
1294 case TY_CSI_PR(
'l', 1047):
1296 resetMode(MODE_AppScreen);
1298 case TY_CSI_PR(
's', 1047):
1299 saveMode(MODE_AppScreen);
1301 case TY_CSI_PR(
'r', 1047):
1302 restoreMode(MODE_AppScreen);
1306 case TY_CSI_PR(
'h', 1048):
1309 case TY_CSI_PR(
'l', 1048):
1312 case TY_CSI_PR(
's', 1048):
1315 case TY_CSI_PR(
'r', 1048):
1321 case TY_CSI_PR(
'h', 1049):
1323 _alternateScreen->clearEntireScreen();
1324 setMode(MODE_AppScreen);
1326 case TY_CSI_PR(
'l', 1049):
1327 resetMode(MODE_AppScreen);
1331 case TY_CSI_PR(
'h', 2004):
1332 setMode(MODE_BracketedPaste);
1334 case TY_CSI_PR(
'l', 2004):
1335 resetMode(MODE_BracketedPaste);
1337 case TY_CSI_PR(
's', 2004):
1338 saveMode(MODE_BracketedPaste);
1340 case TY_CSI_PR(
'r', 2004):
1341 restoreMode(MODE_BracketedPaste);
1345 case TY_CSI_PE(
'p'):
1350 _currentScreen->cursorUp(1);
1353 _currentScreen->cursorDown(1);
1356 _currentScreen->cursorRight(1);
1359 _currentScreen->cursorLeft(1);
1363 setAndUseCharset(0,
'0');
1366 setAndUseCharset(0,
'B');
1370 _currentScreen->setCursorYX(1, 1);
1373 _currentScreen->reverseIndex();
1376 _currentScreen->clearToEndOfScreen();
1379 _currentScreen->clearToEndOfLine();
1382 _currentScreen->setCursorYX(p - 31, q - 31);
1385 reportTerminalType();
1391 setMode(MODE_AppKeyPad);
1394 resetMode(MODE_AppKeyPad);
1397 case TY_CSI_PG(
'c'):
1398 reportSecondaryAttributes();
1402 reportDecodingError();
1407void Vt102Emulation::clearScreenAndSetColumns(
int columnCount)
1411 setDefaultMargins();
1415void Vt102Emulation::sendString(
const char *s,
int length)
1423void Vt102Emulation::reportCursorPosition()
1425 const size_t sz = 20;
1427 const size_t r = snprintf(tmp, sz,
"\033[%d;%dR", _currentScreen->
getCursorY() + 1, _currentScreen->
getCursorX() + 1);
1429 qWarning(
"Vt102Emulation::reportCursorPosition: Buffer too small\n");
1434void Vt102Emulation::reportTerminalType()
1441 if (getMode(MODE_Ansi))
1442 sendString(
"\033[?1;2c");
1444 sendString(
"\033/Z");
1447void Vt102Emulation::reportSecondaryAttributes()
1450 if (getMode(MODE_Ansi))
1451 sendString(
"\033[>0;115;0c");
1453 sendString(
"\033/Z");
1457void Vt102Emulation::reportTerminalParms(
int p)
1460 const size_t sz = 100;
1462 const size_t r = snprintf(tmp, sz,
"\033[%d;1;1;112;112;1;0x", p);
1464 qWarning(
"Vt102Emulation::reportTerminalParms: Buffer too small\n");
1469void Vt102Emulation::reportStatus()
1471 sendString(
"\033[0n");
1474void Vt102Emulation::reportAnswerBack()
1478 const char *ANSWER_BACK =
"";
1479 sendString(ANSWER_BACK);
1494 if (cx < 1 || cy < 1)
1499 if (eventType == 2 && !getMode(MODE_Mouse1006))
1508 if ((getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1)
1514 if (getMode(MODE_Mouse1006)) {
1515 snprintf(command,
sizeof(command),
"\033[<%d;%d;%d%c", cb, cx, cy, eventType == 2 ?
'm' :
'M');
1516 }
else if (getMode(MODE_Mouse1015)) {
1517 snprintf(command,
sizeof(command),
"\033[%d;%d;%dM", cb + 0x20, cx, cy);
1518 }
else if (getMode(MODE_Mouse1005)) {
1519 if (cx <= 2015 && cy <= 2015) {
1524 coords[0] =
QChar(cx + 0x20);
1525 coords[1] =
QChar(cy + 0x20);
1528 snprintf(command,
sizeof(command),
"\033[M%c%s", cb + 0x20,
utf8.constData());
1530 }
else if (cx <= 223 && cy <= 223) {
1531 snprintf(command,
sizeof(command),
"\033[M%c%c%c", cb + 0x20, cx + 0x20, cy + 0x20);
1534 sendString(command);
1546 if (_reportFocusEvents)
1547 sendString(
"\033[O");
1559 if (_reportFocusEvents)
1560 sendString(
"\033[I");
1563void Vt102Emulation::sendText(
const QString &text)
1567 sendKeyEvent(&
event,
false);
1578 if (isTheLabeledKeyCommandPressed) {
1579 qDebug(
"Command is pressed.");
1580 modifiers &=
~Qt::ControlModifier;
1583 modifiers &=
~Qt::MetaModifier;
1586 if (isTheLabeledKeyControlPressed) {
1587 qDebug(
"Control is pressed.");
1588 modifiers &=
~Qt::MetaModifier;
1591 modifiers &=
~Qt::ControlModifier;
1597 event->nativeScanCode(),
1598 event->nativeVirtualKey(),
1599 event->nativeModifiers(),
1601 event->isAutoRepeat(),
1605void Vt102Emulation::sendKeyEvent(
QKeyEvent *origEvent,
bool fromPaste)
1607#if defined(Q_OS_MAC)
1616 if (getMode(MODE_NewLine))
1618 if (getMode(MODE_Ansi))
1620 if (getMode(MODE_AppCuKeys))
1622 if (getMode(MODE_AppScreen))
1629 switch (
event->key()) {
1641 if (_keyTranslator) {
1655 if (modifiers &
Qt::AltModifier && !(wantsAltModifier || wantsAnyModifier) && !
event->text().isEmpty()) {
1658 if (modifiers &
Qt::MetaModifier && !(wantsMetaModifier || wantsAnyModifier) && !
event->text().isEmpty()) {
1671 textToSend += entry.
text(
true, modifiers);
1673 textToSend += (
event->key() & 0x1f);
1677 textToSend +=
"\033[5~";
1679 textToSend +=
"\033[6~";
1681 textToSend += _codec->fromUnicode(
event->text());
1684 if (!fromPaste && textToSend.
length()) {
1685 Q_EMIT outputFromKeypressEvent();
1692 tr(
"No keyboard translator available. "
1693 "The information needed to convert key presses "
1694 "into characters to send to the terminal "
1725#define CHARSET _charset[_currentScreen == _alternateScreen.get()]
1729constexpr std::array<unsigned short, 32> vt100_graphics = {
1730 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c,
1731 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534, 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7};
1735wchar_t Vt102Emulation::applyCharset(
char16_t c)
1737 if (CHARSET.graphic && 0x5f <= c && c <= 0x7e)
1738 return vt100_graphics[c - 0x5f];
1739 if (CHARSET.pound && c ==
'#')
1752void Vt102Emulation::resetCharset(
int scrno)
1754 _charset[scrno].cu_cs = 0;
1755 qstrncpy(_charset[scrno].charset,
"BBBB", 4);
1756 _charset[scrno].sa_graphic =
false;
1757 _charset[scrno].sa_pound =
false;
1758 _charset[scrno].graphic =
false;
1759 _charset[scrno].pound =
false;
1762void Vt102Emulation::setCharset(
int n,
int cs)
1764 _charset[0].charset[n & 3] = cs;
1765 useCharset(_charset[0].cu_cs);
1766 _charset[1].charset[n & 3] = cs;
1767 useCharset(_charset[1].cu_cs);
1770void Vt102Emulation::setAndUseCharset(
int n,
int cs)
1772 CHARSET.charset[n & 3] = cs;
1776void Vt102Emulation::useCharset(
int n)
1778 CHARSET.cu_cs = n & 3;
1779 CHARSET.graphic = (CHARSET.charset[n & 3] ==
'0');
1780 CHARSET.pound = (CHARSET.charset[n & 3] ==
'A');
1783void Vt102Emulation::setDefaultMargins()
1785 _primaryScreen->setDefaultMargins();
1786 _alternateScreen->setDefaultMargins();
1789void Vt102Emulation::setMargins(
int t,
int b)
1791 _primaryScreen->setMargins(t, b);
1792 _alternateScreen->setMargins(t, b);
1795void Vt102Emulation::saveCursor()
1797 CHARSET.sa_graphic = CHARSET.graphic;
1798 CHARSET.sa_pound = CHARSET.pound;
1805void Vt102Emulation::restoreCursor()
1807 CHARSET.graphic = CHARSET.sa_graphic;
1808 CHARSET.pound = CHARSET.sa_pound;
1832void Vt102Emulation::resetModes()
1837 resetMode(MODE_132Columns);
1838 saveMode(MODE_132Columns);
1839 resetMode(MODE_Mouse1000);
1840 saveMode(MODE_Mouse1000);
1841 resetMode(MODE_Mouse1001);
1842 saveMode(MODE_Mouse1001);
1843 resetMode(MODE_Mouse1002);
1844 saveMode(MODE_Mouse1002);
1845 resetMode(MODE_Mouse1003);
1846 saveMode(MODE_Mouse1003);
1847 resetMode(MODE_Mouse1005);
1848 saveMode(MODE_Mouse1005);
1849 resetMode(MODE_Mouse1006);
1850 saveMode(MODE_Mouse1006);
1851 resetMode(MODE_Mouse1015);
1852 saveMode(MODE_Mouse1015);
1853 resetMode(MODE_BracketedPaste);
1854 saveMode(MODE_BracketedPaste);
1856 resetMode(MODE_AppScreen);
1857 saveMode(MODE_AppScreen);
1858 resetMode(MODE_AppCuKeys);
1859 saveMode(MODE_AppCuKeys);
1860 resetMode(MODE_AppKeyPad);
1861 saveMode(MODE_AppKeyPad);
1862 resetMode(MODE_NewLine);
1866void Vt102Emulation::setMode(
int m)
1868 _currentModes.mode[m] =
true;
1870 case MODE_132Columns:
1871 if (getMode(MODE_Allow132Columns))
1872 clearScreenAndSetColumns(132);
1874 _currentModes.mode[m] =
false;
1876 case MODE_Mouse1000:
1877 case MODE_Mouse1001:
1878 case MODE_Mouse1002:
1879 case MODE_Mouse1003:
1883 case MODE_BracketedPaste:
1884 Q_EMIT programBracketedPasteModeChanged(
true);
1888 case MODE_AppScreen:
1889 _alternateScreen->clearSelection();
1893 if (m < MODES_SCREEN || m == MODE_NewLine) {
1894 _primaryScreen->setMode(m);
1895 _alternateScreen->setMode(m);
1899void Vt102Emulation::resetMode(
int m)
1901 _currentModes.mode[m] =
false;
1903 case MODE_132Columns:
1904 if (getMode(MODE_Allow132Columns))
1905 clearScreenAndSetColumns(80);
1907 case MODE_Mouse1000:
1908 case MODE_Mouse1001:
1909 case MODE_Mouse1002:
1910 case MODE_Mouse1003:
1914 case MODE_BracketedPaste:
1915 Q_EMIT programBracketedPasteModeChanged(
false);
1918 case MODE_AppScreen:
1919 _primaryScreen->clearSelection();
1923 if (m < MODES_SCREEN || m == MODE_NewLine) {
1924 _primaryScreen->resetMode(m);
1925 _alternateScreen->resetMode(m);
1929void Vt102Emulation::saveMode(
int m)
1931 _savedModes.mode[m] = _currentModes.mode[m];
1934void Vt102Emulation::restoreMode(
int m)
1936 if (_savedModes.mode[m])
1942bool Vt102Emulation::getMode(
int m)
1944 return _currentModes.mode[m];
1951 return entry.
text().
at(0);
1956void Vt102Emulation::reportDecodingError()
1958 if (tokenBufferPos == 0 || (tokenBufferPos == 1 && (tokenBuffer[0] & 0xff) >= 32))
1960 qDebug() <<
"Undecodable sequence:" <<
QString::fromUtf16(tokenBuffer, tokenBufferPos);
Base class for terminal emulation back-ends.
void programUsesMouseChanged(bool usesMouse)
This is emitted when the program running in the shell indicates whether or not it is interested in mo...
void imageResizeRequest(const QSize &sizz)
Emitted after receiving the escape sequence which asks to change the terminal emulator's size.
void receiveData(const char *buffer, int len)
Processes an incoming stream of characters.
@ UnderlineCursor
A single flat line which occupies the space at the bottom of the cursor character's area.
@ BlockCursor
A rectangular block which covers the entire area of the cursor character.
@ IBeamCursor
An cursor shaped like the capital letter 'I', similar to the IBeam cursor used in Qt/KDE text editors...
void bufferedUpdate()
Schedules an update of attached views.
void changeTabTextColorRequest(int color)
Requests that the color of the text used to represent the tabs associated with this emulation be chan...
void stateSet(int state)
Emitted when the activity state of the emulation is set.
void flowControlKeyPressed(bool suspendKeyPressed)
Emitted when a flow control key combination ( Ctrl+S or Ctrl+Q ) is pressed.
virtual void setImageSize(int lines, int columns)
Change the size of the emulation's image.
void setScreen(int index)
Sets the active screen.
void titleChanged(int title, const QString &newTitle)
Emitted when the program running in the terminal wishes to update the session's title.
void clearHistory()
Clears the history scroll.
bool utf8() const
Convenience method.
void cursorChanged(KeyboardCursorShape cursorShape, bool blinkingCursorEnabled)
Emitted when the cursor shape or its blinking state is changed via DECSCUSR sequences.
void sendData(const char *data, int len)
Emitted when a buffer of data is ready to send to the standard input of the terminal.
void setCodec(const QTextCodec *)
Sets the codec used to decode incoming characters.
Represents an association between a key sequence pressed by the user and the character sequence and c...
Command command() const
Returns the commands associated with this entry.
Qt::KeyboardModifiers modifierMask() const
Returns the keyboard modifiers which are valid in this entry.
States state() const
Returns a bitwise-OR of the enabled state flags associated with this entry.
States stateMask() const
Returns the state flags which are valid in this entry.
Qt::KeyboardModifiers modifiers() const
Returns a bitwise-OR of the enabled keyboard modifiers associated with this entry.
QByteArray text(bool expandWildCards=false, Qt::KeyboardModifiers modifiers=Qt::NoModifier) const
Returns the character sequence associated with this entry, optionally replacing wildcard '*' characte...
Entry findEntry(int keyCode, Qt::KeyboardModifiers modifiers, States state=NoState) const
Looks for an entry in this keyboard translator which matches the given key code, keyboard modifiers a...
static const Qt::KeyboardModifier CTRL_MOD
The modifier code for the actual Ctrl key on this OS.
@ AnsiState
Indicates that the terminal is in 'Ansi' mode.
@ NoState
Indicates that no special state is active.
@ AlternateScreenState
Indicates that the alternate screen ( typically used by interactive programs such as screen or vim ) ...
@ AnyModifierState
Indicates that any of the modifier keys is active.
@ NewLineState
TODO More documentation.
@ CursorKeysState
TODO More documentation.
@ ApplicationKeypadState
Indicates that the numpad is in application mode.
@ NoCommand
Indicates that no command is associated with this command sequence.
@ EraseCommand
Echos the operating system specific erase character.
void setCursorYX(int y, int x)
Position the cursor at line y, column x.
int getCursorY() const
Returns the line which the cursor is positioned on.
void clearEntireScreen()
Clear the whole screen, moving the current screen contents into the history first.
void saveCursor()
Saves the current position and appearance (text color and style) of the cursor.
int getCursorX() const
Returns the column which the cursor is positioned at.
int getLines() const
Return the number of lines.
void setLineProperty(LineProperty property, bool enable)
Sets or clears an attribute of the current line.
void resetRendition(int rendition)
Disables the given rendition flag.
void restoreCursor()
Restores the position and appearance of the cursor.
void clearEntireScreen() override
Copies the current image into the history and clears the screen.
void reset() override
Resets the state of the terminal.
virtual void focusLost()
The focus lost event can be used by Vim (or other terminal applications) to recognize that the konsol...
void receiveChar(QChar cc) override
Processes an incoming character.
char eraseChar() const override
TODO Document me.
Vt102Emulation()
Constructs a new emulation.
virtual void focusGained()
The focus gained event can be used by Vim (or other terminal applications) to recognize that the kons...
void sendMouseEvent(int buttons, int column, int line, int eventType) override
char at(qsizetype i) const const
const char * constData() const const
bool isEmpty() const const
qsizetype length() const const
QByteArray & prepend(QByteArrayView ba)
qsizetype size() const const
QList< Key > keys() const const
Qt::KeyboardModifiers modifiers() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
virtual bool event(QEvent *e)
QString tr(const char *sourceText, const char *disambiguation, int n)
QString fromUtf16(const char16_t *unicode, qsizetype size)
bool isEmpty() const const
qsizetype size() const const
QByteArray toUtf8() const const
void setSingleShot(bool singleShot)