Compare commits

..

No commits in common. "aa5957495d315a2aca2a846a48ba9f7557353ec5" and "8e96ad302c0609fc79e59386ab5826879712a173" have entirely different histories.

10 changed files with 50 additions and 114 deletions

View File

@ -1,4 +1,4 @@
Similar to [dwm-flexipatch](https://github.com/bakkeby/dwm-flexipatch) this st 0.9.2 (5dbcca4, 2024-05-01) project has a different take on st patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more. Similar to [dwm-flexipatch](https://github.com/bakkeby/dwm-flexipatch) this st 0.9 (95f22c5, 2024-03-04) project has a different take on st patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more.
For example to include the `alpha` patch then you would only need to flip this setting from 0 to 1 in [patches.h](https://github.com/bakkeby/st-flexipatch/blob/master/patches.def.h): For example to include the `alpha` patch then you would only need to flip this setting from 0 to 1 in [patches.h](https://github.com/bakkeby/st-flexipatch/blob/master/patches.def.h):
```c ```c

View File

@ -96,7 +96,7 @@ int allowwindowops = 0;
* near minlatency, but it waits longer for slow updates to avoid partial draw. * near minlatency, but it waits longer for slow updates to avoid partial draw.
* low minlatency will tear/flicker more, as it can "detect" idle too early. * low minlatency will tear/flicker more, as it can "detect" idle too early.
*/ */
static double minlatency = 2; static double minlatency = 8;
static double maxlatency = 33; static double maxlatency = 33;
#if SYNC_PATCH #if SYNC_PATCH

View File

@ -1,5 +1,5 @@
# st version # st version
VERSION = 0.9.2 VERSION = 0.9
# Customize below to fit your system # Customize below to fit your system

View File

@ -42,11 +42,7 @@ externalpipe(const Arg *arg)
newline = 0; newline = 0;
for (n = 0; n < term.row; n++) { for (n = 0; n < term.row; n++) {
bp = term.line[n]; bp = term.line[n];
#if REFLOW_PATCH
lastpos = MIN(tlinelen(TLINE(n)) + 1, term.col) - 1;
#else
lastpos = MIN(tlinelen(n) + 1, term.col) - 1; lastpos = MIN(tlinelen(n) + 1, term.col) - 1;
#endif // REFLOW_PATCH
if (lastpos < 0) if (lastpos < 0)
break; break;
end = &bp[lastpos + 1]; end = &bp[lastpos + 1];

View File

@ -81,7 +81,7 @@ treflow(int col, int row)
int oce, nce, bot, scr; int oce, nce, bot, scr;
int ox = 0, oy = -term.histf, nx = 0, ny = -1, len; int ox = 0, oy = -term.histf, nx = 0, ny = -1, len;
int cy = -1; /* proxy for new y coordinate of cursor */ int cy = -1; /* proxy for new y coordinate of cursor */
int buflen, nlines; int buflen, nlines, del;
Line *buf, bufline, line; Line *buf, bufline, line;
#if SIXEL_PATCH #if SIXEL_PATCH
ImageList *im, *next; ImageList *im, *next;
@ -219,14 +219,21 @@ treflow(int col, int row)
} }
} }
/* expand images into new text cells */ /* expand images into new text cells or
* delete images if there is text behind them */
for (im = term.images; im; im = next) { for (im = term.images; im; im = next) {
next = im->next; next = im->next;
if (im->x < col) { if (im->x < col) {
line = TLINE(im->y); line = TLINE(im->y);
x2 = MIN(im->x + im->cols, col); x2 = MIN(im->x + im->cols, col);
for (x = im->x; x < x2; x++) for (del = 0, x = im->x; x < x2; x++) {
line[x].mode |= ATTR_SIXEL; if ((del = line[x].mode & ATTR_SET))
break;
line[x].u = ' ';
line[x].mode = ATTR_SIXEL;
}
if (del)
delete_image(im);
} }
} }
#endif // SIXEL_PATCH #endif // SIXEL_PATCH

40
sixel.c
View File

