#include <stdlib.h>
#include <string.h>
#include <signal.h>
+#include <stdint.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/stat.h>
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;
Colourmap cmap;
Window win;
Drawable buf;
- Atom xembed, wmdeletewin;
+ Atom xembed, wmdeletewin, netwmname, netwmpid;
XIM xim;
XIC xic;
Draw draw;
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 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);
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,
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 {
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;
/* 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))
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]) {
void
tsetattr(int *attr, int l) {
int i;
- long idx;
+ int32_t idx;
for(i = 0; i < l; i++) {
switch(attr[i]) {
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;
*/
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
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);
}
}
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] == '-') {
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
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);
Cursor cursor;
Window parent;
int sw, sh;
+ pid_t thispid = getpid();
if(!(xw.dpy = XOpenDisplay(NULL)))
die("Can't open display\n");
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();
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);
}
if(IS_TRUECOL(base.bg)) {
+ colbg.alpha = 0xffff;
colbg.green = TRUEGREEN(base.bg);
colbg.red = TRUERED(base.bg);
colbg.blue = TRUEBLUE(base.bg);
bg = &dc.col[base.bg];
}
-
-
if(base.mode & ATTR_BOLD) {
if(BETWEEN(base.fg, 0, 7)) {
/* basic system colors */
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;
}
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;
}
}
u8fblen += u8cblen;
}
if(doesexist) {
- if (oneatatime)
+ if(oneatatime)
continue;
break;
}
* 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();
xp += xw.cw * wcwidth(u8char);
}
+ /*
+ * 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);
Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
&prop);
XSetWMName(xw.dpy, xw.win, &prop);
+ XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname);
XFree(prop.value);
}
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
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;
}
}
}
+ ttynew();
if(!xw.isfixed)
cresize(w, h);
else
cresize(xw.fw, xw.fh);
- ttynew();
gettimeofday(&lastblink, NULL);
gettimeofday(&last, NULL);
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);
}
}