lt

simple terminal emulator
Log | Files | Refs | git clone https://git.ne02ptzero.me/git/lt

commit bd018a968d78a68f1e46f814ccd516c80e268c16
parent df848edc86bb7f9d50cd4d4a88a98b6c2c754792
Author: Ne02ptzero <louis@ne02ptzero.me>
Date:   Wed,  6 Jun 2018 00:35:26 +0200

ADD: Smart redraw, for optimized performance

Signed-off-by: Ne02ptzero <louis@ne02ptzero.me>

Diffstat:
M.gitignore | 1+
Mmain.c | 1-
Mterm.c | 2+-
Mx.c | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
4 files changed, 67 insertions(+), 21 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,2 +1,3 @@ *.o lt +.gdb_history diff --git a/main.c b/main.c @@ -23,6 +23,5 @@ int main(int ac, const char **av) term_run(&term); - printf("Hello World!\n"); return 0; } diff --git a/term.c b/term.c @@ -45,7 +45,7 @@ void term_resize(term_t *term) ioctl(term->pty.master, TIOCSWINSZ, &ws); } -#define SHELL "/bin/bash" +#define SHELL "/bin/sh" void term_spawn(term_t *term) { char *env[] = { NULL }; diff --git a/x.c b/x.c @@ -9,6 +9,7 @@ #include <stdbool.h> #include <sys/select.h> #include <ctype.h> +#include <time.h> #include "term.h" @@ -142,17 +143,78 @@ static void term_key(term_t *term, XKeyEvent *ev) KeySym ksym; num = XLookupString(ev, buf, sizeof(buf), &ksym, 0); + write(term->pty.master, buf, num); } +#define ACTION_FPS 30 +#define XFPS 120 + +#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec) * 1000 + (t1.tv_nsec - t2.tv_nsec) / 1E6) +static void fps_redraw(term_t *term, fd_set *readable, struct timespec *tv) +{ + static struct timespec last = { 0 }; + static int xev = ACTION_FPS; + XEvent ev; + struct timespec now; + bool dodraw = false; + + if (last.tv_sec == 0 && last.tv_nsec == 0) + { + clock_gettime(CLOCK_MONOTONIC, &last); + } + + if (FD_ISSET(term->win.fd, readable)) + xev = ACTION_FPS; + + clock_gettime(CLOCK_MONOTONIC, &now); + tv->tv_sec = 0; + tv->tv_nsec = (1000 * 1E6) / XFPS; + + if (TIMEDIFF(now, last) > 1000 / (xev ? XFPS : ACTION_FPS)) + { + dodraw = true; + last = now; + } + + if (dodraw) + { + while (XPending(term->__dsp)) + { + XNextEvent(term->__dsp, &ev); + if (XFilterEvent(&ev, None)) + continue; + + switch (ev.type) + { + case KeyPress: + term_key(term, &ev.xkey); + break; + } + } + + term_redraw(term); + XFlush(term->__dsp); + + if (xev && !FD_ISSET(term->win.fd, readable)) + xev--; + + if (!FD_ISSET(term->pty.master, readable) && !FD_ISSET(term->win.fd, readable)) + { + tv->tv_sec = 0; + tv->tv_nsec = 0; + } + } +} + #define BUF_SIZE 2048 void term_run(term_t *term) { int maxfd; size_t size; fd_set readable; - XEvent ev; char buf[BUF_SIZE]; + struct timespec timeout = { 0 }; maxfd = MAX(term->pty.master, term->win.fd); @@ -162,30 +224,14 @@ void term_run(term_t *term) FD_SET(term->pty.master, &readable); FD_SET(term->win.fd, &readable); - assert(select(maxfd + 1, &readable, NULL, NULL, NULL) != -1); + assert(pselect(maxfd + 1, &readable, NULL, NULL, &timeout, NULL) != -1); if (FD_ISSET(term->pty.master, &readable)) { size = read(term->pty.master, buf, sizeof(buf)); term_buf(term, buf, size); - term_redraw(term); } - if (FD_ISSET(term->win.fd, &readable)) - { - while (XPending(term->__dsp)) - { - XNextEvent(term->__dsp, &ev); - switch (ev.type) - { - case Expose: - term_redraw(term); - break; - case KeyPress: - term_key(term, &ev.xkey); - break; - } - } - } + fps_redraw(term, &readable, &timeout); } }