@ -66,8 +66,6 @@ delete_image(ImageList *im)
im->next->prev = im->prev; im->next->prev = im->prev;
if (im->pixmap) if (im->pixmap)
XFreePixmap(xw.dpy, (Drawable)im->pixmap); XFreePixmap(xw.dpy, (Drawable)im->pixmap);
if (im->clipmask)
XFreePixmap(xw.dpy, (Drawable)im->clipmask);
free(im->pixels); free(im->pixels);
free(im); free(im);
} }
@ -219,7 +217,6 @@ sixel_image_deinit(sixel_image_t *image)
int int
sixel_parser_init(sixel_state_t *st, sixel_parser_init(sixel_state_t *st,
int transparent,
sixel_color_t fgcolor, sixel_color_t bgcolor, sixel_color_t fgcolor, sixel_color_t bgcolor,
unsigned char use_private_register, unsigned char use_private_register,
int cell_width, int cell_height) int cell_width, int cell_height)
@ -235,7 +232,6 @@ sixel_parser_init(sixel_state_t *st,
st->attributed_pad = 1; st->attributed_pad = 1;
st->attributed_ph = 0; st->attributed_ph = 0;
st->attributed_pv = 0; st->attributed_pv = 0;
st->transparent = transparent;
st->repeat_count = 1; st->repeat_count = 1;
st->color_index = 16; st->color_index = 16;
st->grid_width = cell_width; st->grid_width = cell_width;
@ -244,7 +240,7 @@ sixel_parser_init(sixel_state_t *st,
st->param = 0; st->param = 0;
/* buffer initialization */ /* buffer initialization */
status = sixel_image_init(&st->image, 1, 1, fgcolor, transparent ? 0 : bgcolor, use_private_register); status = sixel_image_init(&st->image, 1, 1, fgcolor, bgcolor, use_private_register);
return status; return status;
} }
@ -308,10 +304,8 @@ sixel_parser_finalize(sixel_state_t *st, ImageList **newimages, int cx, int cy,
im->height = MIN(h - ch * i, ch); im->height = MIN(h - ch * i, ch);
im->pixels = malloc(im->width * im->height * 4); im->pixels = malloc(im->width * im->height * 4);
im->pixmap = NULL; im->pixmap = NULL;
im->clipmask = NULL;
im->cw = cw; im->cw = cw;
im->ch = ch; im->ch = ch;
im->transparent = st->transparent;
} }
if (!im || !im->pixels) { if (!im || !im->pixels) {
for (im = *newimages; im; im = next) { for (im = *newimages; im; im = next) {
@ -658,35 +652,3 @@ sixel_parser_deinit(sixel_state_t *st)
if (st) if (st)
sixel_image_deinit(&st->image); sixel_image_deinit(&st->image);
} }
Pixmap
sixel_create_clipmask(char *pixels, int width, int height)
{
char c, *clipdata, *dst;
int b, i, n, y, w;
int msb = (XBitmapBitOrder(xw.dpy) == MSBFirst);
sixel_color_t *src = (sixel_color_t *)pixels;
Pixmap clipmask;
clipdata = dst = malloc((width+7)/8 * height);
if (!clipdata)
return (Pixmap)None;
for (y = 0; y < height; y++) {
for (w = width; w > 0; w -= n) {
n = MIN(w, 8);
if (msb) {
for (b = 0x80, c = 0, i = 0; i < n; i++, b >>= 1)
c |= (*src++) ? b : 0;
} else {
for (b = 0x01, c = 0, i = 0; i < n; i++, b <<= 1)
c |= (*src++) ? b : 0;
}
*dst++ = c;
}
}
clipmask = XCreateBitmapFromData(xw.dpy, xw.win, clipdata, width, height);
free(clipdata);
return clipmask;
}

View File

@ -39,7 +39,6 @@ typedef struct parser_context {
int attributed_pad; int attributed_pad;
int attributed_ph; int attributed_ph;
int attributed_pv; int attributed_pv;
int transparent;
int repeat_count; int repeat_count;
int color_index; int color_index;
int bgindex; int bgindex;
@ -53,11 +52,10 @@ typedef struct parser_context {
void scroll_images(int n); void scroll_images(int n);
void delete_image(ImageList *im); void delete_image(ImageList *im);
int sixel_parser_init(sixel_state_t *st, int transparent, sixel_color_t fgcolor, sixel_color_t bgcolor, unsigned char use_private_register, int cell_width, int cell_height); int sixel_parser_init(sixel_state_t *st, sixel_color_t fgcolor, sixel_color_t bgcolor, unsigned char use_private_register, int cell_width, int cell_height);
int sixel_parser_parse(sixel_state_t *st, const unsigned char *p, size_t len); int sixel_parser_parse(sixel_state_t *st, const unsigned char *p, size_t len);
int sixel_parser_set_default_color(sixel_state_t *st); int sixel_parser_set_default_color(sixel_state_t *st);
int sixel_parser_finalize(sixel_state_t *st, ImageList **newimages, int cx, int cy, int cw, int ch); int sixel_parser_finalize(sixel_state_t *st, ImageList **newimages, int cx, int cy, int cw, int ch);
void sixel_parser_deinit(sixel_state_t *st); void sixel_parser_deinit(sixel_state_t *st);
Pixmap sixel_create_clipmask(char *pixels, int width, int height);
#endif #endif

36
st.c
View File

@ -1498,7 +1498,6 @@ csiparse(void)
{ {
char *p = csiescseq.buf, *np; char *p = csiescseq.buf, *np;
long int v; long int v;
int sep = ';'; /* colon or semi-colon, but not both */
csiescseq.narg = 0; csiescseq.narg = 0;
if (*p == '?') { if (*p == '?') {
@ -1519,9 +1518,7 @@ csiparse(void)
#if UNDERCURL_PATCH #if UNDERCURL_PATCH
readcolonargs(&p, csiescseq.narg-1, csiescseq.carg); readcolonargs(&p, csiescseq.narg-1, csiescseq.carg);
#endif // UNDERCURL_PATCH #endif // UNDERCURL_PATCH
if (sep == ';' && *p == ':') if (*p != ';' || csiescseq.narg == ESC_ARG_SIZ)
sep = ':'; /* allow override to colon once */
if (*p != sep || csiescseq.narg == ESC_ARG_SIZ)
break; break;
p++; p++;
} }
@ -2230,8 +2227,10 @@ csihandle(void)
/* vte does this: /* vte does this:
tscrollup(0, term.row-1, term.row, SCROLL_SAVEHIST); */ tscrollup(0, term.row-1, term.row, SCROLL_SAVEHIST); */
/* alacritty does this: */ /* alacritty does this: */
#if KEYBOARDSELECT_PATCH
for (n = term.row-1; n >= 0 && tlinelen(term.line[n]) == 0; n--) for (n = term.row-1; n >= 0 && tlinelen(term.line[n]) == 0; n--)
; ;
#endif // KEYBOARDSELECT_PATCH
#if SIXEL_PATCH #if SIXEL_PATCH
for (im = term.images; im; im = im->next) for (im = term.images; im; im = im->next)
n = MAX(im->y - term.scr, n); n = MAX(im->y - term.scr, n);
@ -2717,9 +2716,6 @@ strhandle(void)
y1 = newimages->y; y1 = newimages->y;
x2 = x1 + newimages->cols; x2 = x1 + newimages->cols;
y2 = y1 + numimages; y2 = y1 + numimages;
if (newimages->transparent) {
for (tail = term.images; tail && tail->next; tail = tail->next);
} else {
for (tail = NULL, im = term.images; im; im = next) { for (tail = NULL, im = term.images; im; im = next) {
next = im->next; next = im->next;
if (im->x >= x1 && im->x + im->cols <= x2 && if (im->x >= x1 && im->x + im->cols <= x2 &&
@ -2729,7 +2725,6 @@ strhandle(void)
} }
tail = im; tail = im;
} }
}
if (tail) { if (tail) {
tail->next = newimages; tail->next = newimages;
newimages->prev = tail; newimages->prev = tail;
@ -2754,7 +2749,8 @@ strhandle(void)
line = term.line[term.c.y]; line = term.line[term.c.y];
} }
for (x = im->x; x < x2; x++) { for (x = im->x; x < x2; x++) {
line[x].mode |= ATTR_SIXEL; line[x].u = ' ';
line[x].mode = ATTR_SIXEL;
} }
term.dirty[MIN(im->y, term.row-1)] = 1; term.dirty[MIN(im->y, term.row-1)] = 1;
if (!IS_SET(MODE_SIXEL_SDM) && i < numimages-1) { if (!IS_SET(MODE_SIXEL_SDM) && i < numimages-1) {
@ -3103,7 +3099,7 @@ tcontrolcode(uchar ascii)
void void
dcshandle(void) dcshandle(void)
{ {
int bgcolor, transparent; int bgcolor;
unsigned char r, g, b, a = 255; unsigned char r, g, b, a = 255;
switch (csiescseq.mode[0]) { switch (csiescseq.mode[0]) {
@ -3125,7 +3121,6 @@ dcshandle(void)
break; break;
#endif // SYNC_PATCH #endif // SYNC_PATCH
case 'q': /* DECSIXEL */ case 'q': /* DECSIXEL */
transparent = (csiescseq.narg >= 2 && csiescseq.arg[1] == 1);
if (IS_TRUECOL(term.c.attr.bg)) { if (IS_TRUECOL(term.c.attr.bg)) {
r = term.c.attr.bg >> 16 & 255; r = term.c.attr.bg >> 16 & 255;
g = term.c.attr.bg >> 8 & 255; g = term.c.attr.bg >> 8 & 255;
@ -3136,7 +3131,7 @@ dcshandle(void)
a = dc.col[defaultbg].pixel >> 24 & 255; a = dc.col[defaultbg].pixel >> 24 & 255;
} }
bgcolor = a << 24 | r << 16 | g << 8 | b; bgcolor = a << 24 | r << 16 | g << 8 | b;
if (sixel_parser_init(&sixel_st, transparent, (255 << 24), bgcolor, 1, win.cw, win.ch) != 0) if (sixel_parser_init(&sixel_st, (255 << 24), bgcolor, 1, win.cw, win.ch) != 0)
perror("sixel_parser_init() failed"); perror("sixel_parser_init() failed");
term.mode |= MODE_SIXEL; term.mode |= MODE_SIXEL;
break; break;
@ -3639,8 +3634,10 @@ tresize(int col, int row)
line = term.line[im->y]; line = term.line[im->y];
#endif // SCROLLBACK_PATCH #endif // SCROLLBACK_PATCH
x2 = MIN(im->x + im->cols, term.col); x2 = MIN(im->x + im->cols, term.col);
for (x = im->x; x < x2; x++) for (x = im->x; x < x2; x++) {
line[x].mode |= ATTR_SIXEL; line[x].u = ' ';
line[x].mode = ATTR_SIXEL;
}
} }
tswapscreen(); tswapscreen();
} }
@ -3697,10 +3694,12 @@ draw(void)
drawregion(0, 0, term.col, term.row); drawregion(0, 0, term.col, term.row);
#if KEYBOARDSELECT_PATCH && REFLOW_PATCH #if KEYBOARDSELECT_PATCH && REFLOW_PATCH
if (!kbds_drawcursor()) if (!kbds_drawcursor()) {
#elif REFLOW_PATCH || SCROLLBACK_PATCH #endif // KEYBOARDSELECT_PATCH
#if SCROLLBACK_PATCH
if (term.scr == 0) if (term.scr == 0)
#endif // SCROLLBACK_PATCH | REFLOW_PATCH | KEYBOARDSELECT_PATCH #endif // SCROLLBACK_PATCH
#if LIGATURES_PATCH #if LIGATURES_PATCH
xdrawcursor(cx, term.c.y, term.line[term.c.y][cx], xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
term.ocx, term.ocy, term.line[term.ocy][term.ocx], term.ocx, term.ocy, term.line[term.ocy][term.ocx],
@ -3709,6 +3708,9 @@ draw(void)
xdrawcursor(cx, term.c.y, term.line[term.c.y][cx], xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
term.ocx, term.ocy, term.line[term.ocy][term.ocx]); term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
#endif // LIGATURES_PATCH #endif // LIGATURES_PATCH
#if KEYBOARDSELECT_PATCH && REFLOW_PATCH
}
#endif // KEYBOARDSELECT_PATCH
term.ocx = cx; term.ocx = cx;
term.ocy = term.c.y; term.ocy = term.c.y;
xfinishdraw(); xfinishdraw();

2
st.h
View File

@ -77,7 +77,6 @@ typedef struct _ImageList {
struct _ImageList *next, *prev; struct _ImageList *next, *prev;
unsigned char *pixels; unsigned char *pixels;
void *pixmap; void *pixmap;
void *clipmask;
int width; int width;
int height; int height;
int x; int x;
@ -88,7 +87,6 @@ typedef struct _ImageList {
int cols; int cols;
int cw; int cw;
int ch; int ch;
int transparent;
} ImageList; } ImageList;
#endif // SIXEL_PATCH #endif // SIXEL_PATCH

43
x.c
View File

@ -325,10 +325,7 @@ zoomabs(const Arg *arg)
for (im = term.images; im; im = im->next) { for (im = term.images; im; im = im->next) {
if (im->pixmap) if (im->pixmap)
XFreePixmap(xw.dpy, (Drawable)im->pixmap); XFreePixmap(xw.dpy, (Drawable)im->pixmap);
if (im->clipmask)
XFreePixmap(xw.dpy, (Drawable)im->clipmask);
im->pixmap = NULL; im->pixmap = NULL;
im->clipmask = NULL;
} }
#endif // SIXEL_PATCH #endif // SIXEL_PATCH
@ -1021,9 +1018,6 @@ xloadcols(void)
dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha); dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha);
dc.col[defaultbg].pixel &= 0x00FFFFFF; dc.col[defaultbg].pixel &= 0x00FFFFFF;
dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24; dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24;
dc.col[defaultbg].color.red *= alpha;
dc.col[defaultbg].color.green *= alpha;
dc.col[defaultbg].color.blue *= alpha;
#endif // ALPHA_PATCH #endif // ALPHA_PATCH
loaded = 1; loaded = 1;
} }
@ -1064,9 +1058,6 @@ xsetcolorname(int x, const char *name)
dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha); dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha);
dc.col[defaultbg].pixel &= 0x00FFFFFF; dc.col[defaultbg].pixel &= 0x00FFFFFF;
dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24; dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24;
dc.col[defaultbg].color.red *= alpha;
dc.col[defaultbg].color.green *= alpha;
dc.col[defaultbg].color.blue *= alpha;
} }
#endif // ALPHA_PATCH #endif // ALPHA_PATCH
return 0; return 0;
@ -2863,9 +2854,6 @@ xseticontitle(char *p)
XTextProperty prop; XTextProperty prop;
DEFAULT(p, opt_title); DEFAULT(p, opt_title);
if (p[0] == '\0')
p = opt_title;
if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
&prop) != Success) &prop) != Success)
return; return;
@ -2885,7 +2873,7 @@ xsettitle(char *p, int pop)
titlestack[tstki] = NULL; titlestack[tstki] = NULL;
tstki = (tstki - 1 + TITLESTACKSIZE) % TITLESTACKSIZE; tstki = (tstki - 1 + TITLESTACKSIZE) % TITLESTACKSIZE;
p = titlestack[tstki] ? titlestack[tstki] : opt_title; p = titlestack[tstki] ? titlestack[tstki] : opt_title;
} else if (p && p[0] != '\0') { } else if (p) {
titlestack[tstki] = xstrdup(p); titlestack[tstki] = xstrdup(p);
} else { } else {
titlestack[tstki] = NULL; titlestack[tstki] = NULL;
@ -2925,9 +2913,6 @@ xsettitle(char *p)
XTextProperty prop; XTextProperty prop;
DEFAULT(p, opt_title); DEFAULT(p, opt_title);
if (p[0] == '\0')
p = opt_title;
if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
&prop) != Success) &prop) != Success)
return; return;
@ -3141,7 +3126,7 @@ xfinishdraw(void)
XGCValues gcvalues; XGCValues gcvalues;
GC gc; GC gc;
int width, height; int width, height;
int x, x2, del, destx, desty; int x, x2, del;
Line line; Line line;
#endif // SIXEL_PATCH #endif // SIXEL_PATCH
@ -3154,8 +3139,8 @@ xfinishdraw(void)
continue; continue;
/* scale the image */ /* scale the image */
width = MAX(im->width * win.cw / im->cw, 1); width = im->width * win.cw / im->cw;
height = MAX(im->height * win.ch / im->ch, 1); height = im->height * win.ch / im->ch;
if (!im->pixmap) { if (!im->pixmap) {
im->pixmap = (void *)XCreatePixmap(xw.dpy, xw.win, width, height, im->pixmap = (void *)XCreatePixmap(xw.dpy, xw.win, width, height,
#if ALPHA_PATCH #if ALPHA_PATCH
@ -3164,8 +3149,6 @@ xfinishdraw(void)
DefaultDepth(xw.dpy, xw.scr) DefaultDepth(xw.dpy, xw.scr)
#endif // ALPHA_PATCH #endif // ALPHA_PATCH
); );
if (!im->pixmap)
continue;
if (win.cw == im->cw && win.ch == im->ch) { if (win.cw == im->cw && win.ch == im->ch) {
XImage ximage = { XImage ximage = {
.format = ZPixmap, .format = ZPixmap,
@ -3186,15 +3169,12 @@ xfinishdraw(void)
#endif // ALPHA_PATCH #endif // ALPHA_PATCH
}; };
XPutImage(xw.dpy, (Drawable)im->pixmap, dc.gc, &ximage, 0, 0, 0, 0, width, height); XPutImage(xw.dpy, (Drawable)im->pixmap, dc.gc, &ximage, 0, 0, 0, 0, width, height);
if (im->transparent)
im->clipmask = (void *)sixel_create_clipmask((char *)im->pixels, width, height);
} else { } else {
origin = imlib_create_image_using_data(im->width, im->height, (DATA32 *)im->pixels); origin = imlib_create_image_using_data(im->width, im->height, (DATA32 *)im->pixels);
if (!origin) if (!origin)
continue; continue;
imlib_context_set_image(origin); imlib_context_set_image(origin);
imlib_image_set_has_alpha(1); imlib_image_set_has_alpha(1);
imlib_context_set_anti_alias(im->transparent ? 0 : 1); /* anti-aliasing messes up the clip mask */
scaled = imlib_create_cropped_scaled_image(0, 0, im->width, im->height, width, height); scaled = imlib_create_cropped_scaled_image(0, 0, im->width, im->height, width, height);
imlib_free_image_and_decache(); imlib_free_image_and_decache();
if (!scaled) if (!scaled)
@ -3220,8 +3200,6 @@ xfinishdraw(void)
#endif // ALPHA_PATCH #endif // ALPHA_PATCH
}; };
XPutImage(xw.dpy, (Drawable)im->pixmap, dc.gc, &ximage, 0, 0, 0, 0, width, height); XPutImage(xw.dpy, (Drawable)im->pixmap, dc.gc, &ximage, 0, 0, 0, 0, width, height);
if (im->transparent)
im->clipmask = (void *)sixel_create_clipmask((char *)imlib_image_get_data_for_reading_only(), width, height);
imlib_free_image_and_decache(); imlib_free_image_and_decache();
} }
} }
@ -3250,17 +3228,12 @@ xfinishdraw(void)
gcvalues.graphics_exposures = False; gcvalues.graphics_exposures = False;
gc = XCreateGC(xw.dpy, xw.win, GCGraphicsExposures, &gcvalues); gc = XCreateGC(xw.dpy, xw.win, GCGraphicsExposures, &gcvalues);
#if ANYSIZE_PATCH #if ANYSIZE_PATCH
destx = win.hborderpx + im->x * win.cw; XCopyArea(xw.dpy, (Drawable)im->pixmap, xw.buf, gc, 0, 0,
desty = win.vborderpx + im->y * win.ch; width, height, win.hborderpx + im->x * win.cw, win.vborderpx + im->y * win.ch);
#else #else
destx = borderpx + im->x * win.cw; XCopyArea(xw.dpy, (Drawable)im->pixmap, xw.buf, gc, 0, 0,
desty = borderpx + im->y * win.ch; width, height, borderpx + im->x * win.cw, borderpx + im->y * win.ch);
#endif // ANYSIZE_PATCH #endif // ANYSIZE_PATCH
if (im->clipmask) {
XSetClipMask(xw.dpy, gc, (Drawable)im->clipmask);
XSetClipOrigin(xw.dpy, gc, destx, desty);
}
XCopyArea(xw.dpy, (Drawable)im->pixmap, xw.buf, gc, 0, 0, width, height, destx, desty);
XFreeGC(xw.dpy, gc); XFreeGC(xw.dpy, gc);
} }
#endif // SIXEL_PATCH #endif // SIXEL_PATCH