Unboolify st
[st.git] / st.c
diff --git a/st.c b/st.c
index 0c6b9c3..b052b2b 100644 (file)
--- a/st.c
+++ b/st.c
@@ -6,7 +6,6 @@
 #include <locale.h>
 #include <pwd.h>
 #include <stdarg.h>
-#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -71,7 +70,7 @@ char *argv0;
 #define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177')
 #define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
 #define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
-#define ISDELIM(u) (BETWEEN(u, 0, 127) && strchr(worddelimiters, u) != NULL)
+#define ISDELIM(u) (utf8strchr(worddelimiters, u) != NULL)
 #define LIMIT(x, a, b)    (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
 #define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg)
 #define IS_SET(flag) ((term.mode & (flag)) != 0)
@@ -191,8 +190,8 @@ typedef XftColor Color;
 typedef struct {
        Rune u;           /* character code */
        ushort mode;      /* attribute flags */
-       ushort fg;        /* foreground  */
-       ushort bg;        /* background  */
+       uint32_t fg;      /* foreground  */
+       uint32_t bg;      /* background  */
 } Glyph;
 
 typedef Glyph *Line;
@@ -231,7 +230,7 @@ typedef struct {
        int col;      /* nb col */
        Line *line;   /* screen */
        Line *alt;    /* alternate screen */
-       bool *dirty;  /* dirtyness of lines */
+       int *dirty;  /* dirtyness of lines */
        XftGlyphFontSpec *specbuf; /* font spec buffer used for rendering */
        TCursor c;    /* cursor */
        int top;      /* top    scroll limit */
@@ -241,8 +240,8 @@ typedef struct {
        char trantbl[4]; /* charset table translation */
        int charset;  /* current charset */
        int icharset; /* selected charset for sequence */
-       bool numlock; /* lock numbers in keyboard */
-       bool *tabs;
+       int numlock; /* lock numbers in keyboard */
+       int *tabs;
 } Term;
 
 /* Purely graphic info */
@@ -258,7 +257,7 @@ typedef struct {
        Visual *vis;
        XSetWindowAttributes attrs;
        int scr;
-       bool isfixed; /* is fixed geometry? */
+       int isfixed; /* is fixed geometry? */
        int l, t; /* left and top offset */
        int gm; /* geometry mask */
        int tw, th; /* tty width and height */
@@ -302,7 +301,7 @@ typedef struct {
 
        char *primary, *clipboard;
        Atom xtarget;
-       bool alt;
+       int alt;
        struct timespec tclick1;
        struct timespec tclick2;
 } Selection;
@@ -403,14 +402,14 @@ static void tsetscroll(int, int);
 static void tswapscreen(void);
 static void tsetdirt(int, int);
 static void tsetdirtattr(int);
-static void tsetmode(bool, bool, int *, int);
+static void tsetmode(int, int, int *, int);
 static void tfulldirt(void);
 static void techo(Rune);
 static void tcontrolcode(uchar );
 static void tdectest(char );
 static int32_t tdefcolor(int *, int *, int);
 static void tdeftran(char);
-static inline bool match(uint, uint);
+static inline int match(uint, uint);
 static void ttynew(void);
 static void ttyread(void);
 static void ttyresize(void);
@@ -459,7 +458,7 @@ static void selrequest(XEvent *);
 
 static void selinit(void);
 static void selnormalize(void);
-static inline bool selected(int, int);
+static inline int selected(int, int);
 static char *getsel(void);
 static void selcopy(Time);
 static void selscroll(int, int);
@@ -473,6 +472,7 @@ static size_t utf8decode(char *, Rune *, size_t);
 static Rune utf8decodebyte(char, size_t *);
 static size_t utf8encode(Rune, char *);
 static char utf8encodebyte(Rune, size_t);
+static char *utf8strchr(char *s, Rune u);
 static size_t utf8validate(Rune *, size_t);
 
 static ssize_t xwrite(int, const char *, size_t);
@@ -512,7 +512,7 @@ static STREscape strescseq;
 static int cmdfd;
 static pid_t pid;
 static Selection sel;
-static int iofd = STDOUT_FILENO;
+static int iofd = 1;
 static char **opt_cmd = NULL;
 static char *opt_io = NULL;
 static char *opt_title = NULL;
@@ -640,6 +640,21 @@ utf8encodebyte(Rune u, size_t i) {
        return utfbyte[i] | (u & ~utfmask[i]);
 }
 
+char *
+utf8strchr(char *s, Rune u) {
+       Rune r;
+       size_t i, j, len;
+
+       len = strlen(s);
+       for(i = 0, j = 0; i < len; i += j) {
+               if(!(j = utf8decode(&s[i], &r, len - i)))
+                       break;
+               if(r == u)
+                       return &(s[i]);
+       }
+       return NULL;
+}
+
 size_t
 utf8validate(Rune *u, size_t i) {
        if(!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
@@ -718,10 +733,10 @@ selnormalize(void) {
                sel.ne.x = term.col - 1;
 }
 
-bool
+int
 selected(int x, int y) {
        if(sel.mode == SEL_EMPTY)
-               return false;
+               return 0;
 
        if(sel.type == SEL_RECTANGULAR)
                return BETWEEN(y, sel.nb.y, sel.ne.y)
@@ -735,7 +750,7 @@ selected(int x, int y) {
 void
 selsnap(int *x, int *y, int direction) {
        int newx, newy, xt, yt;
-       bool delim, prevdelim;
+       int delim, prevdelim;
        Glyph *gp, *prevgp;
 
        switch(sel.snap) {
@@ -1127,7 +1142,7 @@ selrequest(XEvent *e) {
        }
 
        /* all done, send a notification to the listener */
-       if(!XSendEvent(xsre->display, xsre->requestor, True, 0, (XEvent *) &xev))
+       if(!XSendEvent(xsre->display, xsre->requestor, 1, 0, (XEvent *) &xev))
                fprintf(stderr, "Error sending SelectionNotify event\n");
 }
 
@@ -1191,7 +1206,7 @@ die(const char *errstr, ...) {
        va_start(ap, errstr);
        vfprintf(stderr, errstr, ap);
        va_end(ap);
-       exit(EXIT_FAILURE);
+       exit(1);
 }
 
 void
@@ -1240,12 +1255,12 @@ execsh(void) {
        signal(SIGALRM, SIG_DFL);
 
        execvp(prog, args);
-       _exit(EXIT_FAILURE);
+       _exit(1);
 }
 
 void
 sigchld(int a) {
-       int stat, ret;
+       int stat;
        pid_t p;
 
        if((p = waitpid(pid, &stat, WNOHANG)) < 0)
@@ -1254,10 +1269,9 @@ sigchld(int a) {
        if(pid != p)
                return;
 
-       ret = WIFEXITED(stat) ? WEXITSTATUS(stat) : EXIT_FAILURE;
-       if (ret != EXIT_SUCCESS)
+       if (!WIFEXITED(stat) || WEXITSTATUS(stat))
                die("child finished with error '%d'\n", stat);
-       exit(EXIT_SUCCESS);
+       exit(0);
 }
 
 
@@ -1293,8 +1307,7 @@ ttynew(void) {
        if(opt_io) {
                term.mode |= MODE_PRINT;
                iofd = (!strcmp(opt_io, "-")) ?
-                         STDOUT_FILENO :
-                         open(opt_io, O_WRONLY | O_CREAT, 0666);
+                         1 : open(opt_io, O_WRONLY | O_CREAT, 0666);
                if(iofd < 0) {
                        fprintf(stderr, "Error opening %s:%s\n",
                                opt_io, strerror(errno));
@@ -1304,7 +1317,7 @@ ttynew(void) {
        if (opt_line) {
                if((cmdfd = open(opt_line, O_RDWR)) < 0)
                        die("open line failed: %s\n", strerror(errno));
-               close(STDIN_FILENO);
+               close(0);
                dup(cmdfd);
                stty();
                return;
@@ -1321,9 +1334,9 @@ ttynew(void) {
        case 0:
                close(iofd);
                setsid(); /* create a new process group */
-               dup2(s, STDIN_FILENO);
-               dup2(s, STDOUT_FILENO);
-               dup2(s, STDERR_FILENO);
+               dup2(s, 0);
+               dup2(s, 1);
+               dup2(s, 2);
                if(ioctl(s, TIOCSCTTY, NULL) < 0)
                        die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
                close(s);
@@ -1443,7 +1456,7 @@ tfulldirt(void) {
 void
 tcursor(int mode) {
        static TCursor c[2];
-       bool alt = IS_SET(MODE_ALTSCREEN);
+       int alt = IS_SET(MODE_ALTSCREEN);
 
        if(mode == CURSOR_SAVE) {
                c[alt] = term.c;
@@ -1902,9 +1915,9 @@ tsetscroll(int t, int b) {
 }
 
 void
-tsetmode(bool priv, bool set, int *args, int narg) {
+tsetmode(int priv, int set, int *args, int narg) {
        int *lim, mode;
-       bool alt;
+       int alt;
 
        for(lim = args + narg; args < lim; ++args) {
                if(priv) {
@@ -2670,7 +2683,7 @@ eschandle(uchar ascii) {
 void
 tputc(Rune u) {
        char c[UTF_SIZ];
-       bool control;
+       int control;
        int width, len;
        Glyph *gp;
 
@@ -2794,7 +2807,7 @@ tresize(int col, int row) {
        int i;
        int minrow = MIN(row, term.row);
        int mincol = MIN(col, term.col);
-       bool *bp;
+       int *bp;
        TCursor c;
 
        if(col < 1 || row < 1) {
@@ -2890,7 +2903,7 @@ sixd_to_16bit(int x) {
        return x == 0 ? 0 : 0x3737 + 0x2828 * x;
 }
 
-bool
+int
 xloadcolor(int i, const char *name, Color *ncolor) {
        XRenderColor color = { .alpha = 0xffff };
 
@@ -2915,7 +2928,7 @@ xloadcolor(int i, const char *name, Color *ncolor) {
 void
 xloadcols(void) {
        int i;
-       static bool loaded;
+       static int loaded;
        Color *cp;
 
        if(loaded) {
@@ -2930,7 +2943,7 @@ xloadcols(void) {
                        else
                                die("Could not allocate color %d\n", i);
                }
-       loaded = true;
+       loaded = 1;
 }
 
 int
@@ -2984,7 +2997,7 @@ xhints(void) {
        sizeh->width_inc = xw.cw;
        sizeh->base_height = 2 * borderpx;
        sizeh->base_width = 2 * borderpx;
-       if(xw.isfixed == True) {
+       if(xw.isfixed) {
                sizeh->flags |= PMaxSize | PMinSize;
                sizeh->min_width = sizeh->max_width = xw.w;
                sizeh->min_height = sizeh->max_height = xw.h;
@@ -3045,7 +3058,6 @@ xloadfont(Font *f, FcPattern *pattern) {
 void
 xloadfonts(char *fontstr, double fontsize) {
        FcPattern *pattern;
-       FcResult r_sz, r_psz;
        double fontval;
        float ceilf(float);
 
@@ -3064,11 +3076,11 @@ xloadfonts(char *fontstr, double fontsize) {
                FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)fontsize);
                usedfontsize = fontsize;
        } else {
-               r_psz = FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval);
-               r_sz = FcPatternGetDouble(pattern, FC_SIZE, 0, &fontval);
-               if(r_psz == FcResultMatch) {
+               if(FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) ==
+                               FcResultMatch) {
                        usedfontsize = fontval;
-               } else if(r_sz == FcResultMatch) {
+               } else if(FcPatternGetDouble(pattern, FC_SIZE, 0, &fontval) ==
+                               FcResultMatch) {
                        usedfontsize = -1;
                } else {
                        /*
@@ -3141,14 +3153,14 @@ void
 xzoom(const Arg *arg) {
        Arg larg;
 
-       larg.i = usedfontsize + arg->i;
+       larg.f = usedfontsize + arg->f;
        xzoomabs(&larg);
 }
 
 void
 xzoomabs(const Arg *arg) {
        xunloadfonts();
-       xloadfonts(usedfont, arg->i);
+       xloadfonts(usedfont, arg->f);
        cresize(0, 0);
        redraw();
        xhints();
@@ -3159,7 +3171,7 @@ xzoomreset(const Arg *arg) {
        Arg larg;
 
        if(defaultfontsize > 0) {
-               larg.i = defaultfontsize;
+               larg.f = defaultfontsize;
                xzoomabs(&larg);
        }
 }
@@ -3336,7 +3348,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
                if(f >= frclen) {
                        if(!font->set)
                                font->set = FcFontSort(0, font->pattern,
-                                                      FcTrue, 0, &fcres);
+                                                      1, 0, &fcres);
                        fcsets[0] = font->set;
 
                        /*
@@ -3352,8 +3364,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
                        FcCharSetAddChar(fccharset, rune);
                        FcPatternAddCharSet(fcpattern, FC_CHARSET,
                                        fccharset);
-                       FcPatternAddBool(fcpattern, FC_SCALABLE,
-                                       FcTrue);
+                       FcPatternAddBool(fcpattern, FC_SCALABLE, 1);
 
                        FcConfigSubstitute(0, fcpattern,
                                        FcMatchPattern);
@@ -3651,7 +3662,7 @@ drawregion(int x1, int y1, int x2, int y2) {
        int i, x, y, ox, numspecs;
        Glyph base, new;
        XftGlyphFontSpec* specs;
-       bool ena_sel = sel.ob.x != -1 && sel.alt == IS_SET(MODE_ALTSCREEN);
+       int ena_sel = sel.ob.x != -1 && sel.alt == IS_SET(MODE_ALTSCREEN);
 
        if(!(xw.state & WIN_VISIBLE))
                return;
@@ -3744,7 +3755,7 @@ focus(XEvent *ev) {
        }
 }
 
-bool
+int
 match(uint mask, uint state) {
        return mask == XK_ANY_MOD || mask == (state & ~ignoremod);
 }
@@ -3856,7 +3867,7 @@ cmessage(XEvent *e) {
        } else if(e->xclient.data.l[0] == xw.wmdeletewin) {
                /* Send SIGHUP to shell */
                kill(pid, SIGHUP);
-               exit(EXIT_SUCCESS);
+               exit(0);
        }
 }
 
@@ -3897,6 +3908,13 @@ run(void) {
        /* Waiting for window mapping */
        do {
                XNextEvent(xw.dpy, &ev);
+               /*
+                * XFilterEvent is required to be called after you using XOpenIM,
+                * this is not unnecessary.It does not only filter the key event,
+                * but some clientmessage for input method as well.
+                */
+               if(XFilterEvent(&ev, None))
+                       continue;
                if(ev.type == ConfigureNotify) {
                        w = ev.xconfigure.width;
                        h = ev.xconfigure.height;
@@ -4005,7 +4023,7 @@ main(int argc, char *argv[]) {
 
        ARGBEGIN {
        case 'a':
-               allowaltscreen = false;
+               allowaltscreen = 0;
                break;
        case 'c':
                opt_class = EARGF(usage());
@@ -4022,7 +4040,7 @@ main(int argc, char *argv[]) {
                                &xw.l, &xw.t, &cols, &rows);
                break;
        case 'i':
-               xw.isfixed = True;
+               xw.isfixed = 1;
                break;
        case 'o':
                opt_io = EARGF(usage());