static void strparse(void);
static void strreset(void);
-static void tclearregion(int, int, int, int, int);
+static void tclearregion(int, int, int, int);
static void tcursor(int);
static void tdeletechar(int);
static void tdeleteline(int);
void
selcopy(void) {
char *str, *ptr, *p;
- int x, y, bufsize, is_selected = 0, size;
+ int x, y, bufsize, isselected = 0, size;
Glyph *gp, *last;
if(sel.bx == -1) {
/* append every set & selected glyph to the selection */
for(y = sel.b.y; y < sel.e.y + 1; y++) {
- is_selected = 0;
+ isselected = 0;
gp = &term.line[y][0];
last = gp + term.col;
- while(--last >= gp && !(last->state & GLYPH_SET))
+ while(--last >= gp && !((last->state & GLYPH_SET) && \
+ selected(last - gp, y) && strcmp(last->c, " ") != 0))
/* nothing */;
for(x = 0; gp <= last; x++, ++gp) {
if(!selected(x, y)) {
continue;
} else {
- is_selected = 1;
+ isselected = 1;
}
p = (gp->state & GLYPH_SET) ? gp->c : " ";
memcpy(ptr, p, size);
ptr += size;
}
- /* \n at the end of every selected line except for the last one */
- if(is_selected && y < sel.e.y)
- *ptr++ = '\r';
+
+ /*
+ * Copy and pasting of line endings is inconsistent
+ * in the inconsistent terminal and GUI world.
+ * The best solution seems like to produce '\n' when
+ * something is copied from st and convert '\n' to
+ * '\r', when something to be pasted is received by
+ * st.
+ * FIXME: Fix the computer world.
+ */
+ if(isselected && y < sel.e.y)
+ *ptr++ = '\n';
}
*ptr = 0;
}
selnotify(XEvent *e) {
ulong nitems, ofs, rem;
int format;
- uchar *data;
+ uchar *data, *last, *repl;
Atom type;
ofs = 0;
fprintf(stderr, "Clipboard allocation failed\n");
return;
}
- ttywrite((const char *) data, nitems * format / 8);
+
+ /*
+ * As seen in selcopy:
+ * Line endings are inconsistent in the terminal and GUI world
+ * copy and pasting. When receiving some selection data,
+ * replace all '\n' with '\r'.
+ * FIXME: Fix the computer world.
+ */
+ repl = data;
+ last = data + nitems * format / 8;
+ while((repl = memchr(repl, '\n', last - repl))) {
+ *repl++ = '\r';
+ }
+
+ ttywrite((const char *)data, nitems * format / 8);
XFree(data);
/* number of 32-bit chunks returned */
ofs += nitems * format / 32;
term.bot = term.row - 1;
term.mode = MODE_WRAP;
- tclearregion(0, 0, term.col-1, term.row-1, 0);
+ tclearregion(0, 0, term.col-1, term.row-1);
tmoveto(0, 0);
tcursor(CURSOR_SAVE);
}
LIMIT(n, 0, term.bot-orig+1);
- tclearregion(0, term.bot-n+1, term.col-1, term.bot, 0);
+ tclearregion(0, term.bot-n+1, term.col-1, term.bot);
for(i = term.bot; i >= orig+n; i--) {
temp = term.line[i];
Line temp;
LIMIT(n, 0, term.bot-orig+1);
- tclearregion(0, orig, term.col-1, orig+n-1, 0);
+ tclearregion(0, orig, term.col-1, orig+n-1);
for(i = orig; i <= term.bot-n; i++) {
temp = term.line[i];
}
void
-tclearregion(int x1, int y1, int x2, int y2, int bce) {
+tclearregion(int x1, int y1, int x2, int y2) {
int x, y, temp;
if(x1 > x2)
for(y = y1; y <= y2; y++) {
term.dirty[y] = 1;
for(x = x1; x <= x2; x++) {
- if(bce) {
- term.line[y][x] = term.c.attr;
- memcpy(term.line[y][x].c, " ", 2);
- term.line[y][x].state |= GLYPH_SET;
- } else {
- term.line[y][x].state = 0;
- }
+ term.line[y][x] = term.c.attr;
+ memcpy(term.line[y][x].c, " ", 2);
+ term.line[y][x].state |= GLYPH_SET;
}
}
}
term.dirty[term.c.y] = 1;
if(src >= term.col) {
- tclearregion(term.c.x, term.c.y, term.col-1, term.c.y, 0);
+ tclearregion(term.c.x, term.c.y, term.col-1, term.c.y);
return;
}
memmove(&term.line[term.c.y][dst], &term.line[term.c.y][src],
size * sizeof(Glyph));
- tclearregion(term.col-n, term.c.y, term.col-1, term.c.y, 0);
+ tclearregion(term.col-n, term.c.y, term.col-1, term.c.y);
}
void
term.dirty[term.c.y] = 1;
if(dst >= term.col) {
- tclearregion(term.c.x, term.c.y, term.col-1, term.c.y, 0);
+ tclearregion(term.c.x, term.c.y, term.col-1, term.c.y);
return;
}
memmove(&term.line[term.c.y][dst], &term.line[term.c.y][src],
size * sizeof(Glyph));
- tclearregion(src, term.c.y, dst - 1, term.c.y, 0);
+ tclearregion(src, term.c.y, dst - 1, term.c.y);
}
void
for(i = 0; i < l; i++) {
switch(attr[i]) {
case 0:
- term.c.attr.mode &= ~(ATTR_REVERSE | ATTR_UNDERLINE | ATTR_BOLD \
- | ATTR_ITALIC | ATTR_BLINK);
+ term.c.attr.mode &= ~(ATTR_REVERSE | ATTR_UNDERLINE \
+ | ATTR_BOLD | ATTR_ITALIC \
+ | ATTR_BLINK);
term.c.attr.fg = defaultfg;
term.c.attr.bg = defaultbg;
break;
alt = IS_SET(MODE_ALTSCREEN);
if(alt) {
tclearregion(0, 0, term.col-1,
- term.row-1, 0);
+ term.row-1);
}
if(set ^ alt) /* set is always 1 or 0 */
tswapscreen();
sel.bx = -1;
switch(csiescseq.arg[0]) {
case 0: /* below */
- tclearregion(term.c.x, term.c.y, term.col-1, term.c.y, 1);
+ tclearregion(term.c.x, term.c.y, term.col-1, term.c.y);
if(term.c.y < term.row-1) {
tclearregion(0, term.c.y+1, term.col-1,
- term.row-1, 1);
+ term.row-1);
}
break;
case 1: /* above */
if(term.c.y > 1)
- tclearregion(0, 0, term.col-1, term.c.y-1, 1);
- tclearregion(0, term.c.y, term.c.x, term.c.y, 1);
+ tclearregion(0, 0, term.col-1, term.c.y-1);
+ tclearregion(0, term.c.y, term.c.x, term.c.y);
break;
case 2: /* all */
- tclearregion(0, 0, term.col-1, term.row-1, 1);
+ tclearregion(0, 0, term.col-1, term.row-1);
break;
default:
goto unknown;
switch(csiescseq.arg[0]) {
case 0: /* right */
tclearregion(term.c.x, term.c.y, term.col-1,
- term.c.y, 1);
+ term.c.y);
break;
case 1: /* left */
- tclearregion(0, term.c.y, term.c.x, term.c.y, 1);
+ tclearregion(0, term.c.y, term.c.x, term.c.y);
break;
case 2: /* all */
- tclearregion(0, term.c.y, term.col-1, term.c.y, 1);
+ tclearregion(0, term.c.y, term.col-1, term.c.y);
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] - 1, term.c.y, 1);
+ term.c.x + csiescseq.arg[0] - 1, term.c.y);
break;
case 'P': /* DCH -- Delete <n> char */
DEFAULT(csiescseq.arg[0], 1);
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, dc.col[IS_SET(MODE_REVERSE) ? defaultfg : defaultbg].pixel);
- XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, xw.w, xw.h);
-
XftDrawChange(xw.draw, xw.buf);
+ xclear(0, 0, xw.w, xw.h);
}
static inline ushort
/* draw the new one */
if(!(IS_SET(MODE_HIDE))) {
- if(!(xw.state & WIN_FOCUSED))
- g.bg = defaultucs;
-
- if(IS_SET(MODE_REVERSE))
- g.mode |= ATTR_REVERSE, g.fg = defaultcs, g.bg = defaultfg;
+ if(xw.state & WIN_FOCUSED) {
+ if(IS_SET(MODE_REVERSE)) {
+ g.mode |= ATTR_REVERSE;
+ g.fg = defaultcs;
+ g.bg = defaultfg;
+ }
- sl = utf8size(g.c);
- xdraws(g.c, g, term.c.x, term.c.y, 1, sl);
+ sl = utf8size(g.c);
+ xdraws(g.c, g, term.c.x, term.c.y, 1, sl);
+ } else {
+ XftDrawRect(xw.draw, &dc.col[defaultcs],
+ borderpx + term.c.x * xw.cw,
+ borderpx + term.c.y * xw.ch,
+ xw.cw - 1, 1);
+ XftDrawRect(xw.draw, &dc.col[defaultcs],
+ borderpx + term.c.x * xw.cw,
+ borderpx + term.c.y * xw.ch,
+ 1, xw.ch - 1);
+ XftDrawRect(xw.draw, &dc.col[defaultcs],
+ borderpx + (term.c.x + 1) * xw.cw - 1,
+ borderpx + term.c.y * xw.ch,
+ 1, xw.ch - 1);
+ XftDrawRect(xw.draw, &dc.col[defaultcs],
+ borderpx + term.c.x * xw.cw,
+ borderpx + (term.c.y + 1) * xw.ch - 1,
+ xw.cw, 1);
+ }
oldx = term.c.x, oldy = term.c.y;
}
}
xinit();
ttynew();
selinit();
+ if(xw.isfixed)
+ cresize(xw.h, xw.w);
run();
return 0;