summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bin/termptyesc.c122
1 files changed, 71 insertions, 51 deletions
diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c
index 6dc993c..2eea134 100644
--- a/src/bin/termptyesc.c
+++ b/src/bin/termptyesc.c
@@ -16,12 +16,16 @@
16#define ERR(...) EINA_LOG_DOM_ERR(_termpty_log_dom, __VA_ARGS__) 16#define ERR(...) EINA_LOG_DOM_ERR(_termpty_log_dom, __VA_ARGS__)
17#define WRN(...) EINA_LOG_DOM_WARN(_termpty_log_dom, __VA_ARGS__) 17#define WRN(...) EINA_LOG_DOM_WARN(_termpty_log_dom, __VA_ARGS__)
18#define INF(...) EINA_LOG_DOM_INFO(_termpty_log_dom, __VA_ARGS__) 18#define INF(...) EINA_LOG_DOM_INFO(_termpty_log_dom, __VA_ARGS__)
19#define DBG(...) EINA_LOG_DOM_DBG(_termpty_log_dom, __VA_ARGS__) 19#define DBG(...) EINA_LOG_DOM_ERR(_termpty_log_dom, __VA_ARGS__)
20 20
21#define ST 0x9c // String Terminator 21#define ST 0x9c // String Terminator
22#define BEL 0x07 // Bell 22#define BEL 0x07 // Bell
23#define ESC 033 // Escape 23#define ESC 033 // Escape
24 24
25/* XXX: all handle_ functions return the number of bytes successfully read, 0
26 * if not enought bytes could be read
27 */
28
25static int 29static int
26_csi_arg_get(Eina_Unicode **ptr) 30_csi_arg_get(Eina_Unicode **ptr)
27{ 31{
@@ -62,10 +66,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
62 b++; 66 b++;
63 cc++; 67 cc++;
64 } 68 }
65 // if cc == ce then we got to the end of the string with no end marker 69 if (cc == ce) return 0;
66 // so return -2 to indicate to go back to the escape beginning when
67 // there is more bufer available
68 if (cc == ce) return -2;
69 *b = 0; 70 *b = 0;
70 b = buf; 71 b = buf;
71// DBG(" CSI: '%c' args '%s'", *cc, buf); 72// DBG(" CSI: '%c' args '%s'", *cc, buf);
@@ -892,7 +893,7 @@ _handle_esc_xterm(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
892 } 893 }
893 *b = 0; 894 *b = 0;
894 if ((*cc == ST) || (*cc == BEL) || (*cc == '\\')) cc++; 895 if ((*cc == ST) || (*cc == BEL) || (*cc == '\\')) cc++;
895 else return -2; 896 else return 0;
896 switch (buf[0]) 897 switch (buf[0])
897 { 898 {
898 case '0': 899 case '0':
@@ -946,6 +947,8 @@ _handle_esc_xterm(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
946 break; 947 break;
947 case '4': 948 case '4':
948 // XXX: set palette entry. not supported. 949 // XXX: set palette entry. not supported.
950 DBG("set palette, not supported");
951 if ((cc - c) < 3) return 0;
949 b = &(buf[2]); 952 b = &(buf[2]);
950 break; 953 break;
951 default: 954 default:
@@ -974,7 +977,7 @@ _handle_esc_terminology(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
974 } 977 }
975 *b = 0; 978 *b = 0;
976 if (*cc == 0x0) cc++; 979 if (*cc == 0x0) cc++;
977 else return -2; 980 else return 0;
978 // commands are stored in the buffer, 0 bytes not allowd (end marker) 981 // commands are stored in the buffer, 0 bytes not allowd (end marker)
979 s = eina_unicode_unicode_to_utf8(buf, &slen); 982 s = eina_unicode_unicode_to_utf8(buf, &slen);
980 ty->cur_cmd = s; 983 ty->cur_cmd = s;
@@ -1008,7 +1011,7 @@ _handle_esc_dcs(Termpty *ty __UNUSED__, const Eina_Unicode *c, Eina_Unicode *ce)
1008 } 1011 }
1009 *b = 0; 1012 *b = 0;
1010 if ((*cc == ST) || (*cc == '\\')) cc++; 1013 if ((*cc == ST) || (*cc == '\\')) cc++;
1011 else return -2; 1014 else return 0;
1012 switch (buf[0]) 1015 switch (buf[0])
1013 { 1016 {
1014 case '+': 1017 case '+':
@@ -1025,73 +1028,89 @@ _handle_esc_dcs(Termpty *ty __UNUSED__, const Eina_Unicode *c, Eina_Unicode *ce)
1025static int 1028static int
1026_handle_esc(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) 1029_handle_esc(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
1027{ 1030{
1028 if ((ce - c) < 2) return 0; 1031 int len = ce - c;
1029 DBG("ESC: '%c'", c[1]); 1032
1030 switch (c[1]) 1033 if (len < 1) return 0;
1034 DBG("ESC: '%c'", c[0]);
1035 switch (c[0])
1031 { 1036 {
1032 case '[': 1037 case '[':
1033 return 2 + _handle_esc_csi(ty, c + 2, ce); 1038 len = _handle_esc_csi(ty, c + 1, ce);
1039 if (len == 0) return 0;
1040 return 1 + len;
1034 case ']': 1041 case ']':
1035 return 2 + _handle_esc_xterm(ty, c + 2, ce); 1042 len = _handle_esc_xterm(ty, c + 1, ce);
1043 if (len == 0) return 0;
1044 return 1 + len;
1036 case '}': 1045 case '}':
1037 return 2 + _handle_esc_terminology(ty, c + 2, ce); 1046 len = _handle_esc_terminology(ty, c + 1, ce);
1047 if (len == 0) return 0;
1048 return 1 + len;
1038 case 'P': 1049 case 'P':
1039 return 2 + _handle_esc_dcs(ty, c + 2, ce); 1050 len = _handle_esc_dcs(ty, c + 1, ce);
1051 if (len == 0) return 0;
1052 return 1 + len;
1040 case '=': // set alternate keypad mode 1053 case '=': // set alternate keypad mode
1041 ty->state.alt_kp = 1; 1054 ty->state.alt_kp = 1;
1042 return 2; 1055 return 1;
1043 case '>': // set numeric keypad mode 1056 case '>': // set numeric keypad mode
1044 ty->state.alt_kp = 0; 1057 ty->state.alt_kp = 0;
1045 return 2; 1058 return 1;
1046 case 'M': // move to prev line 1059 case 'M': // move to prev line
1047 ty->state.wrapnext = 0; 1060 ty->state.wrapnext = 0;
1048 ty->state.cy--; 1061 ty->state.cy--;
1049 _termpty_text_scroll_rev_test(ty); 1062 _termpty_text_scroll_rev_test(ty);
1050 return 2; 1063 return 1;
1051 case 'D': // move to next line 1064 case 'D': // move to next line
1052 ty->state.wrapnext = 0; 1065 ty->state.wrapnext = 0;
1053 ty->state.cy++; 1066 ty->state.cy++;
1054 _termpty_text_scroll_test(ty); 1067 _termpty_text_scroll_test(ty);
1055 return 2; 1068 return 1;
1056 case 'E': // add \n\r 1069 case 'E': // add \n\r
1057 ty->state.wrapnext = 0; 1070 ty->state.wrapnext = 0;
1058 ty->state.cx = 0; 1071 ty->state.cx = 0;
1059 ty->state.cy++; 1072 ty->state.cy++;
1060 _termpty_text_scroll_test(ty); 1073 _termpty_text_scroll_test(ty);
1061 return 2; 1074 return 1;
1062 case 'Z': // same a 'ESC [ Pn c' 1075 case 'Z': // same a 'ESC [ Pn c'
1063 _term_txt_write(ty, "\033[?1;2C"); 1076 _term_txt_write(ty, "\033[?1;2C");
1064 return 2; 1077 return 1;
1065 case 'c': // reset terminal to initial state 1078 case 'c': // reset terminal to initial state
1066 DBG("reset to init mode and clear"); 1079 DBG("reset to init mode and clear");
1067 _termpty_reset_state(ty); 1080 _termpty_reset_state(ty);
1068 _termpty_clear_screen(ty, TERMPTY_CLR_ALL); 1081 _termpty_clear_screen(ty, TERMPTY_CLR_ALL);
1069 if (ty->cb.cancel_sel.func) 1082 if (ty->cb.cancel_sel.func)
1070 ty->cb.cancel_sel.func(ty->cb.cancel_sel.data); 1083 ty->cb.cancel_sel.func(ty->cb.cancel_sel.data);
1071 return 2; 1084 return 1;
1072 case '(': // charset 0 1085 case '(': // charset 0
1073 ty->state.chset[0] = c[2]; 1086 if (len < 2) return 0;
1087 ty->state.chset[0] = c[1];
1074 ty->state.multibyte = 0; 1088 ty->state.multibyte = 0;
1075 ty->state.charsetch = c[2]; 1089 ty->state.charsetch = c[1];
1076 return 3; 1090 return 2;
1077 case ')': // charset 1 1091 case ')': // charset 1
1078 ty->state.chset[1] = c[2]; 1092 if (len < 2) return 0;
1093 ty->state.chset[1] = c[1];
1079 ty->state.multibyte = 0; 1094 ty->state.multibyte = 0;
1080 return 3; 1095 return 2;
1081 case '*': // charset 2 1096 case '*': // charset 2
1082 ty->state.chset[2] = c[2]; 1097 if (len < 2) return 0;
1098 ty->state.chset[2] = c[1];
1083 ty->state.multibyte = 0; 1099 ty->state.multibyte = 0;
1084 return 3; 1100 return 2;
1085 case '+': // charset 3 1101 case '+': // charset 3
1086 ty->state.chset[3] = c[2]; 1102 if (len < 2) return 0;
1103 ty->state.chset[3] = c[1];
1087 ty->state.multibyte = 0; 1104 ty->state.multibyte = 0;
1088 return 3; 1105 return 2;
1089 case '$': // charset -2 1106 case '$': // charset -2
1090 ty->state.chset[2] = c[2]; 1107 if (len < 2) return 0;
1108 ty->state.chset[2] = c[1];
1091 ty->state.multibyte = 1; 1109 ty->state.multibyte = 1;
1092 return 3; 1110 return 2;
1093 case '#': // #8 == test mode -> fill screen with "E"; 1111 case '#': // #8 == test mode -> fill screen with "E";
1094 if (c[2] == '8') 1112 if (len < 2) return 0;
1113 if (c[1] == '8')
1095 { 1114 {
1096 int i, size; 1115 int i, size;
1097 Termcell *cells; 1116 Termcell *cells;
@@ -1110,30 +1129,31 @@ _handle_esc(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
1110 for (i = 0; i < size; i++) cells[i].codepoint = 'E'; 1129 for (i = 0; i < size; i++) cells[i].codepoint = 'E';
1111 } 1130 }
1112 } 1131 }
1113 return 3; 1132 return 2;
1114 case '@': // just consume this plus next char 1133 case '@': // just consume this plus next char
1115 return 3; 1134 if (len < 2) return 0;
1135 return 2;
1116 case '7': // save cursor pos 1136 case '7': // save cursor pos
1117 _termpty_cursor_copy(&(ty->state), &(ty->save)); 1137 _termpty_cursor_copy(&(ty->state), &(ty->save));
1118 return 2; 1138 return 1;
1119 case '8': // restore cursor pos 1139 case '8': // restore cursor pos
1120 _termpty_cursor_copy(&(ty->save), &(ty->state)); 1140 _termpty_cursor_copy(&(ty->save), &(ty->state));
1121 return 2; 1141 return 1;
1122/* 1142/*
1123 case 'G': // query gfx mode 1143 case 'G': // query gfx mode
1124 return 3;
1125 case 'H': // set tab at current column
1126 return 2; 1144 return 2;
1145 case 'H': // set tab at current column
1146 return 1;
1127 case 'n': // single shift 2 1147 case 'n': // single shift 2
1128 return 2; 1148 return 1;
1129 case 'o': // single shift 3 1149 case 'o': // single shift 3
1130 return 2; 1150 return 1;
1131 */ 1151 */
1132 default: 1152 default:
1133 ERR("eek - esc unhandled '%c' (0x%02x)", c[1], c[1]); 1153 ERR("eek - esc unhandled '%c' (0x%02x)", c[0], c[0]);
1134 break; 1154 return 1;
1135 } 1155 }
1136 return 1; 1156 return 0;
1137} 1157}
1138 1158
1139int 1159int
@@ -1257,7 +1277,9 @@ _termpty_handle_seq(Termpty *ty, Eina_Unicode *c, Eina_Unicode *ce)
1257 */ 1277 */
1258 case 0x1b: // ESC (escape) 1278 case 0x1b: // ESC (escape)
1259 ty->state.had_cr = 0; 1279 ty->state.had_cr = 0;
1260 return _handle_esc(ty, c, ce); 1280 len = _handle_esc(ty, c + 1, ce);
1281 if (len == 0) return 0;
1282 return 1 + len;
1261/* 1283/*
1262 case 0x1c: // FS (file separator) 1284 case 0x1c: // FS (file separator)
1263 return 1; 1285 return 1;
@@ -1282,13 +1304,11 @@ _termpty_handle_seq(Termpty *ty, Eina_Unicode *c, Eina_Unicode *ce)
1282 } 1304 }
1283 else if (c[0] == 0x9b) // ANSI ESC!!! 1305 else if (c[0] == 0x9b) // ANSI ESC!!!
1284 { 1306 {
1285 int v;
1286
1287 printf("ANSI CSI!!!!!\n"); 1307 printf("ANSI CSI!!!!!\n");
1288 ty->state.had_cr = 0; 1308 ty->state.had_cr = 0;
1289 v = _handle_esc_csi(ty, c + 1, ce); 1309 len = _handle_esc_csi(ty, c + 1, ce);
1290 if (v == -2) return 0; 1310 if (len == 0) return 0;
1291 return v + 1; 1311 return 1 + len;
1292 } 1312 }
1293 1313
1294 cc = (int *)c; 1314 cc = (int *)c;