]> git.armaanb.net Git - st.git/blobdiff - x.c
fix memory leak in xloadcols()
[st.git] / x.c
diff --git a/x.c b/x.c
index d0acfee59b93daa1d8da851ad56a9666b8568bc3..042242181ecb2ca3e8efb82be3f9dd94968d78aa 100644 (file)
--- a/x.c
+++ b/x.c
@@ -1,5 +1,6 @@
 /* See LICENSE for license details. */
 #include <errno.h>
+#include <math.h>
 #include <limits.h>
 #include <locale.h>
 #include <signal.h>
@@ -149,8 +150,8 @@ static void xunloadfont(Font *);
 static void xunloadfonts(void);
 static void xsetenv(void);
 static void xseturgency(int);
-static int x2col(int);
-static int y2row(int);
+static int evcol(XEvent *);
+static int evrow(XEvent *);
 
 static void expose(XEvent *);
 static void visibility(XEvent *);
@@ -244,8 +245,8 @@ clipcopy(const Arg *dummy)
 {
        Atom clipboard;
 
-       if (xsel.clipboard != NULL)
-               free(xsel.clipboard);
+       free(xsel.clipboard);
+       xsel.clipboard = NULL;
 
        if (xsel.primary != NULL) {
                xsel.clipboard = xstrdup(xsel.primary);
@@ -308,17 +309,17 @@ zoomreset(const Arg *arg)
 }
 
 int
-x2col(int x)
+evcol(XEvent *e)
 {
-       x -= borderpx;
+       int x = e->xbutton.x - borderpx;
        LIMIT(x, 0, win.tw - 1);
        return x / win.cw;
 }
 
 int
-y2row(int y)
+evrow(XEvent *e)
 {
-       y -= borderpx;
+       int y = e->xbutton.y - borderpx;
        LIMIT(y, 0, win.th - 1);
        return y / win.ch;
 }
@@ -335,7 +336,7 @@ mousesel(XEvent *e, int done)
                        break;
                }
        }
-       selextend(x2col(e->xbutton.x), y2row(e->xbutton.y), seltype, done);
+       selextend(evcol(e), evrow(e), seltype, done);
        if (done)
                setsel(getsel(), e->xbutton.time);
 }
@@ -343,9 +344,8 @@ mousesel(XEvent *e, int done)
 void
 mousereport(XEvent *e)
 {
-       int x = x2col(e->xbutton.x), y = y2row(e->xbutton.y),
-           button = e->xbutton.button, state = e->xbutton.state,
-           len;
+       int len, x = evcol(e), y = evrow(e),
+           button = e->xbutton.button, state = e->xbutton.state;
        char buf[40];
        static int ox, oy;
 
@@ -440,7 +440,7 @@ bpress(XEvent *e)
                xsel.tclick2 = xsel.tclick1;
                xsel.tclick1 = now;
 
-               selstart(x2col(e->xbutton.x), y2row(e->xbutton.y), snap);
+               selstart(evcol(e), evrow(e), snap);
        }
 }
 
@@ -464,18 +464,16 @@ selnotify(XEvent *e)
        ulong nitems, ofs, rem;
        int format;
        uchar *data, *last, *repl;
-       Atom type, incratom, property;
+       Atom type, incratom, property = None;
 
        incratom = XInternAtom(xw.dpy, "INCR", 0);
 
        ofs = 0;
-       if (e->type == SelectionNotify) {
+       if (e->type == SelectionNotify)
                property = e->xselection.property;
-       } else if(e->type == PropertyNotify) {
+       else if (e->type == PropertyNotify)
                property = e->xproperty.atom;
-       } else {
-               return;
-       }
+
        if (property == None)
                return;
 
@@ -620,12 +618,15 @@ selrequest(XEvent *e)
 void
 setsel(char *str, Time t)
 {
+       if (!str)
+               return;
+
        free(xsel.primary);
        xsel.primary = str;
 
        XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t);
        if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win)
-               selclear_(NULL);
+               selclear();
 }
 
 void
@@ -671,6 +672,8 @@ cresize(int width, int height)
 
        col = (win.w - 2 * borderpx) / win.cw;
        row = (win.h - 2 * borderpx) / win.ch;
+       col = MAX(1, col);
+       row = MAX(1, row);
 
        tresize(col, row);
        xresize(col, row);
@@ -680,8 +683,8 @@ cresize(int width, int height)
 void
 xresize(int col, int row)
 {
-       win.tw = MAX(1, col * win.cw);
-       win.th = MAX(1, row * win.ch);
+       win.tw = col * win.cw;
+       win.th = row * win.ch;
 
        XFreePixmap(xw.dpy, xw.buf);
        xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
@@ -730,20 +733,20 @@ xloadcols(void)
        static int loaded;
        Color *cp;
 
-       dc.collen = MAX(LEN(colorname), 256);
-       dc.col = xmalloc(dc.collen * sizeof(Color));
-
        if (loaded) {
                for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp)
                        XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
+       } else {
+               dc.collen = MAX(LEN(colorname), 256);
+               dc.col = xmalloc(dc.collen * sizeof(Color));
        }
 
        for (i = 0; i < dc.collen; i++)
                if (!xloadcolor(i, NULL, &dc.col[i])) {
                        if (colorname[i])
-                               die("Could not allocate color '%s'\n", colorname[i]);
+                               die("could not allocate color '%s'\n", colorname[i]);
                        else
-                               die("Could not allocate color %d\n", i);
+                               die("could not allocate color %d\n", i);
                }
        loaded = 1;
 }
@@ -783,19 +786,21 @@ xhints(void)
        XClassHint class = {opt_name ? opt_name : termname,
                            opt_class ? opt_class : termname};
        XWMHints wm = {.flags = InputHint, .input = 1};
-       XSizeHints *sizeh = NULL;
+       XSizeHints *sizeh;
 
        sizeh = XAllocSizeHints();
 
-       sizeh->flags = PSize | PResizeInc | PBaseSize;
+       sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize;
        sizeh->height = win.h;
        sizeh->width = win.w;
        sizeh->height_inc = win.ch;
        sizeh->width_inc = win.cw;
        sizeh->base_height = 2 * borderpx;
        sizeh->base_width = 2 * borderpx;
+       sizeh->min_height = win.ch + 2 * borderpx;
+       sizeh->min_width = win.cw + 2 * borderpx;
        if (xw.isfixed) {
-               sizeh->flags |= PMaxSize | PMinSize;
+               sizeh->flags |= PMaxSize;
                sizeh->min_width = sizeh->max_width = win.w;
                sizeh->min_height = sizeh->max_height = win.h;
        }
@@ -868,7 +873,7 @@ xloadfont(Font *f, FcPattern *pattern)
                if ((XftPatternGetInteger(f->match->pattern, "slant", 0,
                    &haveattr) != XftResultMatch) || haveattr < wantattr) {
                        f->badslant = 1;
-                       fputs("st: font slant does not match\n", stderr);
+                       fputs("font slant does not match\n", stderr);
                }
        }
 
@@ -877,7 +882,7 @@ xloadfont(Font *f, FcPattern *pattern)
                if ((XftPatternGetInteger(f->match->pattern, "weight", 0,
                    &haveattr) != XftResultMatch) || haveattr != wantattr) {
                        f->badweight = 1;
-                       fputs("st: font weight does not match\n", stderr);
+                       fputs("font weight does not match\n", stderr);
                }
        }
 
