Use ncurses or go away.
[apps/madmutt.git] / lib-ui / curs_lib.c
index 437ffbc..9236788 100644 (file)
@@ -61,22 +61,6 @@ event_t mutt_getch (void)
   return (ch == ctrl ('G') ? err : ret);
 }
 
-#ifndef waddnwstr
-int waddwch(WINDOW *win, wchar_t wc)
-{
-    char buf[MB_LEN_MAX * 2];
-    mbstate_t mbstate;
-    ssize_t n1, n2;
-
-    p_clear(&mbstate, 1);
-    if ((n1 = wcrtomb(buf, wc, &mbstate)) == -1
-    ||  (n2 = wcrtomb(buf + n1, 0, &mbstate)) == -1)
-        return -1;                  /* ERR */
-    return waddstr(win, buf);
-}
-#endif
-
-
 int _mutt_get_field ( const char *field, char *buf, ssize_t buflen,
                      int complete, int multiple, char ***files, int *numfiles)
 {
@@ -117,16 +101,83 @@ 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 - 2, mw);
+    pid = madtty_forkpty(rt, args[0], args, &pty);
+    if (pid < 0) {
+        madtty_destroy(rt);
+        mutt_error(_("unable to start editor"));
+        return;
+    }
+
+    SETCOLOR(main_w, MT_COLOR_SIDEBAR);
+    mvwhline(main_w, 0, 0, ACS_HLINE, mw);
+
+    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, 1, 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)
@@ -311,7 +362,8 @@ void mutt_show_error (void)
 void curses_initialize(void)
 {
     initscr();
-    start_color();
+    if (start_color() == ERR || !has_colors() || COLORS < 8)
+        mutt_exit(-1);
     madtty_init_colors();
     ci_start_color();
     noecho();
@@ -323,27 +375,6 @@ void curses_initialize(void)
     ESCDELAY = 50;
 }
 
-/*
- * prompts the user to enter a keystroke, and displays the octal value back
- * to the user.
- */
-void mutt_what_key (void)
-{
-  int ch;
-
-  mvwprintw(stdscr, LINES - 1, 0, _("Enter keys (^G to abort): "));
-  do {
-    ch = getch();
-    if (ch != ERR && ch != ctrl ('G')) {
-      mutt_message (_("Char = %s, Octal = %o, Decimal = %d"),
-                    km_keyname (ch), ch, ch);
-    }
-  }
-  while (ch != ERR && ch != ctrl ('G'));
-
-  mutt_flushinp ();
-}
-
 int mutt_any_key_to_continue (const char *s)
 {
   struct termios t;