X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=lib-ui%2Fcurs_lib.c;h=dc42e300abd7b56910d0babfee68f88405cdee53;hp=5ac5dcb1ddb929bde60672865651425f1d7b04a5;hb=51f3b41879d6df19c4549803a11e9f0dd34c8ffb;hpb=83170cc0ea7b56b7ffe3b311b6b7d831393e7524 diff --git a/lib-ui/curs_lib.c b/lib-ui/curs_lib.c index 5ac5dcb..dc42e30 100644 --- a/lib-ui/curs_lib.c +++ b/lib-ui/curs_lib.c @@ -117,16 +117,80 @@ void mutt_clear_error (void) CLEARLINE(stdscr, LINES - 1); } +static struct timeval const slice = { 0, 1000 * 1000 / 100 }; +static struct timeval timeval_add(struct timeval a, struct timeval b) +{ + int usec = a.tv_usec + b.tv_usec; + a.tv_sec += b.tv_sec; + while (usec > 1000 * 1000) { + a.tv_sec += 1; + usec -= 1000 * 1000; + } + a.tv_usec = usec; + return a; +} + +static int is_expired(struct timeval now, struct timeval expiry) +{ + return now.tv_sec > expiry.tv_sec + || (now.tv_sec == expiry.tv_sec && now.tv_usec > expiry.tv_usec); +} + void mutt_edit_file(const char *data) { - char cmd[LONG_STRING]; - - mutt_endwin (NULL); - m_quotefile_fmt(cmd, sizeof (cmd), mod_core.editor, data); - if (mutt_system (cmd) == -1) - mutt_error (_("Error running \"%s\"!"), cmd); - keypad (stdscr, TRUE); - clearok (stdscr, TRUE); + char cmd[STRING]; + const char *args[] = { "/bin/sh", "-c", cmd, NULL }; + int dirty = 0, ch, res, mh, mw, pty, pid; + struct timeval next; + madtty_t *rt; + + m_quotefile_fmt(cmd, sizeof(cmd), mod_core.editor, data); + getmaxyx(main_w, mh, mw); + SigChild = 0; + + rt = madtty_create(mh - 1, mw); + pid = madtty_forkpty(rt, args[0], args, &pty); + if (pid < 0) { + madtty_destroy(rt); + mutt_error(_("unable to start editor")); + return; + } + + nodelay(stdscr, true); + gettimeofday(&next, NULL); + while (!SigChild) { + struct timeval tv = { 0, 1000 * 1000 / 100 }; + fd_set rfds; + + FD_ZERO(&rfds); + FD_SET(0, &rfds); + FD_SET(pty, &rfds); + + if (select(pty + 1, &rfds, NULL, NULL, &tv) < 0) + break; + + if (FD_ISSET(pty, &rfds)) { + madtty_process(rt); + dirty = 1; + } + + while ((ch = getch()) != ERR) { + madtty_keypress(rt, ch); /* pass the keypress for handling */ + dirty = 1; + } + + gettimeofday(&tv, NULL); + if (dirty && is_expired(tv, next)) { + madtty_draw(rt, main_w, 0, 0); + wrefresh(main_w); + dirty = 0; + next = timeval_add(tv, slice); + } + } + while (waitpid(pid, &res, 0) < 0 && errno == EINTR); + nodelay(stdscr, false); + close(pty); + madtty_destroy(rt); } int mutt_yesorno (const char *msg, int def)