Limit usage of extern to config.h globals
[st.git] / st.c
diff --git a/st.c b/st.c
index 01791a5..ce32cc0 100644 (file)
--- a/st.c
+++ b/st.c
@@ -95,6 +95,26 @@ enum escape_state {
        ESC_DCS        =128,
 };
 
+/* Internal representation of the screen */
+typedef struct {
+       int row;      /* nb row */
+       int col;      /* nb col */
+       Line *line;   /* screen */
+       Line *alt;    /* alternate screen */
+       int *dirty;   /* dirtyness of lines */
+       TCursor c;    /* cursor */
+       int ocx;      /* old cursor col */
+       int ocy;      /* old cursor row */
+       int top;      /* top    scroll limit */
+       int bot;      /* bottom scroll limit */
+       int mode;     /* terminal mode flags */
+       int esc;      /* escape state flags */
+       char trantbl[4]; /* charset table translation */
+       int charset;  /* current charset */
+       int icharset; /* selected charset for sequence */
+       int *tabs;
+} Term;
+
 /* CSI Escape sequence structs */
 /* ESC '[' [[ [<priv>] <arg> [;]] <mode> [<mode>]] */
 typedef struct {
@@ -116,8 +136,7 @@ typedef struct {
        int narg;              /* nb of args */
 } STREscape;
 
-
-static void execsh(char **);
+static void execsh(char *, char **);
 static void stty(char **);
 static void sigchld(int);
 static void ttywriteraw(const char *, size_t);
@@ -166,6 +185,8 @@ static int32_t tdefcolor(int *, int *, int);
 static void tdeftran(char);
 static void tstrsequence(uchar);
 
+static void drawregion(int, int, int, int);
+
 static void selscroll(int, int);
 static void selsnap(int *, int *, int);
 
@@ -179,15 +200,13 @@ static char *base64dec(const char *);
 static ssize_t xwrite(int, const char *, size_t);
 
 /* Globals */
-Term term;
-int cmdfd;
-pid_t pid;
-int oldbutton   = 3; /* button event on startup: 3 = release */
-
+static Term term;
 static Selection sel;
 static CSIEscape csiescseq;
 static STREscape strescseq;
 static int iofd = 1;
+static int cmdfd;
+static pid_t pid;
 
 static uchar utfbyte[UTF_SIZ + 1] = {0x80,    0, 0xC0, 0xE0, 0xF0};
 static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
@@ -637,7 +656,7 @@ die(const char *errstr, ...)
 }
 
 void
-execsh(char **args)
+execsh(char *cmd, char **args)
 {
        char *sh, *prog;
        const struct passwd *pw;
@@ -651,7 +670,7 @@ execsh(char **args)
        }
 
        if ((sh = getenv("SHELL")) == NULL)
-               sh = (pw->pw_shell[0]) ? pw->pw_shell : shell;
+               sh = (pw->pw_shell[0]) ? pw->pw_shell : cmd;
 
        if (args)
                prog = args[0];
@@ -723,8 +742,8 @@ stty(char **args)
            perror("Couldn't call stty");
 }
 
-void
-ttynew(char *line, char *out, char **args)
+int
+ttynew(char *line, char *cmd, char *out, char **args)
 {
        int m, s;
 
@@ -743,7 +762,7 @@ ttynew(char *line, char *out, char **args)
                        die("open line failed: %s\n", strerror(errno));
                dup2(cmdfd, 0);
                stty(args);
-               return;
+               return cmdfd;
        }
 
        /* seems to work fine on linux, openbsd and freebsd */
@@ -764,7 +783,7 @@ ttynew(char *line, char *out, char **args)
                        die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
                close(s);
                close(m);
-               execsh(args);
+               execsh(cmd, args);
                break;
        default:
                close(s);
@@ -772,6 +791,7 @@ ttynew(char *line, char *out, char **args)
                signal(SIGCHLD, sigchld);
                break;
        }
+       return cmdfd;
 }
 
 size_t
@@ -894,6 +914,13 @@ ttyresize(int tw, int th)
                fprintf(stderr, "Couldn't set window size: %s\n", strerror(errno));
 }
 
+void
+ttyhangup()
+{
+       /* Send SIGHUP to shell */
+       kill(pid, SIGHUP);
+}
+
 int
 tattrset(int attr)
 {
@@ -2526,6 +2553,42 @@ resettitle(void)
        xsettitle(NULL);
 }
 
+void
+drawregion(int x1, int y1, int x2, int y2)
+{
+       int y;
+       for (y = y1; y < y2; y++) {
+               if (!term.dirty[y])
+                       continue;
+
+               term.dirty[y] = 0;
+               xdrawline(term.line[y], x1, y, x2);
+       }
+}
+
+void
+draw(void)
+{
+       int cx = term.c.x;
+
+       if (!xstartdraw())
+               return;
+
+       /* adjust cursor position */
+       LIMIT(term.ocx, 0, term.col-1);
+       LIMIT(term.ocy, 0, term.row-1);
+       if (term.line[term.ocy][term.ocx].mode & ATTR_WDUMMY)
+               term.ocx--;
+       if (term.line[term.c.y][cx].mode & ATTR_WDUMMY)
+               cx--;
+
+       drawregion(0, 0, term.col, term.row);
+       xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
+                       term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
+       term.ocx = cx, term.ocy = term.c.y;
+       xfinishdraw();
+}
+
 void
 redraw(void)
 {