JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Add xcalloc wrapper
[st.git] / st.c
diff --git a/st.c b/st.c
index 12d6665..df7f8d8 100644 (file)
--- a/st.c
+++ b/st.c
@@ -48,7 +48,7 @@
 #define ESC_ARG_SIZ   16
 #define STR_BUF_SIZ   256
 #define STR_ARG_SIZ   16
-#define DRAW_BUF_SIZ  1024
+#define DRAW_BUF_SIZ  20*1024
 #define UTF_SIZ       4
 #define XK_NO_MOD     UINT_MAX
 #define XK_ANY_MOD    0
@@ -324,6 +324,7 @@ static int isfullutf8(char *, int);
 
 static void *xmalloc(size_t);
 static void *xrealloc(void *, size_t);
+static void *xcalloc(size_t nmemb, size_t size);
 
 static void (*handler[LASTEvent])(XEvent *) = {
        [KeyPress] = kpress,
@@ -373,6 +374,14 @@ xrealloc(void *p, size_t len) {
        return p;
 }
 
+void *
+xcalloc(size_t nmemb, size_t size) {
+       void *p = calloc(nmemb, size);
+       if(!p)
+               die("Out of memory\n");
+       return p;
+}
+
 int
 utf8decode(char *s, long *u) {
        uchar c;
@@ -1801,8 +1810,8 @@ tresize(int col, int row) {
        /* allocate any new rows */
        for(/* i == minrow */; i < row; i++) {
                term.dirty[i] = 1;
-               term.line[i] = calloc(col, sizeof(Glyph));
-               term.alt [i] = calloc(col, sizeof(Glyph));
+               term.line[i] = xcalloc(col, sizeof(Glyph));
+               term.alt [i] = xcalloc(col, sizeof(Glyph));
        }
        if(col > term.col) {
                bool *bp = term.tabs + term.col;
@@ -2319,8 +2328,7 @@ resize(XEvent *e) {
        row = (xw.h - 2*BORDER) / xw.ch;
        if(col == term.col && row == term.row)
                return;
-       if(tresize(col, row))
-               draw();
+       tresize(col, row);
        xresize(col, row);
        ttyresize(col, row);
 }
@@ -2329,20 +2337,38 @@ void
 run(void) {
        XEvent ev;
        fd_set rfd;
-       int xfd = XConnectionNumber(xw.dpy);
+       int xfd = XConnectionNumber(xw.dpy), i;
+       struct timeval drawtimeout, *tv = NULL;
 
-       for(;;) {
+       for(i = 0;; i++) {
                FD_ZERO(&rfd);
                FD_SET(cmdfd, &rfd);
                FD_SET(xfd, &rfd);
-               if(select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, NULL) < 0) {
+               if(select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, tv) < 0) {
                        if(errno == EINTR)
                                continue;
                        die("select failed: %s\n", SERRNO);
                }
-               if(FD_ISSET(cmdfd, &rfd))
+
+               /*
+                * Stop after a certain number of reads so the user does not
+                * feel like the system is stuttering.
+                */
+               if(i < 1000 && FD_ISSET(cmdfd, &rfd)) {
                        ttyread();
 
+                       /*
+                        * Just wait a bit so it isn't disturbing the
+                        * user and the system is able to write something.
+                        */
+                       drawtimeout.tv_sec = 0;
+                       drawtimeout.tv_usec = 5;
+                       tv = &drawtimeout;
+                       continue;
+               }
+               i = 0;
+               tv = NULL;
+
                while(XPending(xw.dpy)) {
                        XNextEvent(xw.dpy, &ev);
                        if(XFilterEvent(&ev, xw.win))