parent
0b10705240
commit
e9398f8471
6 changed files with 84 additions and 47 deletions
|
@ -231,8 +231,8 @@ static MouseShortcut mshortcuts[] = {
|
||||||
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
|
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
|
||||||
{ ShiftMask, Button4, kscrollup, {.i = 1}, 0, S_PRI},
|
{ ShiftMask, Button4, kscrollup, {.i = 1}, 0, S_PRI},
|
||||||
{ ShiftMask, Button5, kscrolldown, {.i = 1}, 0, S_PRI},
|
{ ShiftMask, Button5, kscrolldown, {.i = 1}, 0, S_PRI},
|
||||||
{ XK_NO_MOD, Button4, kscrollup, {.i = 1}, 0, S_PRI },
|
{ XK_ANY_MOD, Button4, kscrollup, {.i = 1}, 0, S_PRI },
|
||||||
{ XK_NO_MOD, Button5, kscrolldown, {.i = 1}, 0, S_PRI },
|
{ XK_ANY_MOD, Button5, kscrolldown, {.i = 1}, 0, S_PRI },
|
||||||
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"}, 0, S_ALT },
|
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"}, 0, S_ALT },
|
||||||
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"}, 0, S_ALT },
|
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"}, 0, S_ALT },
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,15 @@
|
||||||
|
extern char* argv0;
|
||||||
|
|
||||||
|
static char*
|
||||||
|
getcwd_by_pid(pid_t pid) {
|
||||||
|
static char cwd[32];
|
||||||
|
snprintf(cwd, sizeof cwd, "/proc/%d/cwd", pid);
|
||||||
|
return cwd;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
newterm(const Arg* a)
|
newterm(const Arg* a)
|
||||||
{
|
{
|
||||||
int res;
|
|
||||||
switch (fork()) {
|
switch (fork()) {
|
||||||
case -1:
|
case -1:
|
||||||
die("fork failed: %s\n", strerror(errno));
|
die("fork failed: %s\n", strerror(errno));
|
||||||
|
@ -12,19 +20,12 @@ newterm(const Arg* a)
|
||||||
die("fork failed: %s\n", strerror(errno));
|
die("fork failed: %s\n", strerror(errno));
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
res = chdir(getcwd_by_pid(pid));
|
chdir(getcwd_by_pid(pid));
|
||||||
execlp("st", "./st", NULL);
|
|
||||||
break;
|
execl("/proc/self/exe", argv0, NULL);
|
||||||
|
exit(1);
|
||||||
default:
|
default:
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
wait(NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *getcwd_by_pid(pid_t pid) {
|
|
||||||
char buf[32];
|
|
||||||
snprintf(buf, sizeof buf, "/proc/%d/cwd", pid);
|
|
||||||
return realpath(buf, NULL);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
void newterm(const Arg *);
|
void newterm(const Arg *);
|
||||||
static char *getcwd_by_pid(pid_t pid);
|
|
||||||
|
|
15
sixel.c
15
sixel.c
|
@ -256,10 +256,10 @@ sixel_parser_finalize(sixel_state_t *st, ImageList **newimages, int cx, int cy,
|
||||||
sixel_image_t *image = &st->image;
|
sixel_image_t *image = &st->image;
|
||||||
int x, y;
|
int x, y;
|
||||||
sixel_color_no_t *src;
|
sixel_color_no_t *src;
|
||||||
sixel_color_t *dst;
|
sixel_color_t *dst, color;
|
||||||
int color;
|
|
||||||
int w, h;
|
int w, h;
|
||||||
int i, j, cols, numimages;
|
int i, j, cols, numimages;
|
||||||
|
char trans;
|
||||||
ImageList *im, *next, *tail;
|
ImageList *im, *next, *tail;
|
||||||
|
|
||||||
if (!image->data)
|
if (!image->data)
|
||||||
|
@ -306,7 +306,6 @@ sixel_parser_finalize(sixel_state_t *st, ImageList **newimages, int cx, int cy,
|
||||||
im->clipmask = 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) {
|
||||||
|
@ -319,11 +318,15 @@ sixel_parser_finalize(sixel_state_t *st, ImageList **newimages, int cx, int cy,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
dst = (sixel_color_t *)im->pixels;
|
dst = (sixel_color_t *)im->pixels;
|
||||||
for (j = 0; j < im->height && y < h; j++, y++) {
|
for (trans = 0, j = 0; j < im->height && y < h; j++, y++) {
|
||||||
src = st->image.data + image->width * y;
|
src = st->image.data + image->width * y;
|
||||||
for (x = 0; x < w; x++)
|
for (x = 0; x < w; x++) {
|
||||||
*dst++ = st->image.palette[*src++];
|
color = st->image.palette[*src++];
|
||||||
|
trans |= (color == 0);
|
||||||
|
*dst++ = color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
im->transparent = (st->transparent && trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
return numimages;
|
return numimages;
|
||||||
|
|
75
st.c
75
st.c
|
@ -558,17 +558,16 @@ sigchld(int a)
|
||||||
int stat;
|
int stat;
|
||||||
pid_t p;
|
pid_t p;
|
||||||
|
|
||||||
if ((p = waitpid(pid, &stat, WNOHANG)) < 0)
|
while ((p = waitpid(-1, &stat, WNOHANG)) > 0) {
|
||||||
die("waiting for pid %hd failed: %s\n", pid, strerror(errno));
|
if (p == pid) {
|
||||||
|
|
||||||
if (pid != p)
|
if (WIFEXITED(stat) && WEXITSTATUS(stat))
|
||||||
return;
|
die("child exited with status %d\n", WEXITSTATUS(stat));
|
||||||
|
else if (WIFSIGNALED(stat))
|
||||||
if (WIFEXITED(stat) && WEXITSTATUS(stat))
|
die("child terminated due to signal %d\n", WTERMSIG(stat));
|
||||||
die("child exited with status %d\n", WEXITSTATUS(stat));
|
_exit(0);
|
||||||
else if (WIFSIGNALED(stat))
|
}
|
||||||
die("child terminated due to signal %d\n", WTERMSIG(stat));
|
}
|
||||||
_exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -599,6 +598,7 @@ int
|
||||||
ttynew(const char *line, char *cmd, const char *out, char **args)
|
ttynew(const char *line, char *cmd, const char *out, char **args)
|
||||||
{
|
{
|
||||||
int m, s;
|
int m, s;
|
||||||
|
struct sigaction sa;
|
||||||
|
|
||||||
if (out) {
|
if (out) {
|
||||||
term.mode |= MODE_PRINT;
|
term.mode |= MODE_PRINT;
|
||||||
|
@ -651,7 +651,10 @@ ttynew(const char *line, char *cmd, const char *out, char **args)
|
||||||
#endif
|
#endif
|
||||||
close(s);
|
close(s);
|
||||||
cmdfd = m;
|
cmdfd = m;
|
||||||
signal(SIGCHLD, sigchld);
|
memset(&sa, 0, sizeof(sa));
|
||||||
|
sigemptyset(&sa.sa_mask);
|
||||||
|
sa.sa_handler = sigchld;
|
||||||
|
sigaction(SIGCHLD, &sa, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return cmdfd;
|
return cmdfd;
|
||||||
|
@ -1500,7 +1503,7 @@ csihandle(void)
|
||||||
tclearregion(0, term.c.y+1, term.col-1, term.row-1, 1);
|
tclearregion(0, term.c.y+1, term.col-1, term.row-1, 1);
|
||||||
break;
|
break;
|
||||||
case 1: /* above */
|
case 1: /* above */
|
||||||
if (term.c.y >= 1)
|
if (term.c.y > 0)
|
||||||
tclearregion(0, 0, term.col-1, term.c.y-1, 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, term.c.y, term.c.x, term.c.y, 1);
|
||||||
break;
|
break;
|
||||||
|
@ -1778,8 +1781,8 @@ strhandle(void)
|
||||||
{ defaultbg, "background" },
|
{ defaultbg, "background" },
|
||||||
{ defaultcs, "cursor" }
|
{ defaultcs, "cursor" }
|
||||||
};
|
};
|
||||||
ImageList *im, *newimages, *next, *tail;
|
ImageList *im, *newimages, *next, *tail = NULL;
|
||||||
int i, x1, y1, x2, y2, numimages;
|
int i, x1, y1, x2, y2, y, numimages;
|
||||||
int cx, cy;
|
int cx, cy;
|
||||||
Line line;
|
Line line;
|
||||||
int scr = IS_SET(MODE_ALTSCREEN) ? 0 : term.scr;
|
int scr = IS_SET(MODE_ALTSCREEN) ? 0 : term.scr;
|
||||||
|
@ -1886,15 +1889,33 @@ 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) {
|
/* Delete the old images that are covered by the new image(s). We also need
|
||||||
for (tail = term.images; tail && tail->next; tail = tail->next);
|
* to check if they have already been deleted before adding the new ones. */
|
||||||
} else {
|
if (term.images) {
|
||||||
for (tail = NULL, im = term.images; im; im = next) {
|
char transparent[numimages];
|
||||||
|
for (i = 0, im = newimages; im; im = im->next, i++) {
|
||||||
|
transparent[i] = im->transparent;
|
||||||
|
}
|
||||||
|
for (im = term.images; im; im = next) {
|
||||||
next = im->next;
|
next = im->next;
|
||||||
if (im->x >= x1 && im->x + im->cols <= x2 &&
|
if (im->y >= y1 && im->y < y2) {
|
||||||
im->y >= y1 && im->y <= y2) {
|
y = im->y - scr;
|
||||||
delete_image(im);
|
if (y >= 0 && y < term.row && term.dirty[y]) {
|
||||||
continue;
|
line = term.line[y];
|
||||||
|
j = MIN(im->x + im->cols, term.col);
|
||||||
|
for (i = im->x; i < j; i++) {
|
||||||
|
if (line[i].mode & ATTR_SIXEL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == j) {
|
||||||
|
delete_image(im);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (im->x >= x1 && im->x + im->cols <= x2 && !transparent[im->y - y1]) {
|
||||||
|
delete_image(im);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tail = im;
|
tail = im;
|
||||||
}
|
}
|
||||||
|
@ -1965,6 +1986,16 @@ strparse(void)
|
||||||
if (*p == '\0')
|
if (*p == '\0')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* preserve semicolons in window titles, icon names and OSC 7 sequences */
|
||||||
|
if (strescseq.type == ']' && (
|
||||||
|
p[0] <= '2'
|
||||||
|
) && p[1] == ';') {
|
||||||
|
strescseq.args[strescseq.narg++] = p;
|
||||||
|
strescseq.args[strescseq.narg++] = p + 2;
|
||||||
|
p[1] = '\0';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while (strescseq.narg < STR_ARG_SIZ) {
|
while (strescseq.narg < STR_ARG_SIZ) {
|
||||||
strescseq.args[strescseq.narg++] = p;
|
strescseq.args[strescseq.narg++] = p;
|
||||||
while ((c = *p) != ';' && c != '\0')
|
while ((c = *p) != ';' && c != '\0')
|
||||||
|
|
11
x.c
11
x.c
|
@ -1148,7 +1148,7 @@ xinit(int cols, int rows)
|
||||||
{
|
{
|
||||||
XGCValues gcvalues;
|
XGCValues gcvalues;
|
||||||
Pixmap blankpm;
|
Pixmap blankpm;
|
||||||
Window parent;
|
Window parent, root;
|
||||||
pid_t thispid = getpid();
|
pid_t thispid = getpid();
|
||||||
|
|
||||||
if (!(xw.dpy = XOpenDisplay(NULL)))
|
if (!(xw.dpy = XOpenDisplay(NULL)))
|
||||||
|
@ -1190,17 +1190,20 @@ xinit(int cols, int rows)
|
||||||
xw.attrs.colormap = xw.cmap;
|
xw.attrs.colormap = xw.cmap;
|
||||||
xw.attrs.event_mask |= PointerMotionMask;
|
xw.attrs.event_mask |= PointerMotionMask;
|
||||||
|
|
||||||
|
root = XRootWindow(xw.dpy, xw.scr);
|
||||||
if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0))))
|
if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0))))
|
||||||
parent = XRootWindow(xw.dpy, xw.scr);
|
parent = root;
|
||||||
xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t,
|
xw.win = XCreateWindow(xw.dpy, root, xw.l, xw.t,
|
||||||
win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
|
win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
|
||||||
xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
|
xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
|
||||||
| CWEventMask | CWColormap, &xw.attrs);
|
| CWEventMask | CWColormap, &xw.attrs);
|
||||||
|
if (parent != root)
|
||||||
|
XReparentWindow(xw.dpy, xw.win, parent, xw.l, xw.t);
|
||||||
|
|
||||||
memset(&gcvalues, 0, sizeof(gcvalues));
|
memset(&gcvalues, 0, sizeof(gcvalues));
|
||||||
gcvalues.graphics_exposures = False;
|
gcvalues.graphics_exposures = False;
|
||||||
|
|
||||||
dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
|
dc.gc = XCreateGC(xw.dpy, xw.win, GCGraphicsExposures,
|
||||||
&gcvalues);
|
&gcvalues);
|
||||||
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
|
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
|
||||||
DefaultDepth(xw.dpy, xw.scr));
|
DefaultDepth(xw.dpy, xw.scr));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue