X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=st.c;h=ced72ff8ba4b32193726d9084422133569712910;hb=ebb6e03201ce0e5a00be7cff2e365ad3d6cb7195;hp=ee8dc94082e6f14c3d077e5c7f65fae7e4e4186f;hpb=4435e0ee6791136e641d58ce6cf00f8665fe3065;p=st.git diff --git a/st.c b/st.c index ee8dc94..ced72ff 100644 --- a/st.c +++ b/st.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,7 @@ char *argv0; #define XEMBED_FOCUS_OUT 5 /* Arbitrary sizes */ +#define UTF_INVALID 0xFFFD #define UTF_SIZ 4 #define ESC_BUF_SIZ (128*UTF_SIZ) #define ESC_ARG_SIZ 16 @@ -133,6 +135,7 @@ enum term_mode { MODE_MOUSEX10 = 131072, MODE_MOUSEMANY = 262144, MODE_BRCKTPASTE = 524288, + MODE_PRINT = 1048576, MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\ |MODE_MOUSEMANY, }; @@ -180,8 +183,8 @@ typedef unsigned short ushort; typedef struct { char c[UTF_SIZ]; /* character code */ ushort mode; /* attribute flags */ - ulong fg; /* foreground */ - ulong bg; /* background */ + uint32_t fg; /* foreground */ + uint32_t bg; /* background */ } Glyph; typedef Glyph *Line; @@ -239,7 +242,7 @@ typedef struct { Colourmap cmap; Window win; Drawable buf; - Atom xembed, wmdeletewin, netwmname; + Atom xembed, wmdeletewin, netwmname, netwmpid; XIM xim; XIC xic; Draw draw; @@ -312,6 +315,9 @@ static void clippaste(const Arg *); static void numlock(const Arg *); static void selpaste(const Arg *); static void xzoom(const Arg *); +static void printsel(const Arg *); +static void printscreen(const Arg *) ; +static void toggleprinter(const Arg *); /* Config.h for applying patches and the configuration. */ #include "config.h" @@ -354,6 +360,10 @@ static void strparse(void); static void strreset(void); static int tattrset(int); +static void tprinter(char *s, size_t len); +static void tdumpsel(void); +static void tdumpline(int); +static void tdump(void); static void tclearregion(int, int, int, int); static void tcursor(int); static void tdeletechar(int); @@ -379,7 +389,7 @@ static void tsetdirtattr(int); static void tsetmode(bool, bool, int *, int); static void tfulldirt(void); static void techo(char *, int); -static long tdefcolor(int *, int *, int); +static int32_t tdefcolor(int *, int *, int); static void tselcs(void); static void tdeftran(char); static inline bool match(uint, uint); @@ -397,7 +407,7 @@ static void xinit(void); static void xloadcols(void); static int xsetcolorname(int, const char *); static int xloadfont(Font *, FcPattern *); -static void xloadfonts(char *, int); +static void xloadfonts(char *, double); static int xloadfontset(Font *); static void xsettitle(char *); static void xresettitle(void); @@ -428,18 +438,22 @@ static void selrequest(XEvent *); static void selinit(void); static void selsort(void); static inline bool selected(int, int); +static char *getsel(void); static void selcopy(void); static void selscroll(int, int); static void selsnap(int, int *, int *, int); -static int utf8decode(char *, long *); -static int utf8encode(long *, char *); -static int utf8size(char *); -static int isfullutf8(char *, int); +static size_t utf8decode(char *, long *, size_t); +static long utf8decodebyte(char, size_t *); +static size_t utf8encode(long, char *, size_t); +static char utf8encodebyte(long, size_t); +static size_t utf8len(char *); +static size_t utf8validate(long *, size_t); static ssize_t xwrite(int, char *, size_t); static void *xmalloc(size_t); static void *xrealloc(void *, size_t); +static char *xstrdup(char *s); static void (*handler[LASTEvent])(XEvent *) = { [KeyPress] = kpress, @@ -467,7 +481,7 @@ static STREscape strescseq; static int cmdfd; static pid_t pid; static Selection sel; -static int iofd = -1; +static int iofd = STDOUT_FILENO; static char **opt_cmd = NULL; static char *opt_io = NULL; static char *opt_title = NULL; @@ -477,7 +491,12 @@ static char *opt_font = NULL; static int oldbutton = 3; /* button event on startup: 3 = release */ static char *usedfont = NULL; -static int usedfontsize = 0; +static double usedfontsize = 0; + +static uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; +static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; +static long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; +static long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; /* Font Ring Cache */ enum { @@ -528,128 +547,79 @@ xrealloc(void *p, size_t len) { return p; } -int -utf8decode(char *s, long *u) { - uchar c; - int i, n, rtn; - - rtn = 1; - c = *s; - if(~c & 0x80) { /* 0xxxxxxx */ - *u = c; - return rtn; - } else if((c & 0xE0) == 0xC0) { /* 110xxxxx */ - *u = c & 0x1F; - n = 1; - } else if((c & 0xF0) == 0xE0) { /* 1110xxxx */ - *u = c & 0x0F; - n = 2; - } else if((c & 0xF8) == 0xF0) { /* 11110xxx */ - *u = c & 0x07; - n = 3; - } else { - goto invalid; - } - - for(i = n, ++s; i > 0; --i, ++rtn, ++s) { - c = *s; - if((c & 0xC0) != 0x80) /* 10xxxxxx */ - goto invalid; - *u <<= 6; - *u |= c & 0x3F; - } - - if((n == 1 && *u < 0x80) || - (n == 2 && *u < 0x800) || - (n == 3 && *u < 0x10000) || - (*u >= 0xD800 && *u <= 0xDFFF)) { - goto invalid; - } +char * +xstrdup(char *s) { + char *p = strdup(s); - return rtn; -invalid: - *u = 0xFFFD; + if (!p) + die("Out of memory\n"); - return rtn; + return p; } -int -utf8encode(long *u, char *s) { - uchar *sp; - ulong uc; - int i, n; - - sp = (uchar *)s; - uc = *u; - if(uc < 0x80) { - *sp = uc; /* 0xxxxxxx */ +size_t +utf8decode(char *c, long *u, size_t clen) { + size_t i, j, len, type; + long udecoded; + + *u = UTF_INVALID; + if(!clen) + return 0; + udecoded = utf8decodebyte(c[0], &len); + if(!BETWEEN(len, 1, UTF_SIZ)) return 1; - } else if(*u < 0x800) { - *sp = (uc >> 6) | 0xC0; /* 110xxxxx */ - n = 1; - } else if(uc < 0x10000) { - *sp = (uc >> 12) | 0xE0; /* 1110xxxx */ - n = 2; - } else if(uc <= 0x10FFFF) { - *sp = (uc >> 18) | 0xF0; /* 11110xxx */ - n = 3; - } else { - goto invalid; + for(i = 1, j = 1; i < clen && j < len; ++i, ++j) { + udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); + if(type != 0) + return j; } + if(j < len) + return 0; + *u = udecoded; + utf8validate(u, len); + return len; +} - for(i=n,++sp; i>0; --i,++sp) - *sp = ((uc >> 6*(i-1)) & 0x3F) | 0x80; /* 10xxxxxx */ - - return n+1; -invalid: - /* U+FFFD */ - *s++ = '\xEF'; - *s++ = '\xBF'; - *s = '\xBD'; - - return 3; +long +utf8decodebyte(char c, size_t *i) { + for(*i = 0; *i < LEN(utfmask); ++(*i)) + if(((uchar)c & utfmask[*i]) == utfbyte[*i]) + return (uchar)c & ~utfmask[*i]; + return 0; } -/* use this if your buffer is less than UTF_SIZ, it returns 1 if you can decode - UTF-8 otherwise return 0 */ -int -isfullutf8(char *s, int b) { - uchar *c1, *c2, *c3; +size_t +utf8encode(long u, char *c, size_t clen) { + size_t len, i; - c1 = (uchar *)s; - c2 = (uchar *)++s; - c3 = (uchar *)++s; - if(b < 1) { + len = utf8validate(&u, 0); + if(clen < len) return 0; - } else if((*c1 & 0xE0) == 0xC0 && b == 1) { - return 0; - } else if((*c1 & 0xF0) == 0xE0 && - ((b == 1) || - ((b == 2) && (*c2 & 0xC0) == 0x80))) { - return 0; - } else if((*c1 & 0xF8) == 0xF0 && - ((b == 1) || - ((b == 2) && (*c2 & 0xC0) == 0x80) || - ((b == 3) && (*c2 & 0xC0) == 0x80 && (*c3 & 0xC0) == 0x80))) { - return 0; - } else { - return 1; + for(i = len - 1; i != 0; --i) { + c[i] = utf8encodebyte(u, 0); + u >>= 6; } + c[0] = utf8encodebyte(u, len); + return len; } -int -utf8size(char *s) { - uchar c = *s; +char +utf8encodebyte(long u, size_t i) { + return utfbyte[i] | (u & ~utfmask[i]); +} - if(~c & 0x80) { - return 1; - } else if((c & 0xE0) == 0xC0) { - return 2; - } else if((c & 0xF0) == 0xE0) { - return 3; - } else { - return 4; - } +size_t +utf8len(char *c) { + return utf8decode(c, &(long){0}, UTF_SIZ); +} + +size_t +utf8validate(long *u, size_t i) { + if(!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) + *u = UTF_INVALID; + for(i = 1; *u > utfmax[i]; ++i) + ; + return i; } static void @@ -937,8 +907,8 @@ bpress(XEvent *e) { } } -void -selcopy(void) { +char * +getsel(void) { char *str, *ptr; int x, y, bufsize, size, i, ex; Glyph *gp, *last; @@ -952,17 +922,18 @@ selcopy(void) { /* append every set & selected glyph to the selection */ for(y = sel.nb.y; y < sel.ne.y + 1; y++) { gp = &term.line[y][0]; - last = gp + term.col; + last = &gp[term.col-1]; - while(--last >= gp && !(selected(last - gp, y) && \ - strcmp(last->c, " ") != 0)) - /* nothing */; + while(last >= gp && !(selected(last - gp, y) && + strcmp(last->c, " ") != 0)) { + --last; + } for(x = 0; gp <= last; x++, ++gp) { if(!selected(x, y) || (gp->mode & ATTR_WDUMMY)) continue; - size = utf8size(gp->c); + size = utf8len(gp->c); memcpy(ptr, gp->c, size); ptr += size; } @@ -996,7 +967,12 @@ selcopy(void) { } *ptr = 0; } - xsetsel(str); + return str; +} + +void +selcopy(void) { + xsetsel(getsel()); } void @@ -1243,6 +1219,7 @@ ttynew(void) { cmdfd = m; signal(SIGCHLD, sigchld); if(opt_io) { + term.mode |= MODE_PRINT; iofd = (!strcmp(opt_io, "-")) ? STDOUT_FILENO : open(opt_io, O_WRONLY | O_CREAT, 0666); @@ -1270,7 +1247,7 @@ ttyread(void) { char *ptr; char s[UTF_SIZ]; int charsize; /* size of utf8 char in bytes */ - long utf8c; + long unicodep; int ret; /* append read bytes to unprocessed bytes */ @@ -1280,9 +1257,8 @@ ttyread(void) { /* process every complete utf8 char */ buflen += ret; ptr = buf; - while(buflen >= UTF_SIZ || isfullutf8(ptr,buflen)) { - charsize = utf8decode(ptr, &utf8c); - utf8encode(&utf8c, s); + while((charsize = utf8decode(ptr, &unicodep, buflen))) { + utf8encode(unicodep, s, UTF_SIZ); tputc(s, charsize); ptr += charsize; buflen -= charsize; @@ -1666,9 +1642,9 @@ tdeleteline(int n) { tscrollup(term.c.y, n); } -long +int32_t tdefcolor(int *attr, int *npar, int l) { - long idx = -1; + int32_t idx = -1; uint r, g, b; switch (attr[*npar + 1]) { @@ -1717,7 +1693,7 @@ tdefcolor(int *attr, int *npar, int l) { void tsetattr(int *attr, int l) { int i; - long idx; + int32_t idx; for(i = 0; i < l; i++) { switch(attr[i]) { @@ -1966,6 +1942,25 @@ csihandle(void) { DEFAULT(csiescseq.arg[0], 1); tmoveto(term.c.x, term.c.y+csiescseq.arg[0]); break; + case 'i': /* MC -- Media Copy */ + switch(csiescseq.arg[0]) { + case 0: + tdump(); + break; + case 1: + tdumpline(term.c.y); + break; + case 2: + tdumpsel(); + break; + case 4: + term.mode &= ~MODE_PRINT; + break; + case 5: + term.mode |= MODE_PRINT; + break; + } + break; case 'c': /* DA -- Device Attributes */ if(csiescseq.arg[0] == 0) ttywrite(VT102ID, sizeof(VT102ID) - 1); @@ -2151,20 +2146,21 @@ csireset(void) { void strhandle(void) { char *p = NULL; - int i, j, narg; + int j, narg, par; strparse(); narg = strescseq.narg; + par = atoi(strescseq.args[0]); switch(strescseq.type) { case ']': /* OSC -- Operating System Command */ - switch(i = atoi(strescseq.args[0])) { + switch(par) { case 0: case 1: case 2: if(narg > 1) xsettitle(strescseq.args[1]); - break; + return; case 4: /* color set */ if(narg < 3) break; @@ -2181,25 +2177,20 @@ strhandle(void) { */ redraw(0); } - break; - default: - fprintf(stderr, "erresc: unknown str "); - strdump(); - break; + return; } break; case 'k': /* old title set compatibility */ xsettitle(strescseq.args[0]); - break; + return; case 'P': /* DSC -- Device Control String */ case '_': /* APC -- Application Program Command */ case '^': /* PM -- Privacy Message */ - default: - fprintf(stderr, "erresc: unknown str "); - strdump(); - /* die(""); */ - break; + return; } + + fprintf(stderr, "erresc: unknown str "); + strdump(); } void @@ -2243,6 +2234,65 @@ strreset(void) { } void +tprinter(char *s, size_t len) { + if(iofd != -1 && xwrite(iofd, s, len) < 0) { + fprintf(stderr, "Error writing in %s:%s\n", + opt_io, strerror(errno)); + close(iofd); + iofd = -1; + } +} + +void +toggleprinter(const Arg *arg) { + term.mode ^= MODE_PRINT; +} + +void +printscreen(const Arg *arg) { + tdump(); +} + +void +printsel(const Arg *arg) { + tdumpsel(); +} + +void +tdumpsel(void) +{ + char *ptr; + + if((ptr = getsel())) { + tprinter(ptr, strlen(ptr)); + free(ptr); + } +} + +void +tdumpline(int n) { + Glyph *bp, *end; + + bp = &term.line[n][0]; + end = &bp[term.col-1]; + while(end > bp && !strcmp(" ", end->c)) + --end; + if(bp != end || strcmp(bp->c, " ")) { + for( ;bp <= end; ++bp) + tprinter(bp->c, strlen(bp->c)); + } + tprinter("\n", 1); +} + +void +tdump(void) { + int i; + + for(i = 0; i < term.row; ++i) + tdumpline(i); +} + +void tputtab(bool forward) { uint x = term.c.x; @@ -2313,24 +2363,18 @@ void tputc(char *c, int len) { uchar ascii = *c; bool control = ascii < '\x20' || ascii == 0177; - long u8char; + long unicodep; int width; if(len == 1) { width = 1; } else { - utf8decode(c, &u8char); - width = wcwidth(u8char); + utf8decode(c, &unicodep, UTF_SIZ); + width = wcwidth(unicodep); } - if(iofd != -1) { - if(xwrite(iofd, c, len) < 0) { - fprintf(stderr, "Error writing in %s:%s\n", - opt_io, strerror(errno)); - close(iofd); - iofd = -1; - } - } + if(IS_SET(MODE_PRINT)) + tprinter(c, len); /* * STR sequences must be checked before anything else @@ -2792,7 +2836,8 @@ xhints(void) { sizeh->min_height = sizeh->max_height = xw.fh; } - XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm, &class); + XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm, + &class); XFree(sizeh); } @@ -2825,9 +2870,9 @@ xloadfont(Font *f, FcPattern *pattern) { } void -xloadfonts(char *fontstr, int fontsize) { +xloadfonts(char *fontstr, double fontsize) { FcPattern *pattern; - FcResult result; + FcResult r_sz, r_psz; double fontval; if(fontstr[0] == '-') { @@ -2841,12 +2886,16 @@ xloadfonts(char *fontstr, int fontsize) { if(fontsize > 0) { FcPatternDel(pattern, FC_PIXEL_SIZE); + FcPatternDel(pattern, FC_SIZE); FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)fontsize); usedfontsize = fontsize; } else { - result = FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval); - if(result == FcResultMatch) { - usedfontsize = (int)fontval; + r_psz = FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval); + r_sz = FcPatternGetDouble(pattern, FC_SIZE, 0, &fontval); + if(r_psz == FcResultMatch) { + usedfontsize = fontval; + } else if(r_sz == FcResultMatch) { + usedfontsize = -1; } else { /* * Default font size is 12, if none given. This is to @@ -2863,6 +2912,12 @@ xloadfonts(char *fontstr, int fontsize) { if(xloadfont(&dc.font, pattern)) die("st: can't open font %s\n", fontstr); + if(usedfontsize < 0) { + FcPatternGetDouble(dc.font.match->pattern, + FC_PIXEL_SIZE, 0, &fontval); + usedfontsize = fontval; + } + /* Setting character width and height. */ xw.cw = CEIL(dc.font.width * cwscale); xw.ch = CEIL(dc.font.height * chscale); @@ -2932,6 +2987,7 @@ xinit(void) { Cursor cursor; Window parent; int sw, sh; + pid_t thispid = getpid(); if(!(xw.dpy = XOpenDisplay(NULL))) die("Can't open display\n"); @@ -3026,10 +3082,14 @@ xinit(void) { xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False); XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1); + xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False); + XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32, + PropModeReplace, (unsigned char *)&thispid, 1); + xresettitle(); XMapWindow(xw.dpy, xw.win); xhints(); - XSync(xw.dpy, 0); + XSync(xw.dpy, False); } void @@ -3039,7 +3099,7 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { int frcflags; int u8fl, u8fblen, u8cblen, doesexist; char *u8c, *u8fs; - long u8char; + long unicodep; Font *font = &dc.font; FcResult fcres; FcPattern *fcpattern, *fontpattern; @@ -3066,7 +3126,9 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { if(base.fg == defaultfg) base.fg = defaultunderline; } + if(IS_TRUECOL(base.fg)) { + colfg.alpha = 0xffff; colfg.red = TRUERED(base.fg); colfg.green = TRUEGREEN(base.fg); colfg.blue = TRUEBLUE(base.fg); @@ -3077,6 +3139,7 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { } if(IS_TRUECOL(base.bg)) { + colbg.alpha = 0xffff; colbg.green = TRUEGREEN(base.bg); colbg.red = TRUERED(base.bg); colbg.blue = TRUEBLUE(base.bg); @@ -3086,8 +3149,6 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { bg = &dc.col[base.bg]; } - - if(base.mode & ATTR_BOLD) { if(BETWEEN(base.fg, 0, 7)) { /* basic system colors */ @@ -3117,7 +3178,8 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { colfg.green = ~fg->color.green; colfg.blue = ~fg->color.blue; colfg.alpha = fg->color.alpha; - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &revfg); + XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, + &revfg); fg = &revfg; } @@ -3128,7 +3190,8 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { colbg.green = ~bg->color.green; colbg.blue = ~bg->color.blue; colbg.alpha = bg->color.alpha; - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &revbg); + XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, + &revbg); bg = &revbg; } } @@ -3179,11 +3242,11 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { oneatatime = font->width != xw.cw; for(;;) { u8c = s; - u8cblen = utf8decode(s, &u8char); + u8cblen = utf8decode(s, &unicodep, UTF_SIZ); s += u8cblen; bytelen -= u8cblen; - doesexist = XftCharExists(xw.dpy, font->match, u8char); + doesexist = XftCharExists(xw.dpy, font->match, unicodep); if(oneatatime || !doesexist || bytelen <= 0) { if(oneatatime || bytelen <= 0) { if(doesexist) { @@ -3208,14 +3271,14 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { u8fblen += u8cblen; } if(doesexist) { - if (oneatatime) + if(oneatatime) continue; break; } /* Search the font cache. */ for(i = 0; i < frclen; i++) { - if(XftCharExists(xw.dpy, frc[i].font, u8char) + if(XftCharExists(xw.dpy, frc[i].font, unicodep) && frc[i].flags == frcflags) { break; } @@ -3231,11 +3294,13 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { * Nothing was found in the cache. Now use * some dozen of Fontconfig calls to get the * font for one single character. + * + * Xft and fontconfig are design failures. */ fcpattern = FcPatternDuplicate(font->pattern); fccharset = FcCharSetCreate(); - FcCharSetAddChar(fccharset, u8char); + FcCharSetAddChar(fccharset, unicodep); FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); FcPatternAddBool(fcpattern, FC_SCALABLE, @@ -3271,10 +3336,16 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { xp, winy + frc[i].font->ascent, (FcChar8 *)u8c, u8cblen); - xp += xw.cw * wcwidth(u8char); + xp += xw.cw * wcwidth(unicodep); } /* + * This is how the loop above actually should be. Why does the + * application have to care about font details? + * + * I have to repeat: Xft and Fontconfig are design failures. + */ + /* XftDrawStringUtf8(xw.draw, fg, font->set, winx, winy + font->ascent, (FcChar8 *)s, bytelen); */ @@ -3308,7 +3379,7 @@ xdrawcursor(void) { memcpy(g.c, term.line[term.c.y][term.c.x].c, UTF_SIZ); /* remove the old cursor */ - sl = utf8size(term.line[oldy][oldx].c); + sl = utf8len(term.line[oldy][oldx].c); width = (term.line[oldy][oldx].mode & ATTR_WIDE)? 2 : 1; xdraws(term.line[oldy][oldx].c, term.line[oldy][oldx], oldx, oldy, width, sl); @@ -3322,7 +3393,7 @@ xdrawcursor(void) { g.bg = defaultfg; } - sl = utf8size(g.c); + sl = utf8len(g.c); width = (term.line[term.c.y][curx].mode & ATTR_WIDE)\ ? 2 : 1; xdraws(g.c, g, term.c.x, term.c.y, width, sl); @@ -3369,7 +3440,6 @@ void redraw(int timeout) { struct timespec tv = {0, timeout * 1000}; - tfulldirt(); draw(); if(timeout > 0) { @@ -3394,7 +3464,7 @@ drawregion(int x1, int y1, int x2, int y2) { Glyph base, new; char buf[DRAW_BUF_SIZ]; bool ena_sel = sel.ob.x != -1; - long u8char; + long unicodep; if(sel.alt ^ IS_SET(MODE_ALTSCREEN)) ena_sel = 0; @@ -3426,7 +3496,7 @@ drawregion(int x1, int y1, int x2, int y2) { base = new; } - sl = utf8decode(new.c, &u8char); + sl = utf8decode(new.c, &unicodep, UTF_SIZ); memcpy(buf+ib, new.c, sl); ib += sl; ic += (new.mode & ATTR_WIDE)? 2 : 1; @@ -3585,7 +3655,7 @@ kpress(XEvent *ev) { if(IS_SET(MODE_8BIT)) { if(*buf < 0177) { c = *buf | 0x80; - len = utf8encode(&c, buf); + len = utf8encode(c, buf, UTF_SIZ); } } else { buf[1] = buf[0]; @@ -3661,14 +3731,14 @@ run(void) { } } + ttynew(); if(!xw.isfixed) cresize(w, h); else cresize(xw.fw, xw.fh); - ttynew(); - gettimeofday(&lastblink, NULL); gettimeofday(&last, NULL); + lastblink = last; for(xev = actionfps;;) { long deltatime; @@ -3703,7 +3773,7 @@ run(void) { if(blinktimeout && TIMEDIFF(now, lastblink) > blinktimeout) { tsetdirtattr(ATTR_BLINK); term.mode ^= MODE_BLINK; - gettimeofday(&lastblink, NULL); + lastblink = now; dodraw = 1; } deltatime = TIMEDIFF(now, last); @@ -3774,7 +3844,7 @@ main(int argc, char *argv[]) { if(argc > 1) { opt_cmd = &argv[1]; if(argv[1] != NULL && opt_title == NULL) { - titles = strdup(argv[1]); + titles = xstrdup(argv[1]); opt_title = basename(titles); } }