X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=st.c;h=9371b628b4493684eef6c941f85ca135059a3d88;hb=d2ec39f0ef4b9d7f291aeba548a56144fce8a42f;hp=16bf68bf04804ab651140c71f24e6361bf81fd66;hpb=939e149544e4da958c333f3b6d00991d459c2e34;p=st.git diff --git a/st.c b/st.c index 16bf68b..9371b62 100644 --- a/st.c +++ b/st.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -180,8 +181,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 +240,7 @@ typedef struct { Colourmap cmap; Window win; Drawable buf; - Atom xembed, wmdeletewin; + Atom xembed, wmdeletewin, netwmname, netwmpid; XIM xim; XIC xic; Draw draw; @@ -256,9 +257,9 @@ typedef struct { } XWindow; typedef struct { - int b; + uint b; uint mask; - char s[ESC_BUF_SIZ]; + char *s; } Mousekey; typedef struct { @@ -379,13 +380,14 @@ 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); static void ttynew(void); static void ttyread(void); static void ttyresize(void); +static void ttysend(char *, size_t); static void ttywrite(const char *, size_t); static void xdraws(char *, Glyph, int, int, int, int); @@ -396,7 +398,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); @@ -439,6 +441,7 @@ static int isfullutf8(char *, int); 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, @@ -476,7 +479,7 @@ 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; /* Font Ring Cache */ enum { @@ -527,6 +530,16 @@ xrealloc(void *p, size_t len) { return p; } +char * +xstrdup(char *s) { + char *p = strdup(s); + + if (!p) + die("Out of memory\n"); + + return p; +} + int utf8decode(char *s, long *u) { uchar c; @@ -893,9 +906,7 @@ bpress(XEvent *e) { for(mk = mshortcuts; mk < mshortcuts + LEN(mshortcuts); mk++) { if(e->xbutton.button == mk->b && match(mk->mask, e->xbutton.state)) { - ttywrite(mk->s, strlen(mk->s)); - if(IS_SET(MODE_ECHO)) - techo(mk->s, strlen(mk->s)); + ttysend(mk->s, strlen(mk->s)); return; } } @@ -953,11 +964,12 @@ 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)) @@ -1031,7 +1043,7 @@ selnotify(XEvent *e) { if(IS_SET(MODE_BRCKTPASTE)) ttywrite("\033[200~", 6); - ttywrite((const char *)data, nitems * format / 8); + ttysend((char *)data, nitems * format / 8); if(IS_SET(MODE_BRCKTPASTE)) ttywrite("\033[201~", 6); XFree(data); @@ -1300,6 +1312,13 @@ ttywrite(const char *s, size_t n) { } void +ttysend(char *s, size_t n) { + ttywrite(s, n); + if(IS_SET(MODE_ECHO)) + techo(s, n); +} + +void ttyresize(void) { struct winsize w; @@ -1660,9 +1679,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]) { @@ -1711,7 +1730,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]) { @@ -2145,20 +2164,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; @@ -2175,25 +2195,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 @@ -2786,7 +2801,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); } @@ -2819,9 +2835,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] == '-') { @@ -2835,12 +2851,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 @@ -2857,6 +2877,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); @@ -2926,6 +2952,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"); @@ -3017,8 +3044,13 @@ xinit(void) { xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); + 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(); @@ -3060,6 +3092,7 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { 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); @@ -3070,6 +3103,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); @@ -3349,6 +3383,7 @@ xsettitle(char *p) { Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, &prop); XSetWMName(xw.dpy, xw.win, &prop); + XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname); XFree(prop.value); } @@ -3495,15 +3530,7 @@ focus(XEvent *ev) { static inline bool match(uint mask, uint state) { - state &= ~ignoremod; - - if(mask == XK_NO_MOD && state) - return false; - if(mask != XK_ANY_MOD && mask != XK_NO_MOD && !state) - return false; - if(mask == XK_ANY_MOD) - return true; - return state == mask; + return mask == XK_ANY_MOD || mask == (state & ~ignoremod); } void @@ -3533,25 +3560,16 @@ kmap(KeySym k, uint state) { if(!match(kp->mask, state)) continue; - if(kp->appkey > 0) { - if(!IS_SET(MODE_APPKEYPAD)) - continue; - if(term.numlock && kp->appkey == 2) - continue; - } else if(kp->appkey < 0 && IS_SET(MODE_APPKEYPAD)) { + if(IS_SET(MODE_APPKEYPAD) ? kp->appkey < 0 : kp->appkey > 0) + continue; + if(term.numlock && kp->appkey == 2) continue; - } - if((kp->appcursor < 0 && IS_SET(MODE_APPCURSOR)) || - (kp->appcursor > 0 - && !IS_SET(MODE_APPCURSOR))) { + if(IS_SET(MODE_APPCURSOR) ? kp->appcursor < 0 : kp->appcursor > 0) continue; - } - if((kp->crlf < 0 && IS_SET(MODE_CRLF)) || - (kp->crlf > 0 && !IS_SET(MODE_CRLF))) { + if(IS_SET(MODE_CRLF) ? kp->crlf < 0 : kp->crlf > 0) continue; - } return kp->s; } @@ -3573,7 +3591,6 @@ kpress(XEvent *ev) { return; len = XmbLookupString(xw.xic, e, buf, sizeof buf, &ksym, &status); - e->state &= ~Mod2Mask; /* 1. shortcuts */ for(bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { if(ksym == bp->keysym && match(bp->mod, e->state)) { @@ -3584,10 +3601,7 @@ kpress(XEvent *ev) { /* 2. custom keys from config.h */ if((customkey = kmap(ksym, e->state))) { - len = strlen(customkey); - ttywrite(customkey, len); - if(IS_SET(MODE_ECHO)) - techo(customkey, len); + ttysend(customkey, strlen(customkey)); return; } @@ -3606,9 +3620,7 @@ kpress(XEvent *ev) { len = 2; } } - ttywrite(buf, len); - if(IS_SET(MODE_ECHO)) - techo(buf, len); + ttysend(buf, len); } @@ -3676,16 +3688,18 @@ run(void) { } } + ttynew(); if(!xw.isfixed) cresize(w, h); else cresize(xw.fw, xw.fh); - ttynew(); gettimeofday(&lastblink, NULL); gettimeofday(&last, NULL); for(xev = actionfps;;) { + long deltatime; + FD_ZERO(&rfd); FD_SET(cmdfd, &rfd); FD_SET(xfd, &rfd); @@ -3719,8 +3733,9 @@ run(void) { gettimeofday(&lastblink, NULL); dodraw = 1; } - if(TIMEDIFF(now, last) \ - > (xev? (1000/xfps) : (1000/actionfps))) { + deltatime = TIMEDIFF(now, last); + if(deltatime > (xev? (1000/xfps) : (1000/actionfps)) + || deltatime < 0) { dodraw = 1; last = now; } @@ -3786,7 +3801,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); } }