#define DRAW_BUF_SIZ 20*1024
#define XK_ANY_MOD UINT_MAX
#define XK_NO_MOD 0
+#define XK_SWITCH_MOD (1<<13)
#define REDRAW_TIMEOUT (80*1000) /* 80 ms */
void
selrequest(XEvent *e) {
- fprintf(stderr, "selrequest\n");
XSelectionRequestEvent *xsre;
XSelectionEvent xev;
Atom xa_targets, string;
void
xsetsel(char *str) {
- fprintf(stderr, "xsetsel: %s\n", str);
/* register the selection for both the clipboard and the primary */
Atom clipboard;
break;
case 1000: /* 1000,1002: enable xterm mouse report */
MODBIT(term.mode, set, MODE_MOUSEBTN);
+ MODBIT(term.mode, 0, MODE_MOUSEMOTION);
break;
case 1002:
MODBIT(term.mode, set, MODE_MOUSEMOTION);
+ MODBIT(term.mode, 0, MODE_MOUSEBTN);
break;
case 1006:
MODBIT(term.mode, set, MODE_MOUSESGR);
tmoveto(0, term.c.y-csiescseq.arg[0]);
break;
case 'g': /* TBC -- Tabulation clear */
- switch (csiescseq.arg[0]) {
+ switch(csiescseq.arg[0]) {
case 0: /* clear current tab stop */
term.tabs[term.c.x] = 0;
break;
break;
case 'X': /* ECH -- Erase <n> char */
DEFAULT(csiescseq.arg[0], 1);
- tclearregion(term.c.x, term.c.y, term.c.x + csiescseq.arg[0],
- term.c.y, 1);
+ tclearregion(term.c.x, term.c.y,
+ term.c.x + csiescseq.arg[0] - 1, term.c.y, 1);
break;
case 'P': /* DCH -- Delete <n> char */
DEFAULT(csiescseq.arg[0], 1);
if(c == '\033') { /* escape */
tputc("^", 1);
tputc("[", 1);
- } else if (c < '\x20') { /* control code */
+ } else if(c < '\x20') { /* control code */
if(c != '\n' && c != '\r' && c != '\t') {
c |= '\x40';
tputc("^", 1);
break;
}
}
- if (len)
+ if(len)
tputc(buf, len);
}
bool control = ascii < '\x20' || ascii == 0177;
if(iofd != -1) {
- if (xwrite(iofd, c, len) < 0) {
+ if(xwrite(iofd, c, len) < 0) {
fprintf(stderr, "Error writing in %s:%s\n",
opt_io, strerror(errno));
close(iofd);
XFreePixmap(xw.dpy, xw.buf);
xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h,
DefaultDepth(xw.dpy, xw.scr));
- XSetForeground(xw.dpy, dc.gc, 0);
+ XSetForeground(xw.dpy, dc.gc, dc.col[IS_SET(MODE_REVERSE) ? defaultfg : defaultbg].pixel);
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, xw.w, xw.h);
}
void
xloadcols(void) {
int i, r, g, b;
- XRenderColor color = { .alpha = 0 };
+ XRenderColor color = { .alpha = 0xffff };
/* load colors [0-15] colors and [256-LEN(colorname)[ (config.h) */
for(i = 0; i < LEN(colorname); i++) {
xw.cw = dc.font.width;
xw.ch = dc.font.height;
+ FcPatternDel(pattern, FC_SLANT);
FcPatternDel(pattern, FC_WEIGHT);
+ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
if(xloadfont(&dc.bfont, pattern))
die("st: can't open font %s\n", fontstr);
die("st: can't open font %s\n", fontstr);
FcPatternDel(pattern, FC_WEIGHT);
+ FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_MEDIUM);
if(xloadfont(&dc.ifont, pattern))
die("st: can't open font %s\n", fontstr);
* Free the loaded fonts in the font cache. This is done backwards
* from the frccur.
*/
- for (i = 0, ip = frccur; i < frclen; i++, ip--) {
- if (ip < 0)
+ for(i = 0, ip = frccur; i < frclen; i++, ip--) {
+ if(ip < 0)
ip = LEN(frc) - 1;
XftFontClose(xw.dpy, frc[ip].font);
}
xw.vis = XDefaultVisual(xw.dpy, xw.scr);
/* font */
- if (!FcInit())
+ if(!FcInit())
die("Could not init fontconfig.\n");
usedfont = (opt_font == NULL)? font : opt_font;
&gcvalues);
xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h,
DefaultDepth(xw.dpy, xw.scr));
- XSetForeground(xw.dpy, dc.gc, 0);
+ XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, xw.w, xw.h);
//xw.buf = xw.win;
/*
XftDrawRect(xw.draw, bg, winx, winy, width, xw.ch);
fcsets[0] = font->set;
- for (xp = winx; bytelen > 0;) {
+ for(xp = winx; bytelen > 0;) {
/*
* Search for the range in the to be printed string of glyphs
* that are in the main font. Then print that range. If
u8fs = s;
u8fblen = 0;
u8fl = 0;
- for (;;) {
+ for(;;) {
u8c = s;
u8cblen = utf8decode(s, &u8char);
s += u8cblen;
bytelen -= u8cblen;
doesexist = XftCharIndex(xw.dpy, font->match, u8char);
- if (!doesexist || bytelen <= 0) {
- if (bytelen <= 0) {
- if (doesexist) {
+ if(!doesexist || bytelen <= 0) {
+ if(bytelen <= 0) {
+ if(doesexist) {
u8fl++;
u8fblen += u8cblen;
}
}
- if (u8fl > 0) {
+ if(u8fl > 0) {
XftDrawStringUtf8(xw.draw, fg,
font->match, xp,
winy + font->ascent,
u8fl++;
u8fblen += u8cblen;
}
- if (doesexist)
+ if(doesexist)
break;
frp = frccur;
/* Search the font cache. */
- for (i = 0; i < frclen; i++, frp--) {
- if (frp <= 0)
+ for(i = 0; i < frclen; i++, frp--) {
+ if(frp <= 0)
frp = LEN(frc) - 1;
- if (frc[frp].c == u8char
+ if(frc[frp].c == u8char
&& frc[frp].flags == frcflags) {
break;
}
}
/* Nothing was found. */
- if (i >= frclen) {
+ if(i >= frclen) {
/*
* Nothing was found in the cache. Now use
* some dozen of Fontconfig calls to get the
*/
frccur++;
frclen++;
- if (frccur >= LEN(frc))
+ if(frccur >= LEN(frc))
frccur = 0;
- if (frclen > LEN(frc)) {
+ if(frclen > LEN(frc)) {
frclen = LEN(frc);
XftFontClose(xw.dpy, frc[frccur].font);
}
} else {
XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, xw.w,
xw.h, 0, 0);
- XSetForeground(xw.dpy, dc.gc, 0);
+ XSetForeground(xw.dpy, dc.gc, dc.col[IS_SET(MODE_REVERSE) ? defaultfg : defaultbg].pixel);
}
}
void
focus(XEvent *ev) {
+ XFocusChangeEvent *e = &ev->xfocus;
+
+ if(e->mode == NotifyGrab)
+ return;
+
if(ev->type == FocusIn) {
XSetICFocus(xw.xic);
xw.state |= WIN_FOCUSED;
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)
Status status;
Shortcut *bp;
- if (IS_SET(MODE_KBDLOCK))
+ if(IS_SET(MODE_KBDLOCK))
return;
len = XmbLookupString(xw.xic, e, xstr, sizeof(xstr), &ksym, &status);
if(len == 0)
return;
- if (len == 1 && e->state & Mod1Mask)
+ if(len == 1 && e->state & Mod1Mask)
*cp++ = '\033';
memcpy(cp, xstr, len);
run(void) {
XEvent ev;
fd_set rfd;
- int xfd = XConnectionNumber(xw.dpy), i;
- struct timeval drawtimeout, *tv = NULL;
+ int xfd = XConnectionNumber(xw.dpy), xev;
+ struct timeval drawtimeout, *tv = NULL, now, last;
- for(i = 0;; i++) {
+ gettimeofday(&last, NULL);
+
+ for(xev = actionfps;;) {
FD_ZERO(&rfd);
FD_SET(cmdfd, &rfd);
FD_SET(xfd, &rfd);
die("select failed: %s\n", SERRNO);
}
- /*
- * Stop after a certain number of reads so the user does not
- * feel like the system is stuttering.
- */
- if(i < 1000 && FD_ISSET(cmdfd, &rfd)) {
+ gettimeofday(&now, NULL);
+ drawtimeout.tv_sec = 0;
+ drawtimeout.tv_usec = (1000/xfps) * 1000;
+ tv = &drawtimeout;
+
+ if(FD_ISSET(cmdfd, &rfd))
ttyread();
- /*
- * Just wait a bit so it isn't disturbing the
- * user and the system is able to write something.
- */
- drawtimeout.tv_sec = 0;
- drawtimeout.tv_usec = 5;
- tv = &drawtimeout;
- continue;
- }
- i = 0;
- tv = NULL;
+ if(FD_ISSET(xfd, &rfd))
+ xev = actionfps;
- while(XPending(xw.dpy)) {
- XNextEvent(xw.dpy, &ev);
- if(XFilterEvent(&ev, None))
- continue;
- if(handler[ev.type])
- (handler[ev.type])(&ev);
- }
+ if(TIMEDIFF(now, last) > \
+ (xev ? (1000/xfps) : (1000/actionfps))) {
+ while(XPending(xw.dpy)) {
+ XNextEvent(xw.dpy, &ev);
+ if(XFilterEvent(&ev, None))
+ continue;
+ if(handler[ev.type])
+ (handler[ev.type])(&ev);
+ }
- draw();
- XFlush(xw.dpy);
+ draw();
+ XFlush(xw.dpy);
+ last = now;
+
+ if(xev && !FD_ISSET(xfd, &rfd))
+ xev--;
+ if(!FD_ISSET(cmdfd, &rfd) && !FD_ISSET(xfd, &rfd))
+ tv = NULL;
+ }
}
}