typedef unsigned short ushort;
typedef XftDraw *Draw;
-typedef XftColor Colour;
-typedef Colormap Colourmap;
+typedef XftColor Color;
+typedef Colormap Colormap;
typedef struct {
char c[UTF_SIZ]; /* character code */
/* Purely graphic info */
typedef struct {
Display *dpy;
- Colourmap cmap;
+ Colormap cmap;
Window win;
Drawable buf;
Atom xembed, wmdeletewin, netwmname, netwmpid;
/* Drawing Context */
typedef struct {
- Colour col[LEN(colorname) < 256 ? 256 : LEN(colorname)];
+ Color col[MAX(LEN(colorname), 256)];
Font font, bfont, ifont, ibfont;
GC gc;
} DC;
static void selrequest(XEvent *);
static void selinit(void);
-static void selsort(void);
+static void selnormalize(void);
static inline bool selected(int, int);
static char *getsel(void);
static void selcopy(void);
return LIMIT(y, 0, term.row-1);
}
+static int tlinelen(int y) {
+ int i = term.col;
+
+ while (i > 0 && term.line[y][i - 1].c[0] == ' ')
+ --i;
+
+ return i;
+}
+
static void
-selsort(void) {
- if(sel.ob.y == sel.oe.y) {
+selnormalize(void) {
+ int i;
+
+ if(sel.ob.y == sel.oe.y || sel.type == SEL_RECTANGULAR) {
sel.nb.x = MIN(sel.ob.x, sel.oe.x);
sel.ne.x = MAX(sel.ob.x, sel.oe.x);
} else {
}
sel.nb.y = MIN(sel.ob.y, sel.oe.y);
sel.ne.y = MAX(sel.ob.y, sel.oe.y);
+
+ /* expand selection over line breaks */
+ if (sel.type == SEL_RECTANGULAR)
+ return;
+ i = tlinelen(sel.nb.y);
+ if (i < sel.nb.x)
+ sel.nb.x = i;
+ if (tlinelen(sel.ne.y) <= sel.ne.x)
+ sel.ne.x = term.col - 1;
}
static inline bool
void
selsnap(int mode, int *x, int *y, int direction) {
- int i;
+ int newx, newy, xt, yt;
+ Glyph *gp;
switch(mode) {
case SNAP_WORD:
* beginning of a line.
*/
for(;;) {
- if(direction < 0 && *x <= 0) {
- if(*y > 0 && term.line[*y - 1][term.col-1].mode
- & ATTR_WRAP) {
- *y -= 1;
- *x = term.col-1;
- } else {
+ newx = *x + direction;
+ newy = *y;
+ if(!BETWEEN(newx, 0, term.col - 1)) {
+ newy += direction;
+ newx = (newx + term.col) % term.col;
+ if (!BETWEEN(newy, 0, term.row - 1))
break;
- }
- }
- if(direction > 0 && *x >= term.col-1) {
- if(*y < term.row-1 && term.line[*y][*x].mode
- & ATTR_WRAP) {
- *y += 1;
- *x = 0;
- } else {
+
+ if(direction > 0)
+ yt = *y, xt = *x;
+ else
+ yt = newy, xt = newx;
+ if(!(term.line[yt][xt].mode & ATTR_WRAP))
break;
- }
}
- if(term.line[*y][*x+direction].mode & ATTR_WDUMMY) {
- *x += direction;
- continue;
- }
+ if (newx >= tlinelen(newy))
+ break;
- if(strchr(worddelimiters,
- term.line[*y][*x+direction].c[0])) {
+ gp = &term.line[newy][newx];
+ if (!(gp->mode & ATTR_WDUMMY) && strchr(worddelimiters, gp->c[0]))
break;
- }
- *x += direction;
+ *x = newx;
+ *y = newy;
}
break;
case SNAP_LINE:
}
}
break;
- default:
- /*
- * Select the whole line when the end of line is reached.
- */
- if(direction > 0) {
- i = term.col;
- while(--i > 0 && term.line[*y][i].c[0] == ' ')
- /* nothing */;
- if(i > 0 && i < *x)
- *x = term.col - 1;
- }
- break;
}
}
void
getbuttoninfo(XEvent *e) {
int type;
- uint state = e->xbutton.state &~Button1Mask;
+ uint state = e->xbutton.state & ~(Button1Mask | forceselmod);
sel.alt = IS_SET(MODE_ALTSCREEN);
selsnap(sel.snap, &sel.oe.x, &sel.oe.y, -1);
selsnap(sel.snap, &sel.ob.x, &sel.ob.y, +1);
}
- selsort();
+ selnormalize();
sel.type = SEL_REGULAR;
for(type = 1; type < LEN(selmasks); ++type) {
/* MODE_MOUSEX10: no button release reporting */
if(IS_SET(MODE_MOUSEX10))
return;
+ if (button == 64 || button == 65)
+ return;
}
}
struct timeval now;
Mousekey *mk;
- if(IS_SET(MODE_MOUSE)) {
+ if(IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
mousereport(e);
return;
}
}
selsnap(sel.snap, &sel.ob.x, &sel.ob.y, -1);
selsnap(sel.snap, &sel.oe.x, &sel.oe.y, +1);
- selsort();
+ selnormalize();
/*
* Draw selection, unless it's regular and we don't want to
char *
getsel(void) {
char *str, *ptr;
- int x, y, bufsize, size, i, ex;
+ int x, y, bufsize, size, ex;
Glyph *gp, *last;
if(sel.ob.x == -1)
* st.
* FIXME: Fix the computer world.
*/
- if(y < sel.ne.y && x > 0 && !((gp-1)->mode & ATTR_WRAP))
+ if(y < sel.ne.y && !(x > 0 && (gp-1)->mode & ATTR_WRAP))
*ptr++ = '\n';
/*
* after the visible text '\n' is appended.
*/
if(y == sel.ne.y) {
- i = term.col;
- while(--i > 0 && term.line[y][i].c[0] == ' ')
- /* nothing */;
ex = sel.ne.x;
if(sel.nb.y == sel.ne.y && sel.ne.x < sel.nb.x)
ex = sel.nb.x;
- if(i < ex)
+ if(tlinelen(y) < ex)
*ptr++ = '\n';
}
}
void
brelease(XEvent *e) {
- if(IS_SET(MODE_MOUSE)) {
+ if(IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
mousereport(e);
return;
}
bmotion(XEvent *e) {
int oldey, oldex, oldsby, oldsey;
- if(IS_SET(MODE_MOUSE)) {
+ if(IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
mousereport(e);
return;
}
sel.oe.x = term.col;
}
}
- selsort();
+ selnormalize();
}
}
uint r, g, b;
switch (attr[*npar + 1]) {
- case 2: /* direct colour in RGB space */
+ case 2: /* direct color in RGB space */
if (*npar + 4 >= l) {
fprintf(stderr,
"erresc(38): Incorrect number of parameters (%d)\n",
else
idx = TRUECOLOR(r, g, b);
break;
- case 5: /* indexed colour */
+ case 5: /* indexed color */
if (*npar + 2 >= l) {
fprintf(stderr,
"erresc(38): Incorrect number of parameters (%d)\n",
break;
case 0: /* implemented defined (only foreground) */
case 1: /* transparent */
- case 3: /* direct colour in CMY space */
- case 4: /* direct colour in CMYK space */
+ case 3: /* direct color in CMY space */
+ case 4: /* direct color in CMYK space */
default:
fprintf(stderr,
"erresc(38): gfx attr %d unknown\n", attr[*npar]);
/* FALLTHROUGH */
case 104: /* color reset, here p = NULL */
j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
- if (!xsetcolorname(j, p)) {
+ if(xsetcolorname(j, p)) {
fprintf(stderr, "erresc: invalid color %s\n", p);
} else {
/*
void
xloadcols(void) {
- int i, r, g, b;
+ int i;
XRenderColor color = { .alpha = 0xffff };
static bool loaded;
- Colour *cp;
+ Color *cp;
if(loaded) {
for (cp = dc.col; cp < dc.col + LEN(dc.col); ++cp)
XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
}
- /* load colors [0-15] colors and [256-LEN(colorname)[ (config.h) */
+ /* load colors [0-15] and [256-LEN(colorname)] (config.h) */
for(i = 0; i < LEN(colorname); i++) {
if(!colorname[i])
continue;
}
}
- /* load colors [16-255] ; same colors as xterm */
- for(i = 16, r = 0; r < 6; r++) {
- for(g = 0; g < 6; g++) {
- for(b = 0; b < 6; b++) {
- color.red = sixd_to_16bit(r);
- color.green = sixd_to_16bit(g);
- color.blue = sixd_to_16bit(b);
- if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &color, &dc.col[i])) {
- die("Could not allocate color %d\n", i);
- }
- i++;
- }
- }
+ /* load colors [16-231] ; same colors as xterm */
+ for(i = 16; i < 6*6*6+16; i++) {
+ color.red = sixd_to_16bit( ((i-16)/36)%6 );
+ color.green = sixd_to_16bit( ((i-16)/6) %6 );
+ color.blue = sixd_to_16bit( ((i-16)/1) %6 );
+ if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &color, &dc.col[i]))
+ die("Could not allocate color %d\n", i);
}
- for(r = 0; r < 24; r++, i++) {
- color.red = color.green = color.blue = 0x0808 + 0x0a0a * r;
- if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &color,
- &dc.col[i])) {
+ /* load colors [232-255] ; grayscale */
+ for(; i < 256; i++) {
+ color.red = color.green = color.blue = 0x0808 + 0x0a0a * (i-(6*6*6+16));
+ if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &color, &dc.col[i]))
die("Could not allocate color %d\n", i);
- }
}
loaded = true;
}
int
xsetcolorname(int x, const char *name) {
XRenderColor color = { .alpha = 0xffff };
- Colour colour;
+ Color ncolor;
+
if(!BETWEEN(x, 0, LEN(colorname)))
- return -1;
+ return 1;
+
if(!name) {
- if(BETWEEN(x, 16, 16 + 215)) {
- int r = (x - 16) / 36, g = ((x - 16) % 36) / 6, b = (x - 16) % 6;
- color.red = sixd_to_16bit(r);
- color.green = sixd_to_16bit(g);
- color.blue = sixd_to_16bit(b);
- if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &color, &colour))
- return 0; /* something went wrong */
- dc.col[x] = colour;
- return 1;
- } else if(BETWEEN(x, 16 + 216, 255)) {
- color.red = color.green = color.blue = 0x0808 + 0x0a0a * (x - (16 + 216));
- if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &color, &colour))
- return 0; /* something went wrong */
- dc.col[x] = colour;
- return 1;
- } else {
+ if(BETWEEN(x, 16, 16 + 215)) { /* 256 color */
+ color.red = sixd_to_16bit( ((x-16)/36)%6 );
+ color.green = sixd_to_16bit( ((x-16)/6) %6 );
+ color.blue = sixd_to_16bit( ((x-16)/1) %6 );
+ if(!XftColorAllocValue(xw.dpy, xw.vis,
+ xw.cmap, &color, &ncolor)) {
+ return 1;
+ }
+
+ XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]);
+ dc.col[x] = ncolor;
+ return 0;
+ } else if(BETWEEN(x, 16 + 216, 255)) { /* greyscale */
+ color.red = color.green = color.blue = \
+ 0x0808 + 0x0a0a * (x - (16 + 216));
+ if(!XftColorAllocValue(xw.dpy, xw.vis,
+ xw.cmap, &color, &ncolor)) {
+ return 1;
+ }
+
+ XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]);
+ dc.col[x] = ncolor;
+ return 0;
+ } else { /* system colors */
name = colorname[x];
}
}
- if(!XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, &colour))
- return 0;
- dc.col[x] = colour;
- return 1;
+ if(!XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, &ncolor))
+ return 1;
+
+ XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]);
+ dc.col[x] = ncolor;
+ return 0;
}
void
FcPattern *fcpattern, *fontpattern;
FcFontSet *fcsets[] = { NULL };
FcCharSet *fccharset;
- Colour *fg, *bg, *temp, revfg, revbg, truefg, truebg;
+ Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
XRenderColor colfg, colbg;
XRectangle r;
int oneatatime;
}
if(base.mode & ATTR_BOLD) {
- if(BETWEEN(base.fg, 0, 7)) {
- /* basic system colors */
- fg = &dc.col[base.fg + 8];
- } else if(BETWEEN(base.fg, 16, 195)) {
- /* 256 colors */
- fg = &dc.col[base.fg + 36];
- } else if(BETWEEN(base.fg, 232, 251)) {
- /* greyscale */
- fg = &dc.col[base.fg + 4];
- }
/*
- * Those ranges will not be brightened:
- * 8 - 15 – bright system colors
- * 196 - 231 – highest 256 color cube
- * 252 - 255 – brightest colors in greyscale
+ * change basic system colors [0-7]
+ * to bright system colors [8-15]
*/
- font = &dc.bfont;
- frcflags = FRC_BOLD;
+ if(BETWEEN(base.fg, 0, 7))
+ fg = &dc.col[base.fg + 8];
+
+ if(base.mode & ATTR_ITALIC) {
+ font = &dc.ibfont;
+ frcflags = FRC_ITALICBOLD;
+ } else {
+ font = &dc.bfont;
+ frcflags = FRC_BOLD;
+ }
}
if(IS_SET(MODE_REVERSE)) {
redraw(int timeout) {
struct timespec tv = {0, timeout * 1000};
+ tfulldirt();
draw();
if(timeout > 0) {