uint b;
uint mask;
char *s;
-} Mousekey;
+} MouseShortcut;
typedef struct {
KeySym k;
static void tdeftran(char);
static inline int match(uint, uint);
static void ttynew(void);
-static void ttyread(void);
+static size_t ttyread(void);
static void ttyresize(void);
static void ttysend(char *, size_t);
static void ttywrite(const char *, size_t);
void
selinit(void)
{
- memset(&sel.tclick1, 0, sizeof(sel.tclick1));
- memset(&sel.tclick2, 0, sizeof(sel.tclick2));
+ clock_gettime(CLOCK_MONOTONIC, &sel.tclick1);
+ clock_gettime(CLOCK_MONOTONIC, &sel.tclick2);
sel.mode = SEL_IDLE;
+ sel.snap = 0;
sel.ob.x = -1;
sel.primary = NULL;
sel.clipboard = NULL;
bpress(XEvent *e)
{
struct timespec now;
- Mousekey *mk;
+ MouseShortcut *ms;
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
mousereport(e);
return;
}
- for (mk = mshortcuts; mk < mshortcuts + LEN(mshortcuts); mk++) {
- if (e->xbutton.button == mk->b
- && match(mk->mask, e->xbutton.state)) {
- ttysend(mk->s, strlen(mk->s));
+ for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
+ if (e->xbutton.button == ms->b
+ && match(ms->mask, e->xbutton.state)) {
+ ttysend(ms->s, strlen(ms->s));
return;
}
}
}
}
-void
+size_t
ttyread(void)
{
static char buf[BUFSIZ];
/* keep any uncomplete utf8 char for the next call */
memmove(buf, ptr, buflen);
+
+ return ret;
}
void
ttywrite(const char *s, size_t n)
{
- fd_set wfd;
- struct timespec tv;
+ fd_set wfd, rfd;
ssize_t r;
+ size_t lim = 256;
/*
* Remember that we are using a pty, which might be a modem line.
*/
while (n > 0) {
FD_ZERO(&wfd);
+ FD_ZERO(&rfd);
FD_SET(cmdfd, &wfd);
- tv.tv_sec = 0;
- tv.tv_nsec = 0;
+ FD_SET(cmdfd, &rfd);
/* Check if we can write. */
- if (pselect(cmdfd+1, NULL, &wfd, NULL, &tv, NULL) < 0) {
+ if (pselect(cmdfd+1, &rfd, &wfd, NULL, NULL, NULL) < 0) {
if (errno == EINTR)
continue;
die("select failed: %s\n", strerror(errno));
}
- if(!FD_ISSET(cmdfd, &wfd)) {
- /* No, then free some buffer space. */
- ttyread();
- } else {
+ if (FD_ISSET(cmdfd, &rfd))
+ lim = ttyread();
+ if (FD_ISSET(cmdfd, &wfd)) {
/*
- * Only write 256 bytes at maximum. This seems to be a
- * reasonable value for a serial line. Bigger values
- * might clog the I/O.
+ * Only write the bytes written by ttywrite() or the
+ * default of 256. This seems to be a reasonable value
+ * for a serial line. Bigger values might clog the I/O.
*/
- r = write(cmdfd, s, (n < 256)? n : 256);
- if (r < 0) {
- die("write error on tty: %s\n",
- strerror(errno));
- }
+ if ((r = write(cmdfd, s, (n < lim)? n : lim)) < 0)
+ goto write_error;
if (r < n) {
/*
* We weren't able to write out everything.
* This means the buffer is getting full
* again. Empty it.
*/
- if (n < 256)
- ttyread();
+ if (n < lim)
+ lim = ttyread();
n -= r;
s += r;
} else {
}
}
}
+ return;
+
+write_error:
+ die("write error on tty: %s\n", strerror(errno));
}
void
{
int numspecs;
XftGlyphFontSpec spec;
+
numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y);
xdrawglyphfontspecs(&spec, g, numspecs, x, y);
}
{
static int oldx = 0, oldy = 0;
int curx;
- Glyph g = {' ', ATTR_NULL, defaultbg, defaultcs};
+ Glyph g = {' ', ATTR_NULL, defaultbg, defaultcs}, og;
+ int ena_sel = sel.ob.x != -1 && sel.alt == IS_SET(MODE_ALTSCREEN);
+ Color drawcol;
LIMIT(oldx, 0, term.col-1);
LIMIT(oldy, 0, term.row-1);
if (term.line[term.c.y][curx].mode & ATTR_WDUMMY)
curx--;
+ /* remove the old cursor */
+ og = term.line[oldy][oldx];
+ if (ena_sel && selected(oldx, oldy))
+ og.mode ^= ATTR_REVERSE;
+ xdrawglyph(og, oldx, oldy);
+
g.u = term.line[term.c.y][term.c.x].u;
- /* remove the old cursor */
- xdrawglyph(term.line[oldy][oldx], oldx, oldy);
+ /*
+ * Select the right color for the right mode.
+ */
+ if (IS_SET(MODE_REVERSE)) {
+ g.mode |= ATTR_REVERSE;
+ g.bg = defaultfg;
+ if (ena_sel && selected(term.c.x, term.c.y)) {
+ drawcol = dc.col[defaultcs];
+ g.fg = defaultrcs;
+ } else {
+ drawcol = dc.col[defaultrcs];
+ g.fg = defaultcs;
+ }
+ } else {
+ if (ena_sel && selected(term.c.x, term.c.y)) {
+ drawcol = dc.col[defaultrcs];
+ g.fg = defaultfg;
+ g.bg = defaultrcs;
+ } else {
+ drawcol = dc.col[defaultcs];
+ }
+ }
if (IS_SET(MODE_HIDE))
return;
/* draw the new one */
if (xw.state & WIN_FOCUSED) {
switch (xw.cursor) {
+ case 7: /* st extension: snowman */
+ utf8decode("☃", &g.u, UTF_SIZ);
case 0: /* Blinking Block */
case 1: /* Blinking Block (Default) */
case 2: /* Steady Block */
- if (IS_SET(MODE_REVERSE)) {
- g.mode |= ATTR_REVERSE;
- g.fg = defaultcs;
- g.bg = defaultfg;
- }
-
g.mode |= term.line[term.c.y][curx].mode & ATTR_WIDE;
xdrawglyph(g, term.c.x, term.c.y);
break;
case 3: /* Blinking Underline */
case 4: /* Steady Underline */
- XftDrawRect(xw.draw, &dc.col[defaultcs],
+ XftDrawRect(xw.draw, &drawcol,
borderpx + curx * xw.cw,
- borderpx + (term.c.y + 1) * xw.ch - cursorthickness,
+ borderpx + (term.c.y + 1) * xw.ch - \
+ cursorthickness,
xw.cw, cursorthickness);
break;
case 5: /* Blinking bar */
case 6: /* Steady bar */
- XftDrawRect(xw.draw, &dc.col[defaultcs],
+ XftDrawRect(xw.draw, &drawcol,
borderpx + curx * xw.cw,
borderpx + term.c.y * xw.ch,
cursorthickness, xw.ch);
break;
}
} else {
- XftDrawRect(xw.draw, &dc.col[defaultcs],
+ XftDrawRect(xw.draw, &drawcol,
borderpx + curx * xw.cw,
borderpx + term.c.y * xw.ch,
xw.cw - 1, 1);
- XftDrawRect(xw.draw, &dc.col[defaultcs],
+ XftDrawRect(xw.draw, &drawcol,
borderpx + curx * xw.cw,
borderpx + term.c.y * xw.ch,
1, xw.ch - 1);
- XftDrawRect(xw.draw, &dc.col[defaultcs],
+ XftDrawRect(xw.draw, &drawcol,
borderpx + (curx + 1) * xw.cw - 1,
borderpx + term.c.y * xw.ch,
1, xw.ch - 1);
- XftDrawRect(xw.draw, &dc.col[defaultcs],
+ XftDrawRect(xw.draw, &drawcol,
borderpx + curx * xw.cw,
borderpx + (term.c.y + 1) * xw.ch - 1,
xw.cw, 1);
{
int i, x, y, ox, numspecs;
Glyph base, new;
- XftGlyphFontSpec* specs;
+ XftGlyphFontSpec *specs;
int ena_sel = sel.ob.x != -1 && sel.alt == IS_SET(MODE_ALTSCREEN);
if (!(xw.state & WIN_VISIBLE))