# vt100 emulator `vt100-emulator` is a headless [vt100](https://fr.wikipedia.org/wiki/VT100) emulator, a bit like any terminal you may use daily (like urxvt, xterm, ...) but those you're using are NOT headless, they have a graphical interface to interact with you, human). Here, `vt100-emulator` is only the underlying a `C` and `Python` API to an actual emulator, so you can do everything you want with it, like interfacing over TCP, HTTP, automatically testing your implementation `malloc` against `top` while running `top` in the headless terminal, whatever pleases you. For copyright information, please see the file COPYRIGHT in this directory or in the files of the source tree. # INSTALL ## Python module You'll need `swig`, so `apt-get install swig` or whatever works for you. Run: $ make python_module && su -c 'python setup.py install' # Usage using the python wrapper (same methods in C) ``` >>> import hl_vt100 >>> import threading >>> class Top: ... def __init__(self): ... self.vt100 = hl_vt100.vt100_headless() ... self.vt100.fork('top', ['top']) ... ... def __call__(self): ... self.vt100.main_loop() ... ... def __str__(self): ... return "\n".join(self.vt100.getlines()) ... >>> top = Top() >>> thread = threading.Thread(target=top) >>> thread.start() >>> print(top) top - 09:42:43 up 332 days, 23:42, 14 users, load average: 3.08, 3.41, 3.52 KiB Mem: 16443168 total, 15865172 used, 577996 free, 1141216 buffers KiB Swap: 999420 total, 669960 used, 329460 free. 6097952 cached Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 24237 nobody 20 0 1041352 348040 39116 R 78.8 2.1 142:18.54 redacted 24078 nobody 20 0 1152024 382592 38948 R 25.8 2.3 355:44.85 for 24892 nobody 20 0 1182408 434560 40276 S 21.1 2.6 394:06.48 privacy 24472 nobody 20 0 1153196 380712 39000 S 20.3 2.3 410:51.64 ayah 23617 nobody 20 0 170048 100072 6376 S 19.5 0.6 8:36.66 python 23646 nobody 20 0 1095252 367128 39916 R 17.9 2.2 353:48.65 you 23505 nobody 20 0 1159452 377948 38920 S 17.2 2.3 364:29.40 wont 24757 nobody 20 0 943848 216084 40028 R 15.6 1.3 231:10.38 know 23894 nobody 20 0 885740 166600 38724 S 13.3 1.0 195:48.99 what 24689 nobody 20 0 901152 183240 39780 S 13.3 1.1 192:50.13 eats 24820 nobody 20 0 937712 232392 39496 S 13.3 1.4 215:25.32 my_cpu 3117 nobody 20 0 402568 351740 5912 S 3.1 2.1 0:03.72 python 3122 mandark 20 0 27052 3040 1184 R 3.1 0.0 0:00.34 top 23796 nobody 20 0 1069940 347252 39156 S 3.1 2.1 190:37.78 probably 23503 nobody 20 0 903592 268248 38360 S 1.6 1.6 75:54.32 somethign 5169 root 20 0 0 0 0 S 0.8 0.0 45:05.66 kworker/0:1 15324 root 20 0 63848 9768 1628 S 0.8 0.1 437:02.99 supervisord 16382 root 20 0 0 0 0 S 0.8 0.0 11:29.88 kworker/2:0 18278 root 20 0 0 0 0 S 0.8 0.0 184:02.23 kworker/1:0 ``` # Code overview lw_terminal_parser, lw_terminal_vt100, and hl_vt100 are three modules used to emulate a vt100 terminal: ``` ------------- | | | Your Code | | | ------------- | ^ vt100 = vt100_headless_init() | | vt100->changed = changed; | | hl_vt100 raises 'changed' vt100_headless_fork(vt100, ... | | when the screen has changed. | | You get the content of the screen | | calling vt100_headless_getlines. V | ------------- ------------- Read from PTY master and write | | | PTY | | to lw_terminal_vt100_read_str | | hl_vt100 |<------------>| Program | V | |Master Slave| | ------------- ------------- | |^ hl_vt100 gets lw_terminal_vt100's | || lines by calling | || lw_terminal_vt100_getlines | || | || V V| ---------------------- Got data from | | | Recieve data from callbacks lw_terminal_vt100_read_str | | lw_terminal_vt100 | And store an in-memory give it to | | | state of the vt100 terminal lw_terminal_parser_read_strV ---------------------- | ^ | | | | | | | | | | Callbacks | | | | | | | | | | V | ---------------------- Got data from | | lw_terminal_pasrser_read_str | lw_terminal_parser | parses, and call callbacks | | ---------------------- ``` ## lw_terminal_parser `lw_terminal_parser` parses terminal escape sequences, calling callbacks when a sequence is sucessfully parsed, read `example/parse.c`. Provides : * `struct lw_terminal *lw_terminal_parser_init(void);` * `void lw_terminal_parser_destroy(struct lw_terminal* this);` * `void lw_terminal_parser_default_unimplemented(struct lw_terminal* this, char *seq, char chr);` * `void lw_terminal_parser_read(struct lw_terminal *this, char c);` * `void lw_terminal_parser_read_str(struct lw_terminal *this, char *c);` ## lw_terminal_vt100 Hooks into a `lw_terminal_parser` and keep an in-memory state of the screen of a vt100. Provides : * `struct lw_terminal_vt100 *lw_terminal_vt100_init(void *user_data, void (*unimplemented)(struct lw_terminal* term_emul, char *seq, char chr));` * `char lw_terminal_vt100_get(struct lw_terminal_vt100 *vt100, unsigned int x, unsigned int y);` * `const char **lw_terminal_vt100_getlines(struct lw_terminal_vt100 *vt100);` * `void lw_terminal_vt100_destroy(struct lw_terminal_vt100 *this);` * `void lw_terminal_vt100_read_str(struct lw_terminal_vt100 *this, char *buffer);` ## hl_vt100 Forks a program, plug its io to a pseudo terminal and emulate a vt100 using `lw_terminal_vt100`. Provides : * `void vt100_headless_fork(struct vt100_headless *this, const char *progname, char *const argv[]);` * `struct vt100_headless *vt100_headless_init(void);` * `const char **vt100_headless_getlines(struct vt100_headless *this);`