1 /* 2 * TSM - Main Header 3 * 4 * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@gmail.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files 8 * (the "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 #ifndef TSM_LIBTSM_H 27 #define TSM_LIBTSM_H 28 29 #include <inttypes.h> 30 #include <stdarg.h> 31 #include <stdbool.h> 32 #include <stdlib.h> 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 /** 39 * @mainpage 40 * 41 * TSM is a Terminal-emulator State Machine. It implements all common DEC-VT100 42 * to DEC-VT520 control codes and features. A state-machine is used to parse TTY 43 * input and saved in a virtual screen. TSM does not provide any rendering, 44 * glyph/font handling or anything more advanced. TSM is just a simple 45 * state-machine for control-codes handling. 46 * The main use-case for TSM are terminal-emulators. TSM has no dependencies 47 * other than an ISO-C99 compiler and C-library. Any terminal emulator for any 48 * window-environment or rendering-pipline can make use of TSM. However, TSM can 49 * also be used for control-code validation, TTY-screen-capturing or other 50 * advanced users of terminal escape-sequences. 51 */ 52 53 /** 54 * @defgroup symbols Unicode Helpers 55 * Unicode helpers 56 * 57 * Unicode uses 32bit types to uniquely represent symbols. However, combining 58 * characters allow modifications of such symbols but require additional space. 59 * To avoid passing around allocated strings, TSM provides a symbol-table which 60 * can store combining-characters with their base-symbol to create a new symbol. 61 * This way, only the symbol-identifiers have to be passed around (which are 62 * simple integers). No string allocation is needed by the API user. 63 * 64 * The symbol table is currently not exported. Once the API is fixed, we will 65 * provide it to outside users. 66 * 67 * Additionally, this contains some general UTF8/UCS4 helpers. 68 * 69 * @{ 70 */ 71 72 /* UCS4 helpers */ 73 74 #define TSM_UCS4_MAX (0x7fffffffUL) 75 #define TSM_UCS4_INVALID (TSM_UCS4_MAX + 1) 76 #define TSM_UCS4_REPLACEMENT (0xfffdUL) 77 78 /* ucs4 to utf8 converter */ 79 80 size_t tsm_ucs4_to_utf8(uint32_t ucs4, char *out); 81 char *tsm_ucs4_to_utf8_alloc(const uint32_t *ucs4, size_t len, size_t *len_out); 82 83 /* symbols */ 84 85 typedef uint32_t tsm_symbol_t; 86 87 /** @} */ 88 89 /** 90 * @defgroup screen Terminal Screens 91 * Virtual terminal-screen implementation 92 * 93 * A TSM screen respresents the real screen of a terminal/application. It does 94 * not render anything, but only provides a table of cells. Each cell contains 95 * the stored symbol, attributes and more. Applications iterate a screen to 96 * render each cell on their framebuffer. 97 * 98 * Screens provide all features that are expected from terminals. They include 99 * scroll-back buffers, alternate screens, cursor positions and selection 100 * support. Thus, it needs event-input from applications to drive these 101 * features. Most of them are optional, though. 102 * 103 * @{ 104 */ 105 106 struct tsm_screen; 107 typedef uint_fast32_t tsm_age_t; 108 109 #define TSM_SCREEN_INSERT_MODE 0x01 110 #define TSM_SCREEN_AUTO_WRAP 0x02 111 #define TSM_SCREEN_REL_ORIGIN 0x04 112 #define TSM_SCREEN_INVERSE 0x08 113 #define TSM_SCREEN_HIDE_CURSOR 0x10 114 #define TSM_SCREEN_FIXED_POS 0x20 115 #define TSM_SCREEN_ALTERNATE 0x40 116 117 struct tsm_screen_attr { 118 int8_t fccode; /* foreground color code or <0 for rgb */ 119 int8_t bccode; /* background color code or <0 for rgb */ 120 uint8_t fr; /* foreground red */ 121 uint8_t fg; /* foreground green */ 122 uint8_t fb; /* foreground blue */ 123 uint8_t br; /* background red */ 124 uint8_t bg; /* background green */ 125 uint8_t bb; /* background blue */ 126 unsigned int bold : 1; /* bold character */ 127 unsigned int underline : 1; /* underlined character */ 128 unsigned int inverse : 1; /* inverse colors */ 129 unsigned int protect : 1; /* cannot be erased */ 130 unsigned int blink : 1; /* blinking character */ 131 }; 132 133 typedef int (*tsm_screen_draw_cb) (struct tsm_screen *con, 134 uint32_t id, 135 const uint32_t *ch, 136 size_t len, 137 int width, 138 int posx, 139 int posy, 140 const struct tsm_screen_attr *attr, 141 tsm_age_t age, 142 void *data); 143 144 int tsm_screen_new(struct tsm_screen **out); 145 void tsm_screen_ref(struct tsm_screen *con); 146 void tsm_screen_unref(struct tsm_screen *con); 147 148 int tsm_screen_get_width(struct tsm_screen *con); 149 int tsm_screen_get_height(struct tsm_screen *con); 150 int tsm_screen_resize(struct tsm_screen *con, int x, int y); 151 int tsm_screen_set_margins(struct tsm_screen *con, int top, int bottom); 152 void tsm_screen_set_max_sb(struct tsm_screen *con, int max); 153 void tsm_screen_clear_sb(struct tsm_screen *con); 154 155 void tsm_screen_sb_up(struct tsm_screen *con, int num); 156 void tsm_screen_sb_down(struct tsm_screen *con, int num); 157 void tsm_screen_sb_page_up(struct tsm_screen *con, int num); 158 void tsm_screen_sb_page_down(struct tsm_screen *con, int num); 159 void tsm_screen_sb_reset(struct tsm_screen *con); 160 161 void tsm_screen_set_def_attr(struct tsm_screen *con, 162 const struct tsm_screen_attr *attr); 163 void tsm_screen_reset(struct tsm_screen *con); 164 void tsm_screen_set_flags(struct tsm_screen *con, unsigned int flags); 165 void tsm_screen_reset_flags(struct tsm_screen *con, unsigned int flags); 166 unsigned int tsm_screen_get_flags(struct tsm_screen *con); 167 168 int tsm_screen_get_cursor_x(struct tsm_screen *con); 169 int tsm_screen_get_cursor_y(struct tsm_screen *con); 170 171 void tsm_screen_set_tabstop(struct tsm_screen *con); 172 void tsm_screen_reset_tabstop(struct tsm_screen *con); 173 void tsm_screen_reset_all_tabstops(struct tsm_screen *con); 174 175 void tsm_screen_write(struct tsm_screen *con, tsm_symbol_t ch, 176 const struct tsm_screen_attr *attr); 177 void tsm_screen_newline(struct tsm_screen *con); 178 void tsm_screen_scroll_up(struct tsm_screen *con, int num); 179 void tsm_screen_scroll_down(struct tsm_screen *con, int num); 180 void tsm_screen_move_to(struct tsm_screen *con, int x, int y); 181 void tsm_screen_move_up(struct tsm_screen *con, int num, bool scroll); 182 void tsm_screen_move_down(struct tsm_screen *con, int num, bool scroll); 183 void tsm_screen_move_left(struct tsm_screen *con, int num); 184 void tsm_screen_move_right(struct tsm_screen *con, int num); 185 void tsm_screen_move_line_end(struct tsm_screen *con); 186 void tsm_screen_move_line_home(struct tsm_screen *con); 187 void tsm_screen_tab_right(struct tsm_screen *con, int num); 188 void tsm_screen_tab_left(struct tsm_screen *con, int num); 189 void tsm_screen_insert_lines(struct tsm_screen *con, int num); 190 void tsm_screen_delete_lines(struct tsm_screen *con, int num); 191 void tsm_screen_insert_chars(struct tsm_screen *con, int num); 192 void tsm_screen_delete_chars(struct tsm_screen *con, int num); 193 void tsm_screen_erase_cursor(struct tsm_screen *con); 194 void tsm_screen_erase_chars(struct tsm_screen *con, int num); 195 void tsm_screen_erase_cursor_to_end(struct tsm_screen *con, bool protect); 196 void tsm_screen_erase_home_to_cursor(struct tsm_screen *con, bool protect); 197 void tsm_screen_erase_current_line(struct tsm_screen *con, bool protect); 198 void tsm_screen_erase_screen_to_cursor(struct tsm_screen *con, bool protect); 199 void tsm_screen_erase_cursor_to_screen(struct tsm_screen *con, bool protect); 200 void tsm_screen_erase_screen(struct tsm_screen *con, bool protect); 201 202 void tsm_screen_selection_reset(struct tsm_screen *con); 203 void tsm_screen_selection_start(struct tsm_screen *con, int posx, int posy); 204 void tsm_screen_selection_target(struct tsm_screen *con, int posx, int posy); 205 int tsm_screen_selection_copy(struct tsm_screen *con, char **out); 206 207 tsm_age_t tsm_screen_draw(struct tsm_screen *con, tsm_screen_draw_cb draw_cb, 208 void *data); 209 210 /** @} */ 211 212 /** 213 * @defgroup vte State Machine 214 * Virtual terminal emulation with state machine 215 * 216 * A TSM VTE object provides the terminal state machine. It takes input from the 217 * application (which usually comes from a TTY/PTY from a client), parses it, 218 * modifies the attach screen or returns data which has to be written back to 219 * the client. 220 * 221 * Furthermore, VTE objects accept keyboard or mouse input from the application 222 * which is interpreted compliant to DEV-VTs. 223 * 224 * @{ 225 */ 226 227 /* virtual terminal emulator */ 228 229 struct tsm_vte; 230 231 /* keep in sync with shl_xkb_mods */ 232 enum tsm_vte_modifier { 233 TSM_SHIFT_MASK = (1 << 0), 234 TSM_LOCK_MASK = (1 << 1), 235 TSM_CONTROL_MASK = (1 << 2), 236 TSM_ALT_MASK = (1 << 3), 237 TSM_LOGO_MASK = (1 << 4), 238 }; 239 240 /* keep in sync with TSM_INPUT_INVALID */ 241 #define TSM_VTE_INVALID 0xffffffff 242 243 typedef void (*tsm_vte_write_cb) (struct tsm_vte *vte, 244 const char *u8, 245 size_t len, 246 void *data); 247 248 int tsm_vte_new(struct tsm_vte **out, struct tsm_screen *con, 249 tsm_vte_write_cb write_cb, void *data); 250 void tsm_vte_ref(struct tsm_vte *vte); 251 void tsm_vte_unref(struct tsm_vte *vte); 252 253 #define TSM_COLOR_NUM 18 254 enum tsm_vte_color { 255 TSM_COLOR_BLACK, 256 TSM_COLOR_RED, 257 TSM_COLOR_GREEN, 258 TSM_COLOR_YELLOW, 259 TSM_COLOR_BLUE, 260 TSM_COLOR_MAGENTA, 261 TSM_COLOR_CYAN, 262 TSM_COLOR_LIGHT_GREY, 263 TSM_COLOR_DARK_GREY, 264 TSM_COLOR_LIGHT_RED, 265 TSM_COLOR_LIGHT_GREEN, 266 TSM_COLOR_LIGHT_YELLOW, 267 TSM_COLOR_LIGHT_BLUE, 268 TSM_COLOR_LIGHT_MAGENTA, 269 TSM_COLOR_LIGHT_CYAN, 270 TSM_COLOR_WHITE, 271 272 TSM_COLOR_FOREGROUND, 273 TSM_COLOR_BACKGROUND 274 }; 275 276 int tsm_vte_set_palette(struct tsm_vte *vte, uint8_t (*palette)[3]); 277 void tsm_vte_get_def_attr(struct tsm_vte *vte, struct tsm_screen_attr *out); 278 279 void tsm_vte_reset(struct tsm_vte *vte); 280 void tsm_vte_hard_reset(struct tsm_vte *vte); 281 void tsm_vte_input(struct tsm_vte *vte, const char *u8, size_t len); 282 bool tsm_vte_handle_keyboard(struct tsm_vte *vte, uint32_t keysym, 283 uint32_t ascii, unsigned int mods, 284 uint32_t unicode); 285 void tsm_vte_paste_begin(struct tsm_vte *vte); 286 void tsm_vte_paste_end(struct tsm_vte *vte); 287 288 /** @} */ 289 290 #ifdef __cplusplus 291 } 292 #endif 293 294 #endif /* TSM_LIBTSM_H */ 295