term.c (5516B)
1 #include <stdlib.h> 2 #include <string.h> 3 4 #include "term.h" 5 6 /* Eterm */ 7 static const char *Eterm_keys[] = { 8 "\033[11~","\033[12~","\033[13~","\033[14~","\033[15~","\033[17~","\033[18~","\033[19~","\033[20~","\033[21~","\033[23~","\033[24~","\033[2~","\033[3~","\033[7~","\033[8~","\033[5~","\033[6~","\033[A","\033[B","\033[D","\033[C", 0 9 }; 10 static const char *Eterm_funcs[] = { 11 [T_ENTER_CA] = "\0337\033[?47h", 12 [T_EXIT_CA] = "\033[2J\033[?47l\0338", 13 [T_SHOW_CURSOR] = "\033[?25h", 14 [T_HIDE_CURSOR] = "\033[?25l", 15 [T_CLEAR_SCREEN] = "\033[H\033[2J", 16 [T_SGR0] = "\033[m", 17 [T_UNDERLINE] = "\033[4m", 18 [T_BOLD] = "\033[1m", 19 [T_BLINK] = "\033[5m", 20 [T_ENTER_KEYPAD] = "", 21 [T_EXIT_KEYPAD] = "", 22 }; 23 24 /* screen */ 25 static const char *screen_keys[] = { 26 "\033OP","\033OQ","\033OR","\033OS","\033[15~","\033[17~","\033[18~","\033[19~","\033[20~","\033[21~","\033[23~","\033[24~","\033[2~","\033[3~","\033[1~","\033[4~","\033[5~","\033[6~","\033OA","\033OB","\033OD","\033OC", 0 27 }; 28 static const char *screen_funcs[] = { 29 [T_ENTER_CA] = "\033[?1049h", 30 [T_EXIT_CA] = "\033[?1049l", 31 [T_SHOW_CURSOR] = "\033[34h\033[?25h", 32 [T_HIDE_CURSOR] = "\033[?25l", 33 [T_CLEAR_SCREEN] = "\033[H\033[J", 34 [T_SGR0] = "\033[m", 35 [T_UNDERLINE] = "\033[4m", 36 [T_BOLD] = "\033[1m", 37 [T_BLINK] = "\033[5m", 38 [T_ENTER_KEYPAD] = "\033[?1h\033=", 39 [T_EXIT_KEYPAD] = "\033[?1l\033>", 40 }; 41 42 /* xterm */ 43 static const char *xterm_keys[] = { 44 "\033OP","\033OQ","\033OR","\033OS","\033[15~","\033[17~","\033[18~","\033[19~","\033[20~","\033[21~","\033[23~","\033[24~","\033[2~","\033[3~","\033OH","\033OF","\033[5~","\033[6~","\033OA","\033OB","\033OD","\033OC", 0 45 }; 46 static const char *xterm_funcs[] = { 47 [T_ENTER_CA] = "\033[?1049h", 48 [T_EXIT_CA] = "\033[?1049l", 49 [T_SHOW_CURSOR] = "\033[?12l\033[?25h", 50 [T_HIDE_CURSOR] = "\033[?25l", 51 [T_CLEAR_SCREEN] = "\033[H\033[2J", 52 [T_SGR0] = "\033(B\033[m", 53 [T_UNDERLINE] = "\033[4m", 54 [T_BOLD] = "\033[1m", 55 [T_BLINK] = "\033[5m", 56 [T_ENTER_KEYPAD] = "\033[?1h\033=", 57 [T_EXIT_KEYPAD] = "\033[?1l\033>", 58 }; 59 60 /* rxvt-unicode */ 61 static const char *rxvt_unicode_keys[] = { 62 "\033[11~","\033[12~","\033[13~","\033[14~","\033[15~","\033[17~","\033[18~","\033[19~","\033[20~","\033[21~","\033[23~","\033[24~","\033[2~","\033[3~","\033[7~","\033[8~","\033[5~","\033[6~","\033[A","\033[B","\033[D","\033[C", 0 63 }; 64 static const char *rxvt_unicode_funcs[] = { 65 [T_ENTER_CA] = "\033[?1049h", 66 [T_EXIT_CA] = "\033[r\033[?1049l", 67 [T_SHOW_CURSOR] = "\033[?25h", 68 [T_HIDE_CURSOR] = "\033[?25l", 69 [T_CLEAR_SCREEN] = "\033[H\033[2J", 70 [T_SGR0] = "\033[m\033(B", 71 [T_UNDERLINE] = "\033[4m", 72 [T_BOLD] = "\033[1m", 73 [T_BLINK] = "\033[5m", 74 [T_ENTER_KEYPAD] = "\033=", 75 [T_EXIT_KEYPAD] = "\033>", 76 }; 77 78 /* linux */ 79 static const char *linux_keys[] = { 80 "\033[[A","\033[[B","\033[[C","\033[[D","\033[[E","\033[17~","\033[18~","\033[19~","\033[20~","\033[21~","\033[23~","\033[24~","\033[2~","\033[3~","\033[1~","\033[4~","\033[5~","\033[6~","\033[A","\033[B","\033[D","\033[C", 0 81 }; 82 static const char *linux_funcs[] = { 83 [T_ENTER_CA] = "", 84 [T_EXIT_CA] = "", 85 [T_SHOW_CURSOR] = "\033[?25h\033[?0c", 86 [T_HIDE_CURSOR] = "\033[?25l\033[?1c", 87 [T_CLEAR_SCREEN] = "\033[H\033[J", 88 [T_SGR0] = "\033[0;10m", 89 [T_UNDERLINE] = "\033[4m", 90 [T_BOLD] = "\033[1m", 91 [T_BLINK] = "\033[5m", 92 [T_ENTER_KEYPAD] = "", 93 [T_EXIT_KEYPAD] = "", 94 }; 95 96 /* rxvt-256color */ 97 static const char *rxvt_256color_keys[] = { 98 "\033[11~","\033[12~","\033[13~","\033[14~","\033[15~","\033[17~","\033[18~","\033[19~","\033[20~","\033[21~","\033[23~","\033[24~","\033[2~","\033[3~","\033[7~","\033[8~","\033[5~","\033[6~","\033[A","\033[B","\033[D","\033[C", 0 99 }; 100 static const char *rxvt_256color_funcs[] = { 101 [T_ENTER_CA] = "\0337\033[?47h", 102 [T_EXIT_CA] = "\033[2J\033[?47l\0338", 103 [T_SHOW_CURSOR] = "\033[?25h", 104 [T_HIDE_CURSOR] = "\033[?25l", 105 [T_CLEAR_SCREEN] = "\033[H\033[2J", 106 [T_SGR0] = "\033[m", 107 [T_UNDERLINE] = "\033[4m", 108 [T_BOLD] = "\033[1m", 109 [T_BLINK] = "\033[5m", 110 [T_ENTER_KEYPAD] = "\033=", 111 [T_EXIT_KEYPAD] = "\033>", 112 }; 113 114 static struct term { 115 const char *name; 116 const char **keys; 117 const char **funcs; 118 } terms[] = { 119 {"Eterm", Eterm_keys, Eterm_funcs}, 120 {"screen", screen_keys, screen_funcs}, 121 {"xterm", xterm_keys, xterm_funcs}, 122 {"rxvt-unicode", rxvt_unicode_keys, rxvt_unicode_funcs}, 123 {"linux", linux_keys, linux_funcs}, 124 {"rxvt-256color", rxvt_256color_keys, rxvt_256color_funcs}, 125 {0,0,0} 126 }; 127 128 const char **keys; 129 const char **funcs; 130 131 static int try_compatible(const char *term, const char *name, 132 const char **tkeys, const char **tfuncs) 133 { 134 if (strstr(term, name)) { 135 keys = tkeys; 136 funcs = tfuncs; 137 return 0; 138 } 139 140 return EUNSUPPORTED_TERM; 141 } 142 143 int init_term(void) 144 { 145 int i; 146 const char *term = getenv("TERM"); 147 148 if (term) { 149 for (i = 0; terms[i].name; i++) { 150 if (!strcmp(terms[i].name, term)) { 151 keys = terms[i].keys; 152 funcs = terms[i].funcs; 153 return 0; 154 } 155 } 156 157 /* let's do some heuristic, maybe it's a compatible terminal */ 158 if (try_compatible(term, "xterm", xterm_keys, xterm_funcs) == 0) 159 return 0; 160 if (try_compatible(term, "rxvt", rxvt_unicode_keys, rxvt_unicode_funcs) == 0) 161 return 0; 162 if (try_compatible(term, "linux", linux_keys, linux_funcs) == 0) 163 return 0; 164 if (try_compatible(term, "Eterm", Eterm_keys, Eterm_funcs) == 0) 165 return 0; 166 if (try_compatible(term, "screen", screen_keys, screen_funcs) == 0) 167 return 0; 168 /* let's assume that 'cygwin' is xterm compatible */ 169 if (try_compatible(term, "cygwin", xterm_keys, xterm_funcs) == 0) 170 return 0; 171 } 172 173 return EUNSUPPORTED_TERM; 174 }