@@ -904,16 +909,14 @@ xloadfonts(char *fontstr, double fontsize)
 {
        FcPattern *pattern;
        double fontval;
-       float ceilf(float);
 
-       if (fontstr[0] == '-') {
+       if (fontstr[0] == '-')
                pattern = XftXlfdParse(fontstr, False, False);
-       } else {
+       else
                pattern = FcNameParse((FcChar8 *)fontstr);
-       }
 
        if (!pattern)
-               die("st: can't open font %s\n", fontstr);
+               die("can't open font %s\n", fontstr);
 
        if (fontsize > 1) {
                FcPatternDel(pattern, FC_PIXEL_SIZE);
@@ -939,7 +942,7 @@ xloadfonts(char *fontstr, double fontsize)
        }
 
        if (xloadfont(&dc.font, pattern))
-               die("st: can't open font %s\n", fontstr);
+               die("can't open font %s\n", fontstr);
 
        if (usedfontsize < 0) {
                FcPatternGetDouble(dc.font.match->pattern,
@@ -956,17 +959,17 @@ xloadfonts(char *fontstr, double fontsize)
        FcPatternDel(pattern, FC_SLANT);
        FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
        if (xloadfont(&dc.ifont, pattern))
-               die("st: can't open font %s\n", fontstr);
+               die("can't open font %s\n", fontstr);
 
        FcPatternDel(pattern, FC_WEIGHT);
        FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
        if (xloadfont(&dc.ibfont, pattern))
-               die("st: can't open font %s\n", fontstr);
+               die("can't open font %s\n", fontstr);
 
        FcPatternDel(pattern, FC_SLANT);
        FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
        if (xloadfont(&dc.bfont, pattern))
-               die("st: can't open font %s\n", fontstr);
+               die("can't open font %s\n", fontstr);
 
        FcPatternDestroy(pattern);
 }
@@ -1003,13 +1006,13 @@ xinit(int cols, int rows)
        XColor xmousefg, xmousebg;
 
        if (!(xw.dpy = XOpenDisplay(NULL)))
-               die("Can't open display\n");
+               die("can't open display\n");
        xw.scr = XDefaultScreen(xw.dpy);
        xw.vis = XDefaultVisual(xw.dpy, xw.scr);
 
        /* font */
        if (!FcInit())
-               die("Could not init fontconfig.\n");
+               die("could not init fontconfig.\n");
 
        usedfont = (opt_font == NULL)? font : opt_font;
        xloadfonts(usedfont, 0);
@@ -1407,12 +1410,13 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
                og.mode ^= ATTR_REVERSE;
        xdrawglyph(og, ox, oy);
 
+       if (IS_SET(MODE_HIDE))
+               return;
+
        /*
         * Select the right color for the right mode.
         */
        g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE;
-       g.fg = defaultbg;
-       g.bg = defaultcs;
 
        if (IS_SET(MODE_REVERSE)) {
                g.mode |= ATTR_REVERSE;
@@ -1426,17 +1430,15 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
                }
        } else {
                if (selected(cx, cy)) {
-                       drawcol = dc.col[defaultrcs];
                        g.fg = defaultfg;
                        g.bg = defaultrcs;
                } else {
-                       drawcol = dc.col[defaultcs];
+                       g.fg = defaultbg;
+                       g.bg = defaultcs;
                }
+               drawcol = dc.col[g.bg];
        }
 
-       if (IS_SET(MODE_HIDE))
-               return;
-
        /* draw the new one */
        if (IS_SET(MODE_FOCUSED)) {
                switch (win.cursor) {
@@ -1496,7 +1498,7 @@ void
 xsettitle(char *p)
 {
        XTextProperty prop;
-       DEFAULT(p, "st");
+       DEFAULT(p, opt_title);
 
        Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
                        &prop);
@@ -1926,19 +1928,19 @@ main(int argc, char *argv[])
                opt_embed = EARGF(usage());
                break;
        case 'v':
-               die("%s " VERSION " (c) 2010-2016 st engineers\n", argv0);
+               die("%s " VERSION "\n", argv0);
                break;
        default:
                usage();
        } ARGEND;
 
 run:
-       if (argc > 0) {
-               /* eat all remaining arguments */
+       if (argc > 0) /* eat all remaining arguments */
                opt_cmd = argv;
-               if (!opt_title && !opt_line)
-                       opt_title = basename(xstrdup(argv[0]));
-       }
+
+       if (!opt_title)
+               opt_title = (opt_line || !opt_cmd) ? "st" : opt_cmd[0];
+
        setlocale(LC_CTYPE, "");
        XSetLocaleModifiers("");
        cols = MAX(cols, 1);