summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <koverstreet@google.com>2013-03-16 19:13:08 -0700
committerKent Overstreet <koverstreet@google.com>2013-03-23 19:16:45 -0700
commit23cc1e25c3df0344eb1b70700acdadd7561078cd (patch)
treeb20ae499f27d013f49b3ddc4c044e9fb4751f99d
parentf77fd7f5a246083e8e253d6b5b621b8e45631c25 (diff)
Kill some globals
-rw-r--r--st.c1891
1 files changed, 968 insertions, 923 deletions
diff --git a/st.c b/st.c
index fa77627..b579c1e 100644
--- a/st.c
+++ b/st.c
@@ -96,7 +96,6 @@
#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b))
#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg)
-#define IS_SET(flag) ((term.mode & (flag)) != 0)
#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + (t1.tv_usec-t2.tv_usec)/1000)
#define VT102ID "\033[?6c"
@@ -111,11 +110,6 @@ enum glyph_attribute {
ATTR_BLINK = 32,
};
-enum cursor_movement {
- CURSOR_SAVE,
- CURSOR_LOAD
-};
-
enum cursor_state {
CURSOR_DEFAULT = 0,
CURSOR_WRAPNEXT = 1,
@@ -127,6 +121,7 @@ enum glyph_state {
GLYPH_DIRTY = 2
};
+/* XXX: kill, replace with bitfields */
enum term_mode {
MODE_WRAP = 1,
MODE_INSERT = 2,
@@ -200,33 +195,55 @@ struct str_escape {
int narg; /* nb of args */
};
+/* TODO: use better name for vars... */
+struct st_selection {
+ int mode;
+ int type;
+ int bx, by;
+ int ex, ey;
+ struct {
+ int x, y;
+ } b, e;
+ char *clip;
+ Atom xtarget;
+ bool alt;
+ struct timeval tclick1;
+ struct timeval tclick2;
+};
+
/* Internal representation of the screen */
struct st_term {
+ int cmdfd;
+ unsigned char cmdbuf[BUFSIZ];
+ unsigned cmdbuflen;
+
int row; /* nb row */
int col; /* nb col */
struct glyph **line; /* screen */
struct glyph **alt; /* alternate screen */
bool *dirty; /* dirtyness of lines */
struct tcursor c; /* cursor */
+ struct tcursor saved;
int top; /* top scroll limit */
int bot; /* bottom scroll limit */
int mode; /* terminal mode flags */
int esc; /* escape state flags */
bool numlock;/* lock numbers in keyboard */
bool *tabs;
+ struct st_selection sel;
};
/* Font structure */
struct st_font {
- int height;
- int width;
- int ascent;
- int descent;
- short lbearing;
- short rbearing;
- XftFont *match;
- FcFontSet *set;
- FcPattern *pattern;
+ int height;
+ int width;
+ int ascent;
+ int descent;
+ short lbearing;
+ short rbearing;
+ XftFont *match;
+ FcFontSet *set;
+ FcPattern *pattern;
};
struct st_key {
@@ -239,22 +256,6 @@ struct st_key {
signed char crlf; /* crlf mode */
};
-/* TODO: use better name for vars... */
-struct st_selection {
- int mode;
- int type;
- int bx, by;
- int ex, ey;
- struct {
- int x, y;
- } b, e;
- char *clip;
- Atom xtarget;
- bool alt;
- struct timeval tclick1;
- struct timeval tclick2;
-};
-
union st_arg {
int i;
unsigned int ui;
@@ -262,24 +263,28 @@ union st_arg {
const void *v;
};
+struct st_window;
+
struct st_shortcut {
unsigned int mod;
KeySym keysym;
- void (*func) (const union st_arg *);
+ void (*func) (struct st_window *, const union st_arg *);
const union st_arg arg;
};
/* function definitions used in config.h */
-static void clippaste(const union st_arg *);
-static void numlock(const union st_arg *);
-static void selpaste(const union st_arg *);
-static void xzoom(const union st_arg *);
+static void clippaste(struct st_window *, const union st_arg *);
+static void selpaste(struct st_window *, const union st_arg *);
+static void numlock(struct st_window *, const union st_arg *);
+static void xzoom(struct st_window *, const union st_arg *);
/* Config.h for applying patches and the configuration. */
#include "config.h"
-/* Purely graphic info */
struct st_window {
+ struct st_term term;
+
+ /* Graphic info */
XftColor col[ARRAY_SIZE(colorname) < 256 ? 256 : ARRAY_SIZE(colorname)];
GC gc;
Display *dpy;
@@ -292,6 +297,10 @@ struct st_window {
XIC xic;
XftDraw *draw;
Visual *vis;
+ char *default_title;
+ char *class;
+ char *embed;
+
struct st_font font, bfont, ifont, ibfont;
int scr;
@@ -305,46 +314,12 @@ struct st_window {
};
/* Globals */
-static struct st_window xw;
-static struct st_term term;
-static struct csi_escape csiescseq;
-static struct str_escape strescseq;
-static int cmdfd;
static pid_t pid;
-static struct st_selection sel;
static int iofd = -1;
static char **opt_cmd = NULL;
static char *opt_io = NULL;
-static char *opt_title = NULL;
-static char *opt_embed = NULL;
-static char *opt_class = NULL;
static char *opt_font = NULL;
-static char *usedfont = NULL;
-static int usedfontsize = 0;
-
-/* Font Ring Cache */
-enum {
- FRC_NORMAL,
- FRC_ITALIC,
- FRC_BOLD,
- FRC_ITALICBOLD
-};
-
-struct st_fontcache {
- XftFont *font;
- long c;
- int flags;
-};
-
-/*
- * Fontcache is a ring buffer, with frccur as current position and frclen as
- * the current length of used elements.
- */
-
-static struct st_fontcache frc[1024];
-static int frccur = -1, frclen = 0;
-
/* Random utility code */
static void die(const char *errstr, ...)
@@ -357,7 +332,7 @@ static void die(const char *errstr, ...)
exit(EXIT_FAILURE);
}
-static void execsh(void)
+static void execsh(unsigned long windowid)
{
char **args;
char *envshell = getenv("SHELL");
@@ -375,7 +350,7 @@ static void execsh(void)
setenv("HOME", pass->pw_dir, 0);
}
- snprintf(buf, sizeof(buf), "%lu", xw.win);
+ snprintf(buf, sizeof(buf), "%lu", windowid);
setenv("WINDOWID", buf, 1);
signal(SIGCHLD, SIG_DFL);
@@ -400,11 +375,10 @@ static void sigchld(int a)
if (waitpid(pid, &stat, 0) < 0)
die("Waiting for pid %hd failed: %s\n", pid, SERRNO);
- if (WIFEXITED(stat)) {
+ if (WIFEXITED(stat))
exit(WEXITSTATUS(stat));
- } else {
+ else
exit(EXIT_FAILURE);
- }
}
static ssize_t xwrite(int fd, char *s, size_t len)
@@ -475,7 +449,8 @@ static bool match(unsigned mask, uint state)
return true;
}
-static int xsetcolorname(int x, const char *name)
+static int xsetcolorname(struct st_window *xw,
+ int x, const char *name)
{
XRenderColor color = {.alpha = 0xffff };
XftColor colour;
@@ -488,143 +463,141 @@ static int xsetcolorname(int x, const char *name)
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))
+ if (!XftColorAllocValue(xw->dpy, xw->vis,
+ xw->cmap, &color, &colour))
return 0; /* something went wrong */
- xw.col[x] = colour;
+ xw->col[x] = colour;
return 1;
} else if (16 + 216 <= x && x < 256) {
color.red = color.green = color.blue =
0x0808 + 0x0a0a * (x - (16 + 216));
- if (!XftColorAllocValue
- (xw.dpy, xw.vis, xw.cmap, &color, &colour))
+ if (!XftColorAllocValue(xw->dpy, xw->vis,
+ xw->cmap, &color, &colour))
return 0; /* something went wrong */
- xw.col[x] = colour;
+ xw->col[x] = colour;
return 1;
} else {
name = colorname[x];
}
}
- if (!XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, &colour))
+ if (!XftColorAllocName(xw->dpy, xw->vis, xw->cmap, name, &colour))
return 0;
- xw.col[x] = colour;
+ xw->col[x] = colour;
return 1;
}
-static void xsettitle(char *p)
+static void xsettitle(struct st_window *xw, char *p)
{
XTextProperty prop;
- Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
+ Xutf8TextListToTextProperty(xw->dpy, &p, 1, XUTF8StringStyle,
&prop);
- XSetWMName(xw.dpy, xw.win, &prop);
+ XSetWMName(xw->dpy, xw->win, &prop);
}
-static void xresettitle(void)
+static void xresettitle(struct st_window *xw)
{
- xsettitle(opt_title ? opt_title : "st");
+ xsettitle(xw, xw->default_title);
}
-static void xseturgency(int add)
+static void xseturgency(struct st_window *xw, int add)
{
- XWMHints *h = XGetWMHints(xw.dpy, xw.win);
+ XWMHints *h = XGetWMHints(xw->dpy, xw->win);
h->flags =
add ? (h->flags | XUrgencyHint) : (h->flags & ~XUrgencyHint);
- XSetWMHints(xw.dpy, xw.win, h);
+ XSetWMHints(xw->dpy, xw->win, h);
XFree(h);
}
-static void xsetsel(char *str)
+static void xsetsel(struct st_window *xw)
{
- /* register the selection for both the clipboard and the primary */
Atom clipboard;
- free(sel.clip);
- sel.clip = str;
+ XSetSelectionOwner(xw->dpy, XA_PRIMARY, xw->win, CurrentTime);
- XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, CurrentTime);
-
- clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
- XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime);
+ clipboard = XInternAtom(xw->dpy, "CLIPBOARD", 0);
+ XSetSelectionOwner(xw->dpy, clipboard, xw->win, CurrentTime);
}
-static void ttywrite(const char *s, size_t n)
+static void ttywrite(struct st_term *term, const char *s, size_t n)
{
- if (write(cmdfd, s, n) == -1)
+ if (write(term->cmdfd, s, n) == -1)
die("write error on tty: %s\n", SERRNO);
}
/* ? */
-static void tsetdirt(int top, int bot)
+static void tsetdirt(struct st_term *term, int top, int bot)
{
int i;
- bot = min(bot, term.row - 1);
- top = min(top, term.row - 1);
+ bot = min(bot, term->row - 1);
+ top = min(top, term->row - 1);
for (i = top; i <= bot; i++)
- term.dirty[i] = 1;
+ term->dirty[i] = 1;
}
-static void tfulldirt(void)
+static void tfulldirt(struct st_term *term)
{
- tsetdirt(0, term.row - 1);
+ tsetdirt(term, 0, term->row - 1);
}
/* Selection code */
-static bool selected(int x, int y)
+static bool selected(struct st_selection *sel, int x, int y)
{
int bx, ex;
- if (sel.ey == y && sel.by == y) {
- bx = min(sel.bx, sel.ex);
- ex = max(sel.bx, sel.ex);
+ if (sel->ey == y && sel->by == y) {
+ bx = min(sel->bx, sel->ex);
+ ex = max(sel->bx, sel->ex);
return BETWEEN(x, bx, ex);
}
- return ((sel.b.y < y && y < sel.e.y)
- || (y == sel.e.y && x <= sel.e.x))
- || (y == sel.b.y && x >= sel.b.x
- && (x <= sel.e.x || sel.b.y != sel.e.y));
- switch (sel.type) {
+ return ((sel->b.y < y && y < sel->e.y)
+ || (y == sel->e.y && x <= sel->e.x))
+ || (y == sel->b.y && x >= sel->b.x
+ && (x <= sel->e.x || sel->b.y != sel->e.y));
+
+ switch (sel->type) {
case SEL_REGULAR:
- return ((sel.b.y < y && y < sel.e.y)
- || (y == sel.e.y && x <= sel.e.x))
- || (y == sel.b.y && x >= sel.b.x
- && (x <= sel.e.x || sel.b.y != sel.e.y));
+ return ((sel->b.y < y && y < sel->e.y)
+ || (y == sel->e.y && x <= sel->e.x))
+ || (y == sel->b.y && x >= sel->b.x
+ && (x <= sel->e.x || sel->b.y != sel->e.y));
case SEL_RECTANGULAR:
- return ((sel.b.y <= y && y <= sel.e.y)
- && (sel.b.x <= x && x <= sel.e.x));
+ return ((sel->b.y <= y && y <= sel->e.y)
+ && (sel->b.x <= x && x <= sel->e.x));
};
}
-static void selcopy(void)
+static void selcopy(struct st_window *xw)
{
+ struct st_term *term = &xw->term;
char *str, *ptr, *p;
int x, y, bufsize, is_selected = 0, size;
struct glyph *gp, *last;
- if (sel.bx == -1) {
+ if (term->sel.bx == -1) {
str = NULL;
} else {
- bufsize =
- (term.col + 1) * (sel.e.y - sel.b.y + 1) * UTF_SIZ;
+ bufsize = (term->col + 1) *
+ (term->sel.e.y - term->sel.b.y + 1) * UTF_SIZ;
ptr = str = xmalloc(bufsize);
/* append every set & selected glyph to the selection */
- for (y = sel.b.y; y < sel.e.y + 1; y++) {
+ for (y = term->sel.b.y; y < term->sel.e.y + 1; y++) {
is_selected = 0;
- gp = &term.line[y][0];
- last = gp + term.col;
+ gp = &term->line[y][0];
+ last = gp + term->col;
while (--last >= gp && !(last->state & GLYPH_SET))
/* nothing */ ;
for (x = 0; gp <= last; x++, ++gp) {
- if (!selected(x, y)) {
+ if (!selected(&term->sel, x, y)) {
continue;
} else {
is_selected = 1;
@@ -636,15 +609,18 @@ static void selcopy(void)
ptr += size;
}
/* \n at the end of every selected line except for the last one */
- if (is_selected && y < sel.e.y)
+ if (is_selected && y < term->sel.e.y)
*ptr++ = '\r';
}
*ptr = 0;
}
- xsetsel(str);
+
+ free(term->sel.clip);
+ term->sel.clip = str;
+ xsetsel(xw);
}
-static void selnotify(XEvent *e)
+static void selnotify(struct st_window *xw, XEvent *e)
{
unsigned long nitems, ofs, rem;
int format;
@@ -654,44 +630,47 @@ static void selnotify(XEvent *e)
ofs = 0;
do {
if (XGetWindowProperty
- (xw.dpy, xw.win, XA_PRIMARY, ofs, BUFSIZ / 4, False,
+ (xw->dpy, xw->win, XA_PRIMARY, ofs, BUFSIZ / 4, False,
AnyPropertyType, &type, &format, &nitems, &rem,
&data)) {
fprintf(stderr, "Clipboard allocation failed\n");
return;
}
- ttywrite((const char *) data, nitems * format / 8);
+ ttywrite(&xw->term, (const char *) data, nitems * format / 8);
XFree(data);
/* number of 32-bit chunks returned */
ofs += nitems * format / 32;
} while (rem > 0);
}
-static void selpaste(const union st_arg * dummy)
+static void selpaste(struct st_window *xw, const union st_arg *dummy)
{
- XConvertSelection(xw.dpy, XA_PRIMARY, sel.xtarget, XA_PRIMARY,
- xw.win, CurrentTime);
+ XConvertSelection(xw->dpy, XA_PRIMARY, xw->term.sel.xtarget,
+ XA_PRIMARY, xw->win, CurrentTime);
}
-static void clippaste(const union st_arg * dummy)
+static void clippaste(struct st_window *xw, const union st_arg *dummy)
{
Atom clipboard;
- clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
- XConvertSelection(xw.dpy, clipboard, sel.xtarget, XA_PRIMARY,
- xw.win, CurrentTime);
+ clipboard = XInternAtom(xw->dpy, "CLIPBOARD", 0);
+ XConvertSelection(xw->dpy, clipboard, xw->term.sel.xtarget,
+ XA_PRIMARY, xw->win, CurrentTime);
}
-static void selclear(XEvent *e)
+static void selclear(struct st_window *xw, XEvent *e)
{
- if (sel.bx == -1)
+ struct st_selection *sel = &xw->term.sel;
+
+ if (sel->bx == -1)
return;
- sel.bx = -1;
- tsetdirt(sel.b.y, sel.e.y);
+ sel->bx = -1;
+ tsetdirt(&xw->term, sel->b.y, sel->e.y);
}
-static void selrequest(XEvent *e)
+static void selrequest(struct st_window *xw, XEvent *e)
{
+ struct st_selection *sel = &xw->term.sel;
XSelectionRequestEvent *xsre;
XSelectionEvent xev;
Atom xa_targets, string;
@@ -705,19 +684,19 @@ static void selrequest(XEvent *e)
/* reject */
xev.property = None;
- xa_targets = XInternAtom(xw.dpy, "TARGETS", 0);
+ xa_targets = XInternAtom(xw->dpy, "TARGETS", 0);
if (xsre->target == xa_targets) {
/* respond with the supported type */
- string = sel.xtarget;
+ string = sel->xtarget;
XChangeProperty(xsre->display, xsre->requestor,
xsre->property, XA_ATOM, 32,
PropModeReplace, (unsigned char *) & string, 1);
xev.property = xsre->property;
- } else if (xsre->target == sel.xtarget && sel.clip != NULL) {
+ } else if (xsre->target == sel->xtarget && sel->clip != NULL) {
XChangeProperty(xsre->display, xsre->requestor,
xsre->property, xsre->target, 8,
- PropModeReplace, (unsigned char *) sel.clip,
- strlen(sel.clip));
+ PropModeReplace, (unsigned char *) sel->clip,
+ strlen(sel->clip));
xev.property = xsre->property;
}
@@ -727,75 +706,106 @@ static void selrequest(XEvent *e)
fprintf(stderr, "Error sending SelectionNotify event\n");
}
-static void selscroll(int orig, int n)
+static void selscroll(struct st_term *term, int orig, int n)
{
- if (sel.bx == -1)
+ if (term->sel.bx == -1)
return;
- if (BETWEEN(sel.by, orig, term.bot)
- || BETWEEN(sel.ey, orig, term.bot)) {
- if ((sel.by += n) > term.bot || (sel.ey += n) < term.top) {
- sel.bx = -1;
+ if (BETWEEN(term->sel.by, orig, term->bot)
+ || BETWEEN(term->sel.ey, orig, term->bot)) {
+ if ((term->sel.by += n) > term->bot ||
+ (term->sel.ey += n) < term->top) {
+ term->sel.bx = -1;
return;
}
- switch (sel.type) {
+
+ switch (term->sel.type) {
case SEL_REGULAR:
- if (sel.by < term.top) {
- sel.by = term.top;
- sel.bx = 0;
+ if (term->sel.by < term->top) {
+ term->sel.by = term->top;
+ term->sel.bx = 0;
}
- if (sel.ey > term.bot) {
- sel.ey = term.bot;
- sel.ex = term.col;
+ if (term->sel.ey > term->bot) {
+ term->sel.ey = term->bot;
+ term->sel.ex = term->col;
}
break;
case SEL_RECTANGULAR:
- if (sel.by < term.top)
- sel.by = term.top;
- if (sel.ey > term.bot)
- sel.ey = term.bot;
+ if (term->sel.by < term->top)
+ term->sel.by = term->top;
+ if (term->sel.ey > term->bot)
+ term->sel.ey = term->bot;
break;
};
- sel.b.y = sel.by, sel.b.x = sel.bx;
- sel.e.y = sel.ey, sel.e.x = sel.ex;
+ term->sel.b.y = term->sel.by, term->sel.b.x = term->sel.bx;
+ term->sel.e.y = term->sel.ey, term->sel.e.x = term->sel.ex;
}
}
/* Screen drawing code */
-static void xtermclear(int col1, int row1, int col2, int row2)
+static char *usedfont = NULL;
+static int usedfontsize = 0;
+
+/* Font Ring Cache */
+enum {
+ FRC_NORMAL,
+ FRC_ITALIC,
+ FRC_BOLD,
+ FRC_ITALICBOLD
+};
+
+struct st_fontcache {
+ XftFont *font;
+ long c;
+ int flags;
+};
+
+/*
+ * Fontcache is a ring buffer, with frccur as current position and frclen as
+ * the current length of used elements.
+ */
+
+static struct st_fontcache frc[1024];
+static int frccur = -1, frclen = 0;
+
+static void xtermclear(struct st_window *xw,
+ int col1, int row1, int col2, int row2)
{
- XftDrawRect(xw.draw,
- &xw.col[IS_SET(MODE_REVERSE) ? defaultfg : defaultbg],
- borderpx + col1 * xw.cw,
- borderpx + row1 * xw.ch,
- (col2 - col1 + 1) * xw.cw, (row2 - row1 + 1) * xw.ch);
+ XftDrawRect(xw->draw,
+ &xw->col[xw->term.mode & MODE_REVERSE ? defaultfg : defaultbg],
+ borderpx + col1 * xw->cw,
+ borderpx + row1 * xw->ch,
+ (col2 - col1 + 1) * xw->cw, (row2 - row1 + 1) * xw->ch);
}
/*
* Absolute coordinates.
*/
-static void xclear(int x1, int y1, int x2, int y2)
+static void xclear(struct st_window *xw,
+ int x1, int y1, int x2, int y2)
{
- XftDrawRect(xw.draw,
- &xw.col[IS_SET(MODE_REVERSE) ? defaultfg : defaultbg],
+ XftDrawRect(xw->draw,
+ &xw->col[xw->term.mode & MODE_REVERSE ? defaultfg : defaultbg],
x1, y1, x2 - x1, y2 - y1);
}
-static void xdraws(char *s, struct glyph base, int x, int y, int charlen, int bytelen)
+static void xdraws(struct st_window *xw,
+ char *s, struct glyph base, int x, int y,
+ int charlen, int bytelen)
{
- int winx = borderpx + x * xw.cw, winy = borderpx + y * xw.ch,
- width = charlen * xw.cw, xp, i;
+ int winx = borderpx + x * xw->cw, winy = borderpx + y * xw->ch,
+ width = charlen * xw->cw, xp, i;
int frp, frcflags;
int u8fl, u8fblen, u8cblen, doesexist;
char *u8c, *u8fs;
unsigned u8char;
- struct st_font *font = &xw.font;
+ struct st_font *font = &xw->font;
FcResult fcres;
FcPattern *fcpattern, *fontpattern;
FcFontSet *fcsets[] = { NULL };
FcCharSet *fccharset;
- XftColor *fg = &xw.col[base.fg], *bg = &xw.col[base.bg],
+ XftColor *fg = &xw->col[base.fg], *bg = &xw->col[base.bg],
revfg, revbg;
XRenderColor colfg, colbg;
@@ -804,13 +814,13 @@ static void xdraws(char *s, struct glyph base, int x, int y, int charlen, int by
if (base.mode & ATTR_BOLD) {
if (BETWEEN(base.fg, 0, 7)) {
/* basic system colors */
- fg = &xw.col[base.fg + 8];
+ fg = &xw->col[base.fg + 8];
} else if (BETWEEN(base.fg, 16, 195)) {
/* 256 colors */
- fg = &xw.col[base.fg + 36];
+ fg = &xw->col[base.fg + 36];
} else if (BETWEEN(base.fg, 232, 251)) {
/* greyscale */
- fg = &xw.col[base.fg + 4];
+ fg = &xw->col[base.fg + 4];
}
/*
* Those ranges will not be brightened:
@@ -818,40 +828,40 @@ static void xdraws(char *s, struct glyph base, int x, int y, int charlen, int by
* 196 - 231 – highest 256 color cube
* 252 - 255 – brightest colors in greyscale
*/
- font = &xw.bfont;
+ font = &xw->bfont;
frcflags = FRC_BOLD;
}
if (base.mode & ATTR_ITALIC) {
- font = &xw.ifont;
+ font = &xw->ifont;
frcflags = FRC_ITALIC;
}
if ((base.mode & ATTR_ITALIC) && (base.mode & ATTR_BOLD)) {
- font = &xw.ibfont;
+ font = &xw->ibfont;
frcflags = FRC_ITALICBOLD;
}
- if (IS_SET(MODE_REVERSE)) {
- if (fg == &xw.col[defaultfg]) {
- fg = &xw.col[defaultbg];
+ if (xw->term.mode & MODE_REVERSE) {
+ if (fg == &xw->col[defaultfg]) {
+ fg = &xw->col[defaultbg];
} else {
colfg.red = ~fg->color.red;
colfg.green = ~fg->color.green;
colfg.blue = ~fg->color.blue;
colfg.alpha = fg->color.alpha;
- XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg,
+ XftColorAllocValue(xw->dpy, xw->vis, xw->cmap, &colfg,
&revfg);
fg = &revfg;
}
- if (bg == &xw.col[defaultbg]) {
- bg = &xw.col[defaultfg];
+ if (bg == &xw->col[defaultbg]) {
+ bg = &xw->col[defaultfg];
} else {
colbg.red = ~bg->color.red;
colbg.green = ~bg->color.green;
colbg.blue = ~bg->color.blue;
colbg.alpha = bg->color.alpha;
- XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg,
+ XftColorAllocValue(xw->dpy, xw->vis, xw->cmap, &colbg,
&revbg);
bg = &revbg;
}
@@ -862,20 +872,20 @@ static void xdraws(char *s, struct glyph base, int x, int y, int charlen, int by
/* Intelligent cleaning up of the borders. */
if (x == 0) {
- xclear(0, (y == 0) ? 0 : winy, borderpx,
- winy + xw.ch + ((y >= term.row - 1) ? xw.h : 0));
+ xclear(xw, 0, (y == 0) ? 0 : winy, borderpx,
+ winy + xw->ch + ((y >= xw->term.row - 1) ? xw->h : 0));
}
- if (x + charlen >= term.col) {
- xclear(winx + width, (y == 0) ? 0 : winy, xw.w,
- ((y >= term.row - 1) ? xw.h : (winy + xw.ch)));
+ if (x + charlen >= xw->term.col) {
+ xclear(xw, winx + width, (y == 0) ? 0 : winy, xw->w,
+ ((y >= xw->term.row - 1) ? xw->h : (winy + xw->ch)));
}
if (y == 0)
- xclear(winx, 0, winx + width, borderpx);
- if (y == term.row - 1)
- xclear(winx, winy + xw.ch, winx + width, xw.h);
+ xclear(xw, winx, 0, winx + width, borderpx);
+ if (y == xw->term.row - 1)
+ xclear(xw, winx, winy + xw->ch, winx + width, xw->h);
/* Clean up the region we want to draw to. */
- XftDrawRect(xw.draw, bg, winx, winy, width, xw.ch);
+ XftDrawRect(xw->draw, bg, winx, winy, width, xw->ch);
fcsets[0] = font->set;
for (xp = winx; bytelen > 0;) {
@@ -896,7 +906,7 @@ static void xdraws(char *s, struct glyph base, int x, int y, int charlen, int by
bytelen -= u8cblen;
doesexist =
- XftCharIndex(xw.dpy, font->match, u8char);
+ XftCharIndex(xw->dpy, font->match, u8char);
if (!doesexist || bytelen <= 0) {
if (bytelen <= 0) {
if (doesexist) {
@@ -906,7 +916,7 @@ static void xdraws(char *s, struct glyph base, int x, int y, int charlen, int by
}
if (u8fl > 0) {
- XftDrawStringUtf8(xw.draw, fg,
+ XftDrawStringUtf8(xw->draw, fg,
font->match, xp,
winy +
font->ascent,
@@ -967,10 +977,10 @@ static void xdraws(char *s, struct glyph base, int x, int y, int charlen, int by
frccur = 0;
if (frclen > ARRAY_SIZE(frc)) {
frclen = ARRAY_SIZE(frc);
- XftFontClose(xw.dpy, frc[frccur].font);
+ XftFontClose(xw->dpy, frc[frccur].font);
}
- frc[frccur].font = XftFontOpenPattern(xw.dpy,
+ frc[frccur].font = XftFontOpenPattern(xw->dpy,
fontpattern);
frc[frccur].c = u8char;
frc[frccur].flags = frcflags;
@@ -981,7 +991,7 @@ static void xdraws(char *s, struct glyph base, int x, int y, int charlen, int by
frp = frccur;
}
- XftDrawStringUtf8(xw.draw, fg, frc[frp].font,
+ XftDrawStringUtf8(xw->draw, fg, frc[frp].font,
xp, winy + frc[frp].font->ascent,
(FcChar8 *) u8c, u8cblen);
@@ -989,81 +999,82 @@ static void xdraws(char *s, struct glyph base, int x, int y, int charlen, int by
}
/*
- XftDrawStringUtf8(xw.draw, fg, font->set, winx,
+ XftDrawStringUtf8(xw->draw, fg, font->set, winx,
winy + font->ascent, (FcChar8 *)s, bytelen);
*/
if (base.mode & ATTR_UNDERLINE) {
- XftDrawRect(xw.draw, fg, winx, winy + font->ascent + 1,
+ XftDrawRect(xw->draw, fg, winx, winy + font->ascent + 1,
width, 1);
}
}
-static void xdrawcursor(void)
+static void xdrawcursor(struct st_window *xw)
{
static int oldx = 0, oldy = 0;
int sl;
struct glyph g = { {' '}, ATTR_NULL, defaultbg, defaultcs, 0 };
- oldx = min(oldx, term.col - 1);
- oldy = min(oldy, term.row - 1);
+ oldx = min(oldx, xw->term.col - 1);
+ oldy = min(oldy, xw->term.row - 1);
- if (term.line[term.c.y][term.c.x].state & GLYPH_SET)
- memcpy(g.c, term.line[term.c.y][term.c.x].c, UTF_SIZ);
+ if (xw->term.line[xw->term.c.y][xw->term.c.x].state & GLYPH_SET)
+ memcpy(g.c, xw->term.line[xw->term.c.y][xw->term.c.x].c, UTF_SIZ);
/* remove the old cursor */
- if (term.line[oldy][oldx].state & GLYPH_SET) {
- sl = utf8size(term.line[oldy][oldx].c);
- xdraws(term.line[oldy][oldx].c, term.line[oldy][oldx],
+ if (xw->term.line[oldy][oldx].state & GLYPH_SET) {
+ sl = utf8size(xw->term.line[oldy][oldx].c);
+ xdraws(xw, xw->term.line[oldy][oldx].c, xw->term.line[oldy][oldx],
oldx, oldy, 1, sl);
} else {
- xtermclear(oldx, oldy, oldx, oldy);
+ xtermclear(xw, oldx, oldy, oldx, oldy);
}
/* draw the new one */
- if (!(IS_SET(MODE_HIDE))) {
- if (!(xw.state & WIN_FOCUSED))
+ if (!(xw->term.mode & MODE_HIDE)) {
+ if (!(xw->state & WIN_FOCUSED))
g.bg = defaultucs;
- if (IS_SET(MODE_REVERSE))
+ if (xw->term.mode & 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);
- oldx = term.c.x, oldy = term.c.y;
+ xdraws(xw, g.c, g, xw->term.c.x, xw->term.c.y, 1, sl);
+ oldx = xw->term.c.x, oldy = xw->term.c.y;
}
}
-static void drawregion(int x1, int y1, int x2, int y2)
+static void drawregion(struct st_window *xw,
+ int x1, int y1, int x2, int y2)
{
int ic, ib, x, y, ox, sl;
struct glyph base, new;
char buf[DRAW_BUF_SIZ];
- bool ena_sel = sel.bx != -1;
+ bool ena_sel = xw->term.sel.bx != -1;
- if (sel.alt ^ IS_SET(MODE_ALTSCREEN))
+ if (xw->term.sel.alt == !(xw->term.mode & MODE_ALTSCREEN))
ena_sel = 0;
- if (!(xw.state & WIN_VISIBLE))
+ if (!(xw->state & WIN_VISIBLE))
return;
for (y = y1; y < y2; y++) {
- if (!term.dirty[y])
+ if (!xw->term.dirty[y])
continue;
- xtermclear(0, y, term.col, y);
- term.dirty[y] = 0;
- base = term.line[y][0];
+ xtermclear(xw, 0, y, xw->term.col, y);
+ xw->term.dirty[y] = 0;
+ base = xw->term.line[y][0];
ic = ib = ox = 0;
for (x = x1; x < x2; x++) {
- new = term.line[y][x];
- if (ena_sel && *(new.c) && selected(x, y))
+ new = xw->term.line[y][x];
+ if (ena_sel && *(new.c) && selected(&xw->term.sel, x, y))
new.mode ^= ATTR_REVERSE;
if (ib > 0 && (!(new.state & GLYPH_SET)
|| ATTRCMP(base, new)
|| ib >= DRAW_BUF_SIZ - UTF_SIZ)) {
- xdraws(buf, base, ox, y, ic, ib);
+ xdraws(xw, buf, base, ox, y, ic, ib);
ic = ib = 0;
}
if (new.state & GLYPH_SET) {
@@ -1079,35 +1090,38 @@ static void drawregion(int x1, int y1, int x2, int y2)
}
}
if (ib > 0)
- xdraws(buf, base, ox, y, ic, ib);
+ xdraws(xw, buf, base, ox, y, ic, ib);
}
- xdrawcursor();
+ xdrawcursor(xw);
}
-static void draw(void)
+static void draw(struct st_window *xw)
{
- drawregion(0, 0, term.col, term.row);
- XCopyArea(xw.dpy, xw.buf, xw.win, xw.gc, 0, 0, xw.w, xw.h, 0, 0);
- XSetForeground(xw.dpy, xw.gc,
- xw.col[IS_SET(MODE_REVERSE) ?
- defaultfg : defaultbg].pixel);
+ drawregion(xw, 0, 0, xw->term.col, xw->term.row);
+ XCopyArea(xw->dpy, xw->buf, xw->win, xw->gc,
+ 0, 0, xw->w, xw->h, 0, 0);
+ XSetForeground(xw->dpy, xw->gc,
+ xw->col[xw->term.mode & MODE_REVERSE
+ ? defaultfg : defaultbg].pixel);
}
-static void redraw(int timeout)
+static void redraw(struct st_window *xw, int timeout)
{
struct timespec tv = { 0, timeout * 1000 };
- tfulldirt();
- draw();
+ tfulldirt(&xw->term);
+ draw(xw);
if (timeout > 0) {
- nanosleep(&tv, NULL);
- XSync(xw.dpy, False); /* necessary for a good tput flash */
+ nanosleep(&tv, NULL); /* XXX !?!?!? */
+ XSync(xw->dpy, False); /* necessary for a good tput flash */
}
}
/* Escape handling */
+static struct csi_escape csiescseq;
+
static void csiparse(void)
{
char *p = csiescseq.buf, *np;
@@ -1166,7 +1180,8 @@ static void csireset(void)
/* t code */
-static void tclearregion(int x1, int y1, int x2, int y2, int bce)
+static void tclearregion(struct st_term *term,
+ int x1, int y1, int x2, int y2, int bce)
{
int x, y;
@@ -1175,142 +1190,143 @@ static void tclearregion(int x1, int y1, int x2, int y2, int bce)
if (y1 > y2)
swap(y1, y2);
- x1 = min(x1, term.col - 1);
- x2 = min(x2, term.col - 1);
- y1 = min(y1, term.row - 1);
- y2 = min(y2, term.row - 1);
+ x1 = min(x1, term->col - 1);
+ x2 = min(x2, term->col - 1);
+ y1 = min(y1, term->row - 1);
+ y2 = min(y2, term->row - 1);
for (y = y1; y <= y2; y++) {
- term.dirty[y] = 1;
+ 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;
+ 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].state = 0;
}
}
}
}
-static void tscrolldown(int orig, int n)
+static void tscrolldown(struct st_term *term, int orig, int n)
{
int i;
- n = clamp(n, 0, term.bot - orig + 1);
+ n = clamp(n, 0, term->bot - orig + 1);
- tclearregion(0, term.bot - n + 1, term.col - 1, term.bot, 0);
+ tclearregion(term, 0, term->bot - n + 1, term->col - 1, term->bot, 0);
- for (i = term.bot; i >= orig + n; i--) {
- swap(term.line[i], term.line[i - n]);
+ for (i = term->bot; i >= orig + n; i--) {
+ swap(term->line[i], term->line[i - n]);
- term.dirty[i] = 1;
- term.dirty[i - n] = 1;
+ term->dirty[i] = 1;
+ term->dirty[i - n] = 1;
}
- selscroll(orig, n);
+ selscroll(term, orig, n);
}
-static void tscrollup(int orig, int n)
+static void tscrollup(struct st_term *term, int orig, int n)
{
int i;
- n = clamp(n, 0, term.bot - orig + 1);
+ n = clamp(n, 0, term->bot - orig + 1);
- tclearregion(0, orig, term.col - 1, orig + n - 1, 0);
+ tclearregion(term, 0, orig, term->col - 1, orig + n - 1, 0);
- for (i = orig; i <= term.bot - n; i++) {
- swap(term.line[i], term.line[i + n]);
+ /* XXX: optimize? */
+ for (i = orig; i <= term->bot - n; i++) {
+ swap(term->line[i], term->line[i + n]);
- term.dirty[i] = 1;
- term.dirty[i + n] = 1;
+ term->dirty[i] = 1;
+ term->dirty[i + n] = 1;
}
- selscroll(orig, -n);
+ selscroll(term, orig, -n);
}
-static void tmoveto(int x, int y)
+static void tmoveto(struct st_term *term, int x, int y)
{
- x = min(x, term.col - 1);
- y = term.c.state & CURSOR_ORIGIN
- ? clamp(y, term.top, term.bot)
- : min(y, term.row - 1);
+ x = min(x, term->col - 1);
+ y = term->c.state & CURSOR_ORIGIN
+ ? clamp(y, term->top, term->bot)
+ : min(y, term->row - 1);
- term.c.state &= ~CURSOR_WRAPNEXT;
- term.c.x = x;
- term.c.y = y;
+ term->c.state &= ~CURSOR_WRAPNEXT;
+ term->c.x = x;
+ term->c.y = y;
}
/* for absolute user moves, when decom is set */
-static void tmoveato(int x, int y)
+static void tmoveato(struct st_term *term, int x, int y)
{
- tmoveto(x, y + ((term.c.state & CURSOR_ORIGIN) ? term.top : 0));
+ tmoveto(term, x, y + ((term->c.state & CURSOR_ORIGIN) ? term->top : 0));
}
-static void tcursor(int mode)
+static void tcursor_save(struct st_term *term)
{
- static struct tcursor c;
+ term->saved = term->c;
+}
- if (mode == CURSOR_SAVE) {
- c = term.c;
- } else if (mode == CURSOR_LOAD) {
- term.c = c;
- tmoveto(c.x, c.y);
- }
+static void tcursor_load(struct st_term *term)
+{
+ term->c = term->saved;
+ tmoveto(term, term->c.x, term->c.y);
}
-static void treset(void)
+static void treset(struct st_term *term)
{
unsigned i;
- term.c = (struct tcursor) { {
+ term->c = (struct tcursor) { {
.mode = ATTR_NULL,.fg = defaultfg,.bg = defaultbg},.x = 0,.y =
0,.state = CURSOR_DEFAULT};
- memset(term.tabs, 0, term.col * sizeof(*term.tabs));
- for (i = tabspaces; i < term.col; i += tabspaces)
- term.tabs[i] = 1;
- term.top = 0;
- term.bot = term.row - 1;
- term.mode = MODE_WRAP;
+ memset(term->tabs, 0, term->col * sizeof(*term->tabs));
+ for (i = tabspaces; i < term->col; i += tabspaces)
+ term->tabs[i] = 1;
+ term->top = 0;
+ term->bot = term->row - 1;
+ term->mode = MODE_WRAP;
- tclearregion(0, 0, term.col - 1, term.row - 1, 0);
- tmoveto(0, 0);
- tcursor(CURSOR_SAVE);
+ tclearregion(term, 0, 0, term->col - 1, term->row - 1, 0);
+ tmoveto(term, 0, 0);
+ tcursor_save(term);
}
-static void tputtab(bool forward)
+static void tputtab(struct st_term *term, bool forward)
{
- unsigned x = term.c.x;
+ unsigned x = term->c.x;
if (forward) {
- if (x == term.col)
+ if (x == term->col)
return;
- for (++x; x < term.col && !term.tabs[x]; ++x)
+ for (++x; x < term->col && !term->tabs[x]; ++x)
/* nothing */ ;
} else {
if (x == 0)
return;
- for (--x; x > 0 && !term.tabs[x]; --x)
+ for (--x; x > 0 && !term->tabs[x]; --x)
/* nothing */ ;
}
- tmoveto(x, term.c.y);
+ tmoveto(term, x, term->c.y);
}
-static void tnewline(int first_col)
+static void tnewline(struct st_term *term, int first_col)
{
- int y = term.c.y;
+ int y = term->c.y;
- if (y == term.bot) {
- tscrollup(term.top, 1);
- } else {
+ if (y == term->bot)
+ tscrollup(term, term->top, 1);
+ else
y++;
- }
- tmoveto(first_col ? 0 : term.c.x, y);
+
+ tmoveto(term, first_col ? 0 : term->c.x, y);
}
-static void tsetchar(char *c, struct glyph *attr, int x, int y)
+static void tsetchar(struct st_term *term, char *c,
+ struct glyph *attr, int x, int y)
{
static char *vt100_0[62] = { /* 0x41 - 0x7e */
"↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */
@@ -1332,117 +1348,119 @@ static void tsetchar(char *c, struct glyph *attr, int x, int y)
}
}
- term.dirty[y] = 1;
- term.line[y][x] = *attr;
- memcpy(term.line[y][x].c, c, UTF_SIZ);
- term.line[y][x].state |= GLYPH_SET;
+ term->dirty[y] = 1;
+ term->line[y][x] = *attr;
+ memcpy(term->line[y][x].c, c, UTF_SIZ);
+ term->line[y][x].state |= GLYPH_SET;
}
-static void tdeletechar(int n)
+static void tdeletechar(struct st_term *term, int n)
{
- int src = term.c.x + n;
- int dst = term.c.x;
- int size = term.col - src;
+ int src = term->c.x + n;
+ int dst = term->c.x;
+ int size = term->col - src;
- term.dirty[term.c.y] = 1;
+ term->dirty[term->c.y] = 1;
- if (src >= term.col) {
- tclearregion(term.c.x, term.c.y, term.col - 1, term.c.y,
- 0);
- return;
+ if (src < term->col) {
+ memmove(&term->line[term->c.y][dst],
+ &term->line[term->c.y][src],
+ size * sizeof(struct glyph));
+ tclearregion(term, term->col - n, term->c.y,
+ term->col - 1, term->c.y, 0);
+ } else {
+ tclearregion(term, term->c.x, term->c.y,
+ term->col - 1, term->c.y, 0);
}
-
- memmove(&term.line[term.c.y][dst], &term.line[term.c.y][src],
- size * sizeof(struct glyph));
- tclearregion(term.col - n, term.c.y, term.col - 1, term.c.y, 0);
}
-static void tinsertblank(int n)
+static void tinsertblank(struct st_term *term, int n)
{
- int src = term.c.x;
+ int src = term->c.x;
int dst = src + n;
- int size = term.col - dst;
+ int size = term->col - dst;
- term.dirty[term.c.y] = 1;
+ term->dirty[term->c.y] = 1;
- if (dst >= term.col) {
- tclearregion(term.c.x, term.c.y, term.col - 1, term.c.y,
- 0);
- return;
+ if (dst < term->col) {
+ memmove(&term->line[term->c.y][dst],
+ &term->line[term->c.y][src],
+ size * sizeof(struct glyph));
+ tclearregion(term, src, term->c.y,
+ dst - 1, term->c.y, 0);
+ } else {
+ tclearregion(term, term->c.x, term->c.y,
+ term->col - 1, term->c.y, 0);
}
-
- memmove(&term.line[term.c.y][dst], &term.line[term.c.y][src],
- size * sizeof(struct glyph));
- tclearregion(src, term.c.y, dst - 1, term.c.y, 0);
}
-static void tinsertblankline(int n)
+static void tinsertblankline(struct st_term *term, int n)
{
- if (term.c.y < term.top || term.c.y > term.bot)
+ if (term->c.y < term->top || term->c.y > term->bot)
return;
- tscrolldown(term.c.y, n);
+ tscrolldown(term, term->c.y, n);
}
-static void tdeleteline(int n)
+static void tdeleteline(struct st_term *term, int n)
{
- if (term.c.y < term.top || term.c.y > term.bot)
+ if (term->c.y < term->top || term->c.y > term->bot)
return;
- tscrollup(term.c.y, n);
+ tscrollup(term, term->c.y, n);
}
-static void tsetattr(int *attr, int l)
+static void tsetattr(struct st_term *term, int *attr, int l)
{
int i;
for (i = 0; i < l; i++) {
switch (attr[i]) {
case 0:
- term.c.attr.mode &=
+ term->c.attr.mode &=
~(ATTR_REVERSE | ATTR_UNDERLINE | ATTR_BOLD |
ATTR_ITALIC | ATTR_BLINK);
- term.c.attr.fg = defaultfg;
- term.c.attr.bg = defaultbg;
+ term->c.attr.fg = defaultfg;
+ term->c.attr.bg = defaultbg;
break;
case 1:
- term.c.attr.mode |= ATTR_BOLD;
+ term->c.attr.mode |= ATTR_BOLD;
break;
case 3:
- term.c.attr.mode |= ATTR_ITALIC;
+ term->c.attr.mode |= ATTR_ITALIC;
break;
case 4:
- term.c.attr.mode |= ATTR_UNDERLINE;
+ term->c.attr.mode |= ATTR_UNDERLINE;
break;
case 5: /* slow blink */
case 6: /* rapid blink */
- term.c.attr.mode |= ATTR_BLINK;
+ term->c.attr.mode |= ATTR_BLINK;
break;
case 7:
- term.c.attr.mode |= ATTR_REVERSE;
+ term->c.attr.mode |= ATTR_REVERSE;
break;
case 21:
case 22:
- term.c.attr.mode &= ~ATTR_BOLD;
+ term->c.attr.mode &= ~ATTR_BOLD;
break;
case 23:
- term.c.attr.mode &= ~ATTR_ITALIC;
+ term->c.attr.mode &= ~ATTR_ITALIC;
break;
case 24:
- term.c.attr.mode &= ~ATTR_UNDERLINE;
+ term->c.attr.mode &= ~ATTR_UNDERLINE;
break;
case 25:
case 26:
- term.c.attr.mode &= ~ATTR_BLINK;
+ term->c.attr.mode &= ~ATTR_BLINK;
break;
case 27:
- term.c.attr.mode &= ~ATTR_REVERSE;
+ term->c.attr.mode &= ~ATTR_REVERSE;
break;
case 38:
if (i + 2 < l && attr[i + 1] == 5) {
i += 2;
if (BETWEEN(attr[i], 0, 255)) {
- term.c.attr.fg = attr[i];
+ term->c.attr.fg = attr[i];
} else {
fprintf(stderr,
"erresc: bad fgcolor %d\n",
@@ -1455,13 +1473,13 @@ static void tsetattr(int *attr, int l)
}
break;
case 39:
- term.c.attr.fg = defaultfg;
+ term->c.attr.fg = defaultfg;
break;
case 48:
if (i + 2 < l && attr[i + 1] == 5) {
i += 2;
if (BETWEEN(attr[i], 0, 255)) {
- term.c.attr.bg = attr[i];
+ term->c.attr.bg = attr[i];
} else {
fprintf(stderr,
"erresc: bad bgcolor %d\n",
@@ -1474,17 +1492,17 @@ static void tsetattr(int *attr, int l)
}
break;
case 49:
- term.c.attr.bg = defaultbg;
+ term->c.attr.bg = defaultbg;
break;
default:
if (BETWEEN(attr[i], 30, 37)) {
- term.c.attr.fg = attr[i] - 30;
+ term->c.attr.fg = attr[i] - 30;
} else if (BETWEEN(attr[i], 40, 47)) {
- term.c.attr.bg = attr[i] - 40;
+ term->c.attr.bg = attr[i] - 40;
} else if (BETWEEN(attr[i], 90, 97)) {
- term.c.attr.fg = attr[i] - 90 + 8;
+ term->c.attr.fg = attr[i] - 90 + 8;
} else if (BETWEEN(attr[i], 100, 107)) {
- term.c.attr.bg = attr[i] - 100 + 8;
+ term->c.attr.bg = attr[i] - 100 + 8;
} else {
fprintf(stderr,
"erresc(default): gfx attr %d unknown\n",
@@ -1495,26 +1513,27 @@ static void tsetattr(int *attr, int l)
}
}
-static void tsetscroll(int t, int b)
+static void tsetscroll(struct st_term *term, int t, int b)
{
- t = min(t, term.row - 1);
- b = min(b, term.row - 1);
+ t = min(t, term->row - 1);
+ b = min(b, term->row - 1);
if (t > b)
swap(t, b);
- term.top = t;
- term.bot = b;
+ term->top = t;
+ term->bot = b;
}
-static void tswapscreen(void)
+static void tswapscreen(struct st_term *term)
{
- swap(term.line, term.alt);
- term.mode ^= MODE_ALTSCREEN;
- tfulldirt();
+ swap(term->line, term->alt);
+ term->mode ^= MODE_ALTSCREEN;
+ tfulldirt(term);
}
-static void tsetmode(bool priv, bool set, int *args, int narg)
+static void tsetmode(struct st_window *xw,
+ bool priv, bool set, int *args, int narg)
{
#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit)))
int *lim, mode;
@@ -1525,20 +1544,20 @@ static void tsetmode(bool priv, bool set, int *args, int narg)
switch (*args) {
break;
case 1: /* DECCKM -- Cursor key */
- MODBIT(term.mode, set, MODE_APPCURSOR);
+ MODBIT(xw->term.mode, set, MODE_APPCURSOR);
break;
case 5: /* DECSCNM -- Reverse video */
- mode = term.mode;
- MODBIT(term.mode, set, MODE_REVERSE);
- if (mode != term.mode)
- redraw(REDRAW_TIMEOUT);
+ mode = xw->term.mode;
+ MODBIT(xw->term.mode, set, MODE_REVERSE);
+ if (mode != xw->term.mode)
+ redraw(xw, REDRAW_TIMEOUT);
break;
case 6: /* DECOM -- Origin */
- MODBIT(term.c.state, set, CURSOR_ORIGIN);
- tmoveato(0, 0);
+ MODBIT(xw->term.c.state, set, CURSOR_ORIGIN);
+ tmoveato(&xw->term, 0, 0);
break;
case 7: /* DECAWM -- Auto wrap */
- MODBIT(term.mode, set, MODE_WRAP);
+ MODBIT(xw->term.mode, set, MODE_WRAP);
break;
case 0: /* Error (IGNORED) */
case 2: /* DECANM -- ANSI/VT52 (IGNORED) */
@@ -1551,37 +1570,40 @@ static void tsetmode(bool priv, bool set, int *args, int narg)
case 12: /* att610 -- Start blinking cursor (IGNORED) */
break;
case 25: /* DECTCEM -- Text Cursor Enable Mode */
- MODBIT(term.mode, !set, MODE_HIDE);
+ MODBIT(xw->term.mode, !set, MODE_HIDE);
break;
case 1000: /* 1000,1002: enable xterm mouse report */
- MODBIT(term.mode, set, MODE_MOUSEBTN);
- MODBIT(term.mode, 0, MODE_MOUSEMOTION);
+ MODBIT(xw->term.mode, set, MODE_MOUSEBTN);
+ MODBIT(xw->term.mode, 0, MODE_MOUSEMOTION);
break;
case 1002:
- MODBIT(term.mode, set, MODE_MOUSEMOTION);
- MODBIT(term.mode, 0, MODE_MOUSEBTN);
+ MODBIT(xw->term.mode, set, MODE_MOUSEMOTION);
+ MODBIT(xw->term.mode, 0, MODE_MOUSEBTN);
break;
case 1006:
- MODBIT(term.mode, set, MODE_MOUSESGR);
+ MODBIT(xw->term.mode, set, MODE_MOUSESGR);
break;
case 1049: /* = 1047 and 1048 */
case 47:
case 1047:{
- alt = IS_SET(MODE_ALTSCREEN);
+ alt = (xw->term.mode & MODE_ALTSCREEN) != 0;
if (alt) {
- tclearregion(0, 0,
- term.col - 1,
- term.row - 1,
+ tclearregion(&xw->term, 0, 0,
+ xw->term.col - 1,
+ xw->term.row - 1,
0);
}
- if (set ^ alt) /* set is always 1 or 0 */
- tswapscreen();
+ if (set != alt) /* set is always 1 or 0 */
+ tswapscreen(&xw->term);
if (*args != 1049)
break;
}
/* pass through */
case 1048:
- tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD);
+ if (set)
+ tcursor_save(&xw->term);
+ else
+ tcursor_load(&xw->term);
break;
default:
fprintf(stderr,
@@ -1594,16 +1616,16 @@ static void tsetmode(bool priv, bool set, int *args, int narg)
case 0: /* Error (IGNORED) */
break;
case 2: /* KAM -- keyboard action */
- MODBIT(term.mode, set, MODE_KBDLOCK);
+ MODBIT(xw->term.mode, set, MODE_KBDLOCK);
break;
case 4: /* IRM -- Insertion-replacement */
- MODBIT(term.mode, set, MODE_INSERT);
+ MODBIT(xw->term.mode, set, MODE_INSERT);
break;
case 12: /* SRM -- Send/Receive */
- MODBIT(term.mode, !set, MODE_ECHO);
+ MODBIT(xw->term.mode, !set, MODE_ECHO);
break;
case 20: /* LNM -- Linefeed/new line */
- MODBIT(term.mode, set, MODE_CRLF);
+ MODBIT(xw->term.mode, set, MODE_CRLF);
break;
default:
fprintf(stderr,
@@ -1616,8 +1638,10 @@ static void tsetmode(bool priv, bool set, int *args, int narg)
#undef MODBIT
}
-static void csihandle(void)
+static void csihandle(struct st_window *xw)
{
+ struct st_term *term = &xw->term;
+
switch (csiescseq.mode) {
default:
unknown:
@@ -1627,46 +1651,46 @@ static void csihandle(void)
break;
case '@': /* ICH -- Insert <n> blank char */
DEFAULT(csiescseq.arg[0], 1);
- tinsertblank(csiescseq.arg[0]);
+ tinsertblank(term, csiescseq.arg[0]);
break;
case 'A': /* CUU -- Cursor <n> Up */
DEFAULT(csiescseq.arg[0], 1);
- tmoveto(term.c.x, term.c.y - csiescseq.arg[0]);
+ tmoveto(term, term->c.x, term->c.y - csiescseq.arg[0]);
break;
case 'B': /* CUD -- Cursor <n> Down */
case 'e': /* VPR --Cursor <n> Down */
DEFAULT(csiescseq.arg[0], 1);
- tmoveto(term.c.x, term.c.y + csiescseq.arg[0]);
+ tmoveto(term, term->c.x, term->c.y + csiescseq.arg[0]);
break;
case 'c': /* DA -- Device Attributes */
if (csiescseq.arg[0] == 0)
- ttywrite(VT102ID, sizeof(VT102ID) - 1);
+ ttywrite(term, VT102ID, sizeof(VT102ID) - 1);
break;
case 'C': /* CUF -- Cursor <n> Forward */
case 'a': /* HPR -- Cursor <n> Forward */
DEFAULT(csiescseq.arg[0], 1);
- tmoveto(term.c.x + csiescseq.arg[0], term.c.y);
+ tmoveto(term, term->c.x + csiescseq.arg[0], term->c.y);
break;
case 'D': /* CUB -- Cursor <n> Backward */
DEFAULT(csiescseq.arg[0], 1);
- tmoveto(term.c.x - csiescseq.arg[0], term.c.y);
+ tmoveto(term, term->c.x - csiescseq.arg[0], term->c.y);
break;
case 'E': /* CNL -- Cursor <n> Down and first col */
DEFAULT(csiescseq.arg[0], 1);
- tmoveto(0, term.c.y + csiescseq.arg[0]);
+ tmoveto(term, 0, term->c.y + csiescseq.arg[0]);
break;
case 'F': /* CPL -- Cursor <n> Up and first col */
DEFAULT(csiescseq.arg[0], 1);
- tmoveto(0, term.c.y - csiescseq.arg[0]);
+ tmoveto(term, 0, term->c.y - csiescseq.arg[0]);
break;
case 'g': /* TBC -- Tabulation clear */
switch (csiescseq.arg[0]) {
case 0: /* clear current tab stop */
- term.tabs[term.c.x] = 0;
+ term->tabs[term->c.x] = 0;
break;
case 3: /* clear all the tabs */
- memset(term.tabs, 0,
- term.col * sizeof(*term.tabs));
+ memset(term->tabs, 0,
+ term->col * sizeof(*term->tabs));
break;
default:
goto unknown;
@@ -1675,38 +1699,40 @@ static void csihandle(void)
case 'G': /* CHA -- Move to <col> */
case '`': /* HPA */
DEFAULT(csiescseq.arg[0], 1);
- tmoveto(csiescseq.arg[0] - 1, term.c.y);
+ tmoveto(term, csiescseq.arg[0] - 1, term->c.y);
break;
case 'H': /* CUP -- Move to <row> <col> */
case 'f': /* HVP */
DEFAULT(csiescseq.arg[0], 1);
DEFAULT(csiescseq.arg[1], 1);
- tmoveato(csiescseq.arg[1] - 1, csiescseq.arg[0] - 1);
+ tmoveato(term, csiescseq.arg[1] - 1, csiescseq.arg[0] - 1);
break;
case 'I': /* CHT -- Cursor Forward Tabulation <n> tab stops */
DEFAULT(csiescseq.arg[0], 1);
while (csiescseq.arg[0]--)
- tputtab(1);
+ tputtab(term, 1);
break;
case 'J': /* ED -- Clear screen */
- sel.bx = -1;
+ term->sel.bx = -1;
switch (csiescseq.arg[0]) {
case 0: /* below */
- tclearregion(term.c.x, term.c.y, term.col - 1,
- term.c.y, 1);
- if (term.c.y < term.row - 1) {
- tclearregion(0, term.c.y + 1, term.col - 1,
- term.row - 1, 1);
+ tclearregion(term, term->c.x, term->c.y,
+ term->col - 1, term->c.y, 1);
+ if (term->c.y < term->row - 1) {
+ tclearregion(term, 0, term->c.y + 1,
+ term->col - 1, term->row - 1, 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);
+ if (term->c.y > 1)
+ tclearregion(term, 0, 0,
+ term->col - 1, term->c.y - 1, 1);
+ tclearregion(term, 0, term->c.y,
+ term->c.x, term->c.y, 1);
break;
case 2: /* all */
- tclearregion(0, 0, term.col - 1, term.row - 1, 1);
+ tclearregion(term, 0, 0, term->col - 1,
+ term->row - 1, 1);
break;
default:
goto unknown;
@@ -1715,83 +1741,86 @@ static void csihandle(void)
case 'K': /* EL -- Clear line */
switch (csiescseq.arg[0]) {
case 0: /* right */
- tclearregion(term.c.x, term.c.y, term.col - 1,
- term.c.y, 1);
+ tclearregion(term, term->c.x, term->c.y,
+ term->col - 1, term->c.y, 1);
break;
case 1: /* left */
- tclearregion(0, term.c.y, term.c.x, term.c.y, 1);
+ tclearregion(term, 0, term->c.y,
+ term->c.x, term->c.y, 1);
break;
case 2: /* all */
- tclearregion(0, term.c.y, term.col - 1, term.c.y,
- 1);
+ tclearregion(term, 0, term->c.y,
+ term->col - 1, term->c.y, 1);
break;
}
break;
case 'S': /* SU -- Scroll <n> line up */
DEFAULT(csiescseq.arg[0], 1);
- tscrollup(term.top, csiescseq.arg[0]);
+ tscrollup(term, term->top, csiescseq.arg[0]);
break;
case 'T': /* SD -- Scroll <n> line down */
DEFAULT(csiescseq.arg[0], 1);
- tscrolldown(term.top, csiescseq.arg[0]);
+ tscrolldown(term, term->top, csiescseq.arg[0]);
break;
case 'L': /* IL -- Insert <n> blank lines */
DEFAULT(csiescseq.arg[0], 1);
- tinsertblankline(csiescseq.arg[0]);
+ tinsertblankline(term, csiescseq.arg[0]);
break;
case 'l': /* RM -- Reset Mode */
- tsetmode(csiescseq.priv, 0, csiescseq.arg, csiescseq.narg);
+ tsetmode(xw, csiescseq.priv, 0, csiescseq.arg, csiescseq.narg);
break;
case 'M': /* DL -- Delete <n> lines */
DEFAULT(csiescseq.arg[0], 1);
- tdeleteline(csiescseq.arg[0]);
+ tdeleteline(term, csiescseq.arg[0]);
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);
+ tclearregion(term, term->c.x, term->c.y,
+ term->c.x + csiescseq.arg[0] - 1, term->c.y, 1);
break;
case 'P': /* DCH -- Delete <n> char */
DEFAULT(csiescseq.arg[0], 1);
- tdeletechar(csiescseq.arg[0]);
+ tdeletechar(term, csiescseq.arg[0]);
break;
case 'Z': /* CBT -- Cursor Backward Tabulation <n> tab stops */
DEFAULT(csiescseq.arg[0], 1);
while (csiescseq.arg[0]--)
- tputtab(0);
+ tputtab(term, 0);
break;
case 'd': /* VPA -- Move to <row> */
DEFAULT(csiescseq.arg[0], 1);
- tmoveato(term.c.x, csiescseq.arg[0] - 1);
+ tmoveato(term, term->c.x, csiescseq.arg[0] - 1);
break;
case 'h': /* SM -- Set terminal mode */
- tsetmode(csiescseq.priv, 1, csiescseq.arg, csiescseq.narg);
+ tsetmode(xw, csiescseq.priv, 1, csiescseq.arg, csiescseq.narg);
break;
case 'm': /* SGR -- Terminal attribute (color) */
- tsetattr(csiescseq.arg, csiescseq.narg);
+ tsetattr(term, csiescseq.arg, csiescseq.narg);
break;
case 'r': /* DECSTBM -- Set Scrolling Region */
if (csiescseq.priv) {
goto unknown;
} else {
DEFAULT(csiescseq.arg[0], 1);
- DEFAULT(csiescseq.arg[1], term.row);
- tsetscroll(csiescseq.arg[0] - 1,
+ DEFAULT(csiescseq.arg[1], term->row);
+ tsetscroll(term, csiescseq.arg[0] - 1,
csiescseq.arg[1] - 1);
- tmoveato(0, 0);
+ tmoveato(term, 0, 0);
}
break;
case 's': /* DECSC -- Save cursor position (ANSI.SYS) */
- tcursor(CURSOR_SAVE);
+ tcursor_save(term);
break;
case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */
- tcursor(CURSOR_LOAD);
+ tcursor_load(term);
break;
}
}
/* String escape handling */
+static struct str_escape strescseq;
+
static void strparse(void)
{
char *p = strescseq.buf;
@@ -1832,7 +1861,7 @@ static void strreset(void)
memset(&strescseq, 0, sizeof(strescseq));
}
-static void strhandle(void)
+static void strhandle(struct st_window *xw)
{
char *p = NULL;
int i, j, narg;
@@ -1847,7 +1876,7 @@ static void strhandle(void)
case 1:
case 2:
if (narg > 1)
- xsettitle(strescseq.args[1]);
+ xsettitle(xw, strescseq.args[1]);
break;
case 4: /* color set */
if (narg < 3)
@@ -1856,7 +1885,7 @@ static void strhandle(void)
/* fall through */
case 104: /* color reset, here p = NULL */
j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
- if (!xsetcolorname(j, p)) {
+ if (!xsetcolorname(xw, j, p)) {
fprintf(stderr,
"erresc: invalid color %s\n", p);
} else {
@@ -1864,7 +1893,7 @@ static void strhandle(void)
* TODO if defaultbg color is changed, borders
* are dirty
*/
- redraw(0);
+ redraw(xw, 0);
}
break;
default:
@@ -1874,7 +1903,7 @@ static void strhandle(void)
}
break;
case 'k': /* old title set compatibility */
- xsettitle(strescseq.args[0]);
+ xsettitle(xw, strescseq.args[0]);
break;
case 'P': /* DSC -- Device Control String */
case '_': /* APC -- Application Program Command */
@@ -1889,10 +1918,12 @@ static void strhandle(void)
/* more random input code */
-static void tputc(char *c, int len)
+static void tputc(struct st_window *xw,
+ char *c, int len)
{
unsigned char ascii = *c;
bool control = ascii < '\x20' || ascii == 0177;
+ struct st_term *term = &xw->term;
if (iofd != -1) {
if (xwrite(iofd, c, len) < 0) {
@@ -1907,14 +1938,14 @@ static void tputc(char *c, int len)
* STR sequences must be checked before anything else
* because it can use some control codes as part of the sequence.
*/
- if (term.esc & ESC_STR) {
+ if (term->esc & ESC_STR) {
switch (ascii) {
case '\033':
- term.esc = ESC_START | ESC_STR_END;
+ term->esc = ESC_START | ESC_STR_END;
break;
case '\a': /* backwards compatibility to xterm */
- term.esc = 0;
- strhandle();
+ term->esc = 0;
+ strhandle(xw);
break;
default:
if (strescseq.len + len <
@@ -1933,7 +1964,7 @@ static void tputc(char *c, int len)
* In the case users ever get fixed, here is the code:
*/
/*
- * term.esc = 0;
+ * term->esc = 0;
* strhandle();
*/
}
@@ -1949,27 +1980,27 @@ static void tputc(char *c, int len)
if (control) {
switch (ascii) {
case '\t': /* HT */
- tputtab(1);
+ tputtab(term, 1);
return;
case '\b': /* BS */
- tmoveto(term.c.x - 1, term.c.y);
+ tmoveto(term, term->c.x - 1, term->c.y);
return;
case '\r': /* CR */
- tmoveto(0, term.c.y);
+ tmoveto(term, 0, term->c.y);
return;
case '\f': /* LF */
case '\v': /* VT */
case '\n': /* LF */
/* go to first col if the mode is set */
- tnewline(IS_SET(MODE_CRLF));
+ tnewline(term, (term->mode & MODE_CRLF) != 0);
return;
case '\a': /* BEL */
- if (!(xw.state & WIN_FOCUSED))
- xseturgency(1);
+ if (!(xw->state & WIN_FOCUSED))
+ xseturgency(xw, 1);
return;
case '\033': /* ESC */
csireset();
- term.esc = ESC_START;
+ term->esc = ESC_START;
return;
case '\016': /* SO */
case '\017': /* SI */
@@ -1991,26 +2022,26 @@ static void tputc(char *c, int len)
case 0177: /* DEL (IGNORED) */
return;
}
- } else if (term.esc & ESC_START) {
- if (term.esc & ESC_CSI) {
+ } else if (term->esc & ESC_START) {
+ if (term->esc & ESC_CSI) {
csiescseq.buf[csiescseq.len++] = ascii;
if (BETWEEN(ascii, 0x40, 0x7E)
|| csiescseq.len >= sizeof(csiescseq.buf) - 1) {
- term.esc = 0;
+ term->esc = 0;
csiparse();
- csihandle();
+ csihandle(xw);
}
- } else if (term.esc & ESC_STR_END) {
- term.esc = 0;
+ } else if (term->esc & ESC_STR_END) {
+ term->esc = 0;
if (ascii == '\\')
- strhandle();
- } else if (term.esc & ESC_ALTCHARSET) {
+ strhandle(xw);
+ } else if (term->esc & ESC_ALTCHARSET) {
switch (ascii) {
case '0': /* Line drawing set */
- term.c.attr.mode |= ATTR_GFX;
+ term->c.attr.mode |= ATTR_GFX;
break;
case 'B': /* USASCII */
- term.c.attr.mode &= ~ATTR_GFX;
+ term->c.attr.mode &= ~ATTR_GFX;
break;
case 'A': /* UK (IGNORED) */
case '<': /* multinational charset (IGNORED) */
@@ -2023,26 +2054,26 @@ static void tputc(char *c, int len)
"esc unhandled charset: ESC ( %c\n",
ascii);
}
- term.esc = 0;
- } else if (term.esc & ESC_TEST) {
+ term->esc = 0;
+ } else if (term->esc & ESC_TEST) {
if (ascii == '8') { /* DEC screen alignment test. */
char E[UTF_SIZ] = "E";
int x, y;
- for (x = 0; x < term.col; ++x) {
- for (y = 0; y < term.row; ++y)
- tsetchar(E, &term.c.attr,
- x, y);
+ for (x = 0; x < term->col; ++x) {
+ for (y = 0; y < term->row; ++y)
+ tsetchar(term, E,
+ &term->c.attr, x, y);
}
}
- term.esc = 0;
+ term->esc = 0;
} else {
switch (ascii) {
case '[':
- term.esc |= ESC_CSI;
+ term->esc |= ESC_CSI;
break;
case '#':
- term.esc |= ESC_TEST;
+ term->esc |= ESC_TEST;
break;
case 'P': /* DCS -- Device Control String */
case '_': /* APC -- Application Program Command */
@@ -2051,74 +2082,74 @@ static void tputc(char *c, int len)
case 'k': /* old title set compatibility */
strreset();
strescseq.type = ascii;
- term.esc |= ESC_STR;
+ term->esc |= ESC_STR;
break;
case '(': /* set primary charset G0 */
- term.esc |= ESC_ALTCHARSET;
+ term->esc |= ESC_ALTCHARSET;
break;
case ')': /* set secondary charset G1 (IGNORED) */
case '*': /* set tertiary charset G2 (IGNORED) */
case '+': /* set quaternary charset G3 (IGNORED) */
- term.esc = 0;
+ term->esc = 0;
break;
case 'D': /* IND -- Linefeed */
- if (term.c.y == term.bot) {
- tscrollup(term.top, 1);
+ if (term->c.y == term->bot) {
+ tscrollup(term, term->top, 1);
} else {
- tmoveto(term.c.x, term.c.y + 1);
+ tmoveto(term, term->c.x, term->c.y + 1);
}
- term.esc = 0;
+ term->esc = 0;
break;
case 'E': /* NEL -- Next line */
- tnewline(1); /* always go to first col */
- term.esc = 0;
+ tnewline(term, 1); /* always go to first col */
+ term->esc = 0;
break;
case 'H': /* HTS -- Horizontal tab stop */
- term.tabs[term.c.x] = 1;
- term.esc = 0;
+ term->tabs[term->c.x] = 1;
+ term->esc = 0;
break;
case 'M': /* RI -- Reverse index */
- if (term.c.y == term.top) {
- tscrolldown(term.top, 1);
+ if (term->c.y == term->top) {
+ tscrolldown(term, term->top, 1);
} else {
- tmoveto(term.c.x, term.c.y - 1);
+ tmoveto(term, term->c.x, term->c.y - 1);
}
- term.esc = 0;
+ term->esc = 0;
break;
case 'Z': /* DECID -- Identify Terminal */
- ttywrite(VT102ID, sizeof(VT102ID) - 1);
- term.esc = 0;
+ ttywrite(term, VT102ID, sizeof(VT102ID) - 1);
+ term->esc = 0;
break;
case 'c': /* RIS -- Reset to inital state */
- treset();
- term.esc = 0;
- xresettitle();
+ treset(term);
+ term->esc = 0;
+ xresettitle(xw);
break;
case '=': /* DECPAM -- Application keypad */
- term.mode |= MODE_APPKEYPAD;
- term.esc = 0;
+ term->mode |= MODE_APPKEYPAD;
+ term->esc = 0;
break;
case '>': /* DECPNM -- Normal keypad */
- term.mode &= ~MODE_APPKEYPAD;
- term.esc = 0;
+ term->mode &= ~MODE_APPKEYPAD;
+ term->esc = 0;
break;
case '7': /* DECSC -- Save Cursor */
- tcursor(CURSOR_SAVE);
- term.esc = 0;
+ tcursor_save(term);
+ term->esc = 0;
break;
case '8': /* DECRC -- Restore Cursor */
- tcursor(CURSOR_LOAD);
- term.esc = 0;
+ tcursor_load(term);
+ term->esc = 0;
break;
case '\\': /* ST -- Stop */
- term.esc = 0;
+ term->esc = 0;
break;
default:
fprintf(stderr,
"erresc: unknown sequence ESC 0x%02X '%c'\n",
(unsigned char) ascii,
isprint(ascii) ? ascii : '.');
- term.esc = 0;
+ term->esc = 0;
}
}
/*
@@ -2130,50 +2161,54 @@ static void tputc(char *c, int len)
/*
* Display control codes only if we are in graphic mode
*/
- if (control && !(term.c.attr.mode & ATTR_GFX))
+ if (control && !(term->c.attr.mode & ATTR_GFX))
return;
- if (sel.bx != -1 && BETWEEN(term.c.y, sel.by, sel.ey))
- sel.bx = -1;
- if (IS_SET(MODE_WRAP) && term.c.state & CURSOR_WRAPNEXT)
- tnewline(1); /* always go to first col */
- if (IS_SET(MODE_INSERT) && term.c.x + 1 < term.col) {
- memmove(&term.line[term.c.y][term.c.x + 1],
- &term.line[term.c.y][term.c.x],
- (term.col - term.c.x - 1) * sizeof(struct glyph));
+ if (term->sel.bx != -1 &&
+ BETWEEN(term->c.y, term->sel.by, term->sel.ey))
+ term->sel.bx = -1;
+
+ if ((term->mode & MODE_WRAP) && term->c.state & CURSOR_WRAPNEXT)
+ tnewline(term, 1); /* always go to first col */
+
+ if ((term->mode & MODE_INSERT) && term->c.x + 1 < term->col) {
+ memmove(&term->line[term->c.y][term->c.x + 1],
+ &term->line[term->c.y][term->c.x],
+ (term->col - term->c.x - 1) * sizeof(struct glyph));
}
- tsetchar(c, &term.c.attr, term.c.x, term.c.y);
- if (term.c.x + 1 < term.col) {
- tmoveto(term.c.x + 1, term.c.y);
+ tsetchar(term, c, &term->c.attr, term->c.x, term->c.y);
+ if (term->c.x + 1 < term->col) {
+ tmoveto(term, term->c.x + 1, term->c.y);
} else {
- term.c.state |= CURSOR_WRAPNEXT;
+ term->c.state |= CURSOR_WRAPNEXT;
}
}
-static void techo(char *buf, int len)
+static void techo(struct st_window *xw,
+ char *buf, int len)
{
for (; len > 0; buf++, len--) {
char c = *buf;
if (c == '\033') { /* escape */
- tputc("^", 1);
- tputc("[", 1);
+ tputc(xw, "^", 1);
+ tputc(xw, "[", 1);
} else if (c < '\x20') { /* control code */
if (c != '\n' && c != '\r' && c != '\t') {
c |= '\x40';
- tputc("^", 1);
+ tputc(xw, "^", 1);
}
- tputc(&c, 1);
+ tputc(xw, &c, 1);
} else {
break;
}
}
if (len)
- tputc(buf, len);
+ tputc(xw, buf, len);
}
-static char *kmap(KeySym k, unsigned state)
+static char *kmap(struct st_term *term, KeySym k, unsigned state)
{
unsigned mask;
struct st_key *kp;
@@ -2199,23 +2234,20 @@ static char *kmap(KeySym k, unsigned state)
continue;
if (kp->appkey > 0) {
- if (!IS_SET(MODE_APPKEYPAD))
+ if (!(term->mode & MODE_APPKEYPAD))
continue;
- if (term.numlock && kp->appkey == 2)
+ if (term->numlock && kp->appkey == 2)
continue;
- } else if (kp->appkey < 0 && IS_SET(MODE_APPKEYPAD)) {
+ } else if (kp->appkey < 0 && (term->mode & MODE_APPKEYPAD))
continue;
- }
- if ((kp->appcursor < 0 && IS_SET(MODE_APPCURSOR)) ||
- (kp->appcursor > 0 && !IS_SET(MODE_APPCURSOR))) {
+ if ((kp->appcursor < 0 && (term->mode & MODE_APPCURSOR)) ||
+ (kp->appcursor > 0 && !(term->mode & MODE_APPCURSOR)))
continue;
- }
- if ((kp->crlf < 0 && IS_SET(MODE_CRLF)) ||
- (kp->crlf > 0 && !IS_SET(MODE_CRLF))) {
+ if ((kp->crlf < 0 && (term->mode & MODE_CRLF)) ||
+ (kp->crlf > 0 && !(term->mode & MODE_CRLF)))
continue;
- }
return kp->s;
}
@@ -2223,7 +2255,7 @@ static char *kmap(KeySym k, unsigned state)
return NULL;
}
-static void kpress(XEvent *ev)
+static void kpress(struct st_window *xw, XEvent *ev)
{
XKeyEvent *e = &ev->xkey;
KeySym ksym;
@@ -2232,22 +2264,22 @@ static void kpress(XEvent *ev)
Status status;
struct st_shortcut *bp;
- if (IS_SET(MODE_KBDLOCK))
+ if (xw->term.mode & MODE_KBDLOCK)
return;
- len =
- XmbLookupString(xw.xic, e, xstr, sizeof(xstr), &ksym, &status);
+ len = XmbLookupString(xw->xic, e, xstr, sizeof(xstr),
+ &ksym, &status);
e->state &= ~Mod2Mask;
/* 1. shortcuts */
for (bp = shortcuts; bp < shortcuts + ARRAY_SIZE(shortcuts); bp++) {
if (ksym == bp->keysym && match(bp->mod, e->state)) {
- bp->func(&(bp->arg));
+ bp->func(xw, &(bp->arg));
return;
}
}
/* 2. custom keys from config.h */
- if ((customkey = kmap(ksym, e->state))) {
+ if ((customkey = kmap(&xw->term, ksym, e->state))) {
len = strlen(customkey);
memcpy(buf, customkey, len);
/* 2. hardcoded (overrides X lookup) */
@@ -2262,110 +2294,113 @@ static void kpress(XEvent *ev)
len = cp - buf + len;
}
- ttywrite(buf, len);
- if (IS_SET(MODE_ECHO))
- techo(buf, len);
+ ttywrite(&xw->term, buf, len);
+ if (xw->term.mode & MODE_ECHO)
+ techo(xw, buf, len);
}
-static void ttyread(void)
+static void ttyread(struct st_window *xw)
{
- static unsigned char buf[BUFSIZ];
- static int buflen = 0;
+ struct st_term *term = &xw->term;
unsigned char *ptr;
int ret;
/* append read bytes to unprocessed bytes */
- if ((ret = read(cmdfd, buf + buflen, sizeof(buf) - buflen)) < 0)
+ if ((ret = read(term->cmdfd,
+ term->cmdbuf + term->cmdbuflen,
+ sizeof(term->cmdbuf) - term->cmdbuflen)) < 0)
die("Couldn't read from shell: %s\n", SERRNO);
/* process every complete utf8 char */
- buflen += ret;
- ptr = buf;
+ term->cmdbuflen += ret;
+ ptr = term->cmdbuf;
- while (buflen) {
+ while (term->cmdbuflen) {
unsigned ucs;
- int charsize = FcUtf8ToUcs4(ptr, &ucs, buflen);
+ int charsize = FcUtf8ToUcs4(ptr, &ucs, term->cmdbuflen);
if (charsize < 0) {
charsize = 1;
ucs = *ptr;
}
- if (charsize > buflen)
+ if (charsize > term->cmdbuflen)
break;
- tputc((char *) ptr, charsize);
+ tputc(xw, (char *) ptr, charsize);
ptr += charsize;
- buflen -= charsize;
+ term->cmdbuflen -= charsize;
}
/* keep any uncomplete utf8 char for the next call */
- memmove(buf, ptr, buflen);
+ memmove(term->cmdbuf, ptr, term->cmdbuflen);
}
/* Mouse code */
-static int x2col(int x)
+static int x2col(struct st_window *xw, int x)
{
x -= borderpx;
- x /= xw.cw;
+ x /= xw->cw;
- return min(x, term.col - 1);
+ return min(x, xw->term.col - 1);
}
-static int y2row(int y)
+static int y2row(struct st_window *xw, int y)
{
y -= borderpx;
- y /= xw.ch;
+ y /= xw->ch;
- return min(y, term.row - 1);
+ return min(y, xw->term.row - 1);
}
-static void getbuttoninfo(XEvent *e)
+static void getbuttoninfo(struct st_window *xw, XEvent *ev)
{
int type;
- unsigned state = e->xbutton.state & ~Button1Mask;
+ unsigned state = ev->xbutton.state & ~Button1Mask;
+ struct st_selection *sel = &xw->term.sel;
- sel.alt = IS_SET(MODE_ALTSCREEN);
+ sel->alt = (xw->term.mode & MODE_ALTSCREEN) != 0;
- sel.ex = x2col(e->xbutton.x);
- sel.ey = y2row(e->xbutton.y);
+ sel->ex = x2col(xw, ev->xbutton.x);
+ sel->ey = y2row(xw, ev->xbutton.y);
- sel.b.x = sel.by < sel.ey ? sel.bx : sel.ex;
- sel.b.y = min(sel.by, sel.ey);
- sel.e.x = sel.by < sel.ey ? sel.ex : sel.bx;
- sel.e.y = max(sel.by, sel.ey);
+ sel->b.x = sel->by < sel->ey ? sel->bx : sel->ex;
+ sel->b.y = min(sel->by, sel->ey);
+ sel->e.x = sel->by < sel->ey ? sel->ex : sel->bx;
+ sel->e.y = max(sel->by, sel->ey);
- sel.type = SEL_REGULAR;
+ sel->type = SEL_REGULAR;
for (type = 1; type < ARRAY_SIZE(selmasks); ++type) {
if (match(selmasks[type], state)) {
- sel.type = type;
+ sel->type = type;
break;
}
}
}
-static void mousereport(XEvent *e)
+static void mousereport(struct st_window *xw, XEvent *ev)
{
- int x = x2col(e->xbutton.x), y = y2row(e->xbutton.y),
- button = e->xbutton.button, state = e->xbutton.state, len;
+ int x = x2col(xw, ev->xbutton.x), y = y2row(xw, ev->xbutton.y),
+ button = ev->xbutton.button, state = ev->xbutton.state, len;
char buf[40];
static int ob, ox, oy;
/* from urxvt */
- if (e->xbutton.type == MotionNotify) {
- if (!IS_SET(MODE_MOUSEMOTION) || (x == ox && y == oy))
+ if (ev->xbutton.type == MotionNotify) {
+ if (!(xw->term.mode & MODE_MOUSEMOTION) ||
+ (x == ox && y == oy))
return;
button = ob + 32;
ox = x, oy = y;
- } else if (!IS_SET(MODE_MOUSESGR)
- && (e->xbutton.type == ButtonRelease
+ } else if (!(xw->term.mode & MODE_MOUSESGR)
+ && (ev->xbutton.type == ButtonRelease
|| button == AnyButton)) {
button = 3;
} else {
button -= Button1;
if (button >= 3)
button += 64 - 3;
- if (e->xbutton.type == ButtonPress) {
+ if (ev->xbutton.type == ButtonPress) {
ob = button;
ox = x, oy = y;
}
@@ -2376,10 +2411,10 @@ static void mousereport(XEvent *e)
+ (state & ControlMask ? 16 : 0);
len = 0;
- if (IS_SET(MODE_MOUSESGR)) {
+ if (xw->term.mode & MODE_MOUSESGR) {
len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c",
button, x + 1, y + 1,
- e->xbutton.type ==
+ ev->xbutton.type ==
ButtonRelease ? 'm' : 'M');
} else if (x < 223 && y < 223) {
len = snprintf(buf, sizeof(buf), "\033[M%c%c%c",
@@ -2388,134 +2423,142 @@ static void mousereport(XEvent *e)
return;
}
- ttywrite(buf, len);
+ ttywrite(&xw->term, buf, len);
}
-static void bpress(XEvent *e)
+static void bpress(struct st_window *xw, XEvent *ev)
{
- if (IS_SET(MODE_MOUSE)) {
- mousereport(e);
- } else if (e->xbutton.button == Button1) {
- if (sel.bx != -1) {
- sel.bx = -1;
- tsetdirt(sel.b.y, sel.e.y);
- draw();
+ struct st_term *term = &xw->term;
+ struct st_selection *sel = &xw->term.sel;
+
+ if (term->mode & MODE_MOUSE) {
+ mousereport(xw, ev);
+ } else if (ev->xbutton.button == Button1) {
+ if (sel->bx != -1) {
+ sel->bx = -1;
+ tsetdirt(&xw->term, sel->b.y, sel->e.y);
+ draw(xw);
}
- sel.mode = 1;
- sel.type = SEL_REGULAR;
- sel.ex = sel.bx = x2col(e->xbutton.x);
- sel.ey = sel.by = y2row(e->xbutton.y);
- } else if (e->xbutton.button == Button4) {
- ttywrite("\031", 1);
- } else if (e->xbutton.button == Button5) {
- ttywrite("\005", 1);
+ sel->mode = 1;
+ sel->type = SEL_REGULAR;
+ sel->ex = sel->bx = x2col(xw, ev->xbutton.x);
+ sel->ey = sel->by = y2row(xw, ev->xbutton.y);
+ } else if (ev->xbutton.button == Button4) {
+ ttywrite(term, "\031", 1);
+ } else if (ev->xbutton.button == Button5) {
+ ttywrite(term, "\005", 1);
}
}
-static void brelease(XEvent *e)
+static void brelease(struct st_window *xw, XEvent *e)
{
+ struct st_term *term = &xw->term;
+ struct st_selection *sel = &term->sel;
struct timeval now;
- if (IS_SET(MODE_MOUSE)) {
- mousereport(e);
+ if (term->mode & MODE_MOUSE) {
+ mousereport(xw, e);
return;
}
if (e->xbutton.button == Button2) {
- selpaste(NULL);
+ selpaste(xw, NULL);
} else if (e->xbutton.button == Button1) {
- sel.mode = 0;
- getbuttoninfo(e);
- term.dirty[sel.ey] = 1;
- if (sel.bx == sel.ex && sel.by == sel.ey) {
- sel.bx = -1;
+ sel->mode = 0;
+ getbuttoninfo(xw, e);
+ term->dirty[sel->ey] = 1;
+ if (sel->bx == sel->ex && sel->by == sel->ey) {
+ sel->bx = -1;
gettimeofday(&now, NULL);
- if (TIMEDIFF(now, sel.tclick2) <=
+ if (TIMEDIFF(now, sel->tclick2) <=
tripleclicktimeout) {
/* triple click on the line */
- sel.b.x = sel.bx = 0;
- sel.e.x = sel.ex = term.col;
- sel.b.y = sel.e.y = sel.ey;
- selcopy();
- } else if (TIMEDIFF(now, sel.tclick1) <=
+ sel->b.x = sel->bx = 0;
+ sel->e.x = sel->ex = term->col;
+ sel->b.y = sel->e.y = sel->ey;
+ selcopy(xw);
+ } else if (TIMEDIFF(now, sel->tclick1) <=
doubleclicktimeout) {
/* double click to select word */
- sel.bx = sel.ex;
- while (sel.bx > 0
- && term.line[sel.ey][sel.bx -
+ sel->bx = sel->ex;
+ while (sel->bx > 0
+ && term->line[sel->ey][sel->bx -
1].
state & GLYPH_SET
- && term.line[sel.ey][sel.bx -
+ && term->line[sel->ey][sel->bx -
1].c[0] !=
' ') {
- sel.bx--;
+ sel->bx--;
}
- sel.b.x = sel.bx;
- while (sel.ex < term.col - 1
- && term.line[sel.ey][sel.ex +
+ sel->b.x = sel->bx;
+ while (sel->ex < term->col - 1
+ && term->line[sel->ey][sel->ex +
1].
state & GLYPH_SET
- && term.line[sel.ey][sel.ex +
+ && term->line[sel->ey][sel->ex +
1].c[0] !=
' ') {
- sel.ex++;
+ sel->ex++;
}
- sel.e.x = sel.ex;
- sel.b.y = sel.e.y = sel.ey;
- selcopy();
+ sel->e.x = sel->ex;
+ sel->b.y = sel->e.y = sel->ey;
+ selcopy(xw);
}
} else {
- selcopy();
+ selcopy(xw);
}
}
- memcpy(&sel.tclick2, &sel.tclick1, sizeof(struct timeval));
- gettimeofday(&sel.tclick1, NULL);
+ memcpy(&sel->tclick2, &sel->tclick1, sizeof(struct timeval));
+ gettimeofday(&sel->tclick1, NULL);
}
-static void bmotion(XEvent *e)
+static void bmotion(struct st_window *xw, XEvent *e)
{
+ struct st_term *term = &xw->term;
int oldey, oldex, oldsby, oldsey;
- if (IS_SET(MODE_MOUSE)) {
- mousereport(e);
+ if (term->mode & MODE_MOUSE) {
+ mousereport(xw, e);
return;
}
- if (!sel.mode)
+ if (!term->sel.mode)
return;
- oldey = sel.ey;
- oldex = sel.ex;
- oldsby = sel.b.y;
- oldsey = sel.e.y;
- getbuttoninfo(e);
+ oldey = term->sel.ey;
+ oldex = term->sel.ex;
+ oldsby = term->sel.b.y;
+ oldsey = term->sel.e.y;
+ getbuttoninfo(xw, e);
- if (oldey != sel.ey || oldex != sel.ex)
- tsetdirt(min(sel.b.y, oldsby), max(sel.e.y, oldsey));
+ if (oldey != term->sel.ey || oldex != term->sel.ex)
+ tsetdirt(term,
+ min(term->sel.b.y, oldsby),
+ max(term->sel.e.y, oldsey));
}
/* Resizing code */
-static void ttyresize(void)
+static void ttyresize(struct st_window *xw)
{
struct winsize w;
- w.ws_row = term.row;
- w.ws_col = term.col;
- w.ws_xpixel = xw.tw;
- w.ws_ypixel = xw.th;
- if (ioctl(cmdfd, TIOCSWINSZ, &w) < 0)
+ w.ws_row = xw->term.row;
+ w.ws_col = xw->term.col;
+ w.ws_xpixel = xw->tw;
+ w.ws_ypixel = xw->th;
+ if (ioctl(xw->term.cmdfd, TIOCSWINSZ, &w) < 0)
fprintf(stderr, "Couldn't set window size: %s\n", SERRNO);
}
-static int tresize(int col, int row)
+static int tresize(struct st_term *term, int col, int row)
{
int i, x;
- int minrow = min(row, term.row);
- int mincol = min(col, term.col);
- int slide = term.c.y - row + 1;
+ int minrow = min(row, term->row);
+ int mincol = min(col, term->col);
+ int slide = term->c.y - row + 1;
bool *bp;
if (col < 1 || row < 1)
@@ -2530,111 +2573,114 @@ static int tresize(int col, int row)
* memmove because we're freeing the earlier lines
*/
for ( /* i = 0 */ ; i < slide; i++) {
- free(term.line[i]);
- free(term.alt[i]);
+ free(term->line[i]);
+ free(term->alt[i]);
}
- memmove(term.line, term.line + slide,
+ memmove(term->line, term->line + slide,
row * sizeof(struct glyph *));
- memmove(term.alt, term.alt + slide,
+ memmove(term->alt, term->alt + slide,
row * sizeof(struct glyph *));
}
- for (i += row; i < term.row; i++) {
- free(term.line[i]);
- free(term.alt[i]);
+ for (i += row; i < term->row; i++) {
+ free(term->line[i]);
+ free(term->alt[i]);
}
/* resize to new height */
- term.line = xrealloc(term.line, row * sizeof(struct glyph *));
- term.alt = xrealloc(term.alt, row * sizeof(struct glyph *));
- term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty));
- term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs));
+ term->line = xrealloc(term->line, row * sizeof(struct glyph *));
+ term->alt = xrealloc(term->alt, row * sizeof(struct glyph *));
+ term->dirty = xrealloc(term->dirty, row * sizeof(*term->dirty));
+ term->tabs = xrealloc(term->tabs, col * sizeof(*term->tabs));
/* resize each row to new width, zero-pad if needed */
for (i = 0; i < minrow; i++) {
- term.dirty[i] = 1;
- term.line[i] = xrealloc(term.line[i], col * sizeof(struct glyph));
- term.alt[i] = xrealloc(term.alt[i], col * sizeof(struct glyph));
+ term->dirty[i] = 1;
+ term->line[i] = xrealloc(term->line[i], col * sizeof(struct glyph));
+ term->alt[i] = xrealloc(term->alt[i], col * sizeof(struct glyph));
for (x = mincol; x < col; x++) {
- term.line[i][x].state = 0;
- term.alt[i][x].state = 0;
+ term->line[i][x].state = 0;
+ term->alt[i][x].state = 0;
}
}
/* allocate any new rows */
for ( /* i == minrow */ ; i < row; i++) {
- term.dirty[i] = 1;
- term.line[i] = xcalloc(col, sizeof(struct glyph));
- term.alt[i] = xcalloc(col, sizeof(struct glyph));
+ term->dirty[i] = 1;
+ term->line[i] = xcalloc(col, sizeof(struct glyph));
+ term->alt[i] = xcalloc(col, sizeof(struct glyph));
}
- if (col > term.col) {
- bp = term.tabs + term.col;
+ if (col > term->col) {
+ bp = term->tabs + term->col;
- memset(bp, 0, sizeof(*term.tabs) * (col - term.col));
- while (--bp > term.tabs && !*bp)
+ memset(bp, 0, sizeof(*term->tabs) * (col - term->col));
+ while (--bp > term->tabs && !*bp)
/* nothing */ ;
- for (bp += tabspaces; bp < term.tabs + col;
+ for (bp += tabspaces; bp < term->tabs + col;
bp += tabspaces)
*bp = 1;
}
/* update terminal size */
- term.col = col;
- term.row = row;
+ term->col = col;
+ term->row = row;
/* reset scrolling region */
- tsetscroll(0, row - 1);
+ tsetscroll(term, 0, row - 1);
/* make use of the LIMIT in tmoveto */
- tmoveto(term.c.x, term.c.y);
+ tmoveto(term, term->c.x, term->c.y);
return (slide > 0);
}
-static void xresize(int col, int row)
+static void xresize(struct st_window *xw, int col, int row)
{
- xw.tw = max(1, col * xw.cw);
- xw.th = max(1, row * xw.ch);
+ xw->tw = max(1, col * xw->cw);
+ xw->th = max(1, row * xw->ch);
- XFreePixmap(xw.dpy, xw.buf);
- xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h,
- DefaultDepth(xw.dpy, xw.scr));
- XSetForeground(xw.dpy, xw.gc,
- xw.
- col[IS_SET(MODE_REVERSE) ? defaultfg : defaultbg].
+ XFreePixmap(xw->dpy, xw->buf);
+ xw->buf = XCreatePixmap(xw->dpy, xw->win,
+ xw->w, xw->h,
+ DefaultDepth(xw->dpy, xw->scr));
+ XSetForeground(xw->dpy, xw->gc,
+ xw->col[xw->term.mode & MODE_REVERSE
+ ? defaultfg : defaultbg].
pixel);
- XFillRectangle(xw.dpy, xw.buf, xw.gc, 0, 0, xw.w, xw.h);
+ XFillRectangle(xw->dpy, xw->buf, xw->gc, 0, 0,
+ xw->w, xw->h);
- XftDrawChange(xw.draw, xw.buf);
+ XftDrawChange(xw->draw, xw->buf);
}
-static void cresize(int width, int height)
+static void cresize(struct st_window *xw, int width, int height)
{
int col, row;
if (width != 0)
- xw.w = width;
+ xw->w = width;
if (height != 0)
- xw.h = height;
+ xw->h = height;
- col = (xw.w - 2 * borderpx) / xw.cw;
- row = (xw.h - 2 * borderpx) / xw.ch;
+ col = (xw->w - 2 * borderpx) / xw->cw;
+ row = (xw->h - 2 * borderpx) / xw->ch;
- tresize(col, row);
- xresize(col, row);
- ttyresize();
+ tresize(&xw->term, col, row);
+ xresize(xw, col, row);
+ ttyresize(xw);
}
-static void resize(XEvent *ev)
+static void resize(struct st_window *xw, XEvent *ev)
{
- if (ev->xconfigure.width == xw.w && ev->xconfigure.height == xw.h)
+ if (ev->xconfigure.width == xw->w &&
+ ev->xconfigure.height == xw->h)
return;
- cresize(ev->xconfigure.width, ev->xconfigure.height);
+ cresize(xw, ev->xconfigure.width, ev->xconfigure.height);
}
/* Start of st */
-static void ttynew(void)
+static void ttynew(struct st_window *xw)
{
int m, s;
- struct winsize w = { term.row, term.col, 0, 0 };
+ struct winsize w = { xw->term.row, xw->term.col, 0, 0 };
/* seems to work fine on linux, openbsd and freebsd */
if (openpty(&m, &s, NULL, NULL, &w) < 0)
@@ -2653,11 +2699,11 @@ static void ttynew(void)
die("ioctl TIOCSCTTY failed: %s\n", SERRNO);
close(s);
close(m);
- execsh();
+ execsh(xw->win);
break;
default:
close(s);
- cmdfd = m;
+ xw->term.cmdfd = m;
signal(SIGCHLD, sigchld);
if (opt_io) {
iofd = (!strcmp(opt_io, "-")) ?
@@ -2671,41 +2717,37 @@ static void ttynew(void)
}
}
-static void tnew(int col, int row)
+static void tnew(struct st_term *term, int col, int row)
{
/* set screen size */
- term.row = row;
- term.col = col;
- term.line = xmalloc(term.row * sizeof(struct glyph *));
- term.alt = xmalloc(term.row * sizeof(struct glyph *));
- term.dirty = xmalloc(term.row * sizeof(*term.dirty));
- term.tabs = xmalloc(term.col * sizeof(*term.tabs));
+ term->row = row;
+ term->col = col;
+ term->line = xmalloc(term->row * sizeof(struct glyph *));
+ term->alt = xmalloc(term->row * sizeof(struct glyph *));
+ term->dirty = xmalloc(term->row * sizeof(*term->dirty));
+ term->tabs = xmalloc(term->col * sizeof(*term->tabs));
- for (row = 0; row < term.row; row++) {
- term.line[row] = xmalloc(term.col * sizeof(struct glyph));
- term.alt[row] = xmalloc(term.col * sizeof(struct glyph));
- term.dirty[row] = 0;
+ for (row = 0; row < term->row; row++) {
+ term->line[row] = xmalloc(term->col * sizeof(struct glyph));
+ term->alt[row] = xmalloc(term->col * sizeof(struct glyph));
+ term->dirty[row] = 0;
}
- term.numlock = 1;
- memset(term.tabs, 0, term.col * sizeof(*term.tabs));
+ term->numlock = 1;
+ memset(term->tabs, 0, term->col * sizeof(*term->tabs));
/* setup screen */
- treset();
+ treset(term);
}
-static void selinit(void)
+static void selinit(struct st_window *xw)
{
- memset(&sel.tclick1, 0, sizeof(sel.tclick1));
- memset(&sel.tclick2, 0, sizeof(sel.tclick2));
- sel.mode = 0;
- sel.bx = -1;
- sel.clip = NULL;
- sel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0);
- if (sel.xtarget == None)
- sel.xtarget = XA_STRING;
+ xw->term.sel.bx = -1;
+ xw->term.sel.xtarget = XInternAtom(xw->dpy, "UTF8_STRING", 0);
+ if (xw->term.sel.xtarget == None)
+ xw->term.sel.xtarget = XA_STRING;
}
-static void xloadcols(void)
+static void xloadcols(struct st_window *xw)
{
int i, r, g, b;
XRenderColor color = {.alpha = 0xffff };
@@ -2714,11 +2756,9 @@ static void xloadcols(void)
for (i = 0; i < ARRAY_SIZE(colorname); i++) {
if (!colorname[i])
continue;
- if (!XftColorAllocName
- (xw.dpy, xw.vis, xw.cmap, colorname[i], &xw.col[i])) {
- die("Could not allocate color '%s'\n",
- colorname[i]);
- }
+ if (!XftColorAllocName(xw->dpy, xw->vis, xw->cmap,
+ colorname[i], &xw->col[i]))
+ die("Could not allocate color '%s'\n", colorname[i]);
}
/* load colors [16-255] ; same colors as xterm */
@@ -2728,11 +2768,10 @@ static void xloadcols(void)
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,
- &xw.col[i])) {
+ if (!XftColorAllocValue(xw->dpy, xw->vis,
+ xw->cmap, &color,
+ &xw->col[i]))
die("Could not allocate color %d\n", i);
- }
i++;
}
}
@@ -2740,40 +2779,40 @@ static void xloadcols(void)
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,
- &xw.col[i])) {
+ if (!XftColorAllocValue(xw->dpy, xw->vis, xw->cmap,
+ &color, &xw->col[i]))
die("Could not allocate color %d\n", i);
- }
}
}
-static void xhints(void)
+static void xhints(struct st_window *xw)
{
- XClassHint class = { opt_class ? opt_class : termname, termname };
+ XClassHint class = { xw->class, termname };
XWMHints wm = {.flags = InputHint,.input = 1 };
XSizeHints *sizeh = NULL;
sizeh = XAllocSizeHints();
- if (xw.isfixed == False) {
+ if (xw->isfixed == False) {
sizeh->flags = PSize | PResizeInc | PBaseSize;
- sizeh->height = xw.h;
- sizeh->width = xw.w;
- sizeh->height_inc = xw.ch;
- sizeh->width_inc = xw.cw;
+ sizeh->height = xw->h;
+ sizeh->width = xw->w;
+ sizeh->height_inc = xw->ch;
+ sizeh->width_inc = xw->cw;
sizeh->base_height = 2 * borderpx;
sizeh->base_width = 2 * borderpx;
} else {
sizeh->flags = PMaxSize | PMinSize;
- sizeh->min_width = sizeh->max_width = xw.fw;
- sizeh->min_height = sizeh->max_height = xw.fh;
+ sizeh->min_width = sizeh->max_width = xw->fw;
+ sizeh->min_height = sizeh->max_height = xw->fh;
}
- XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm,
- &class);
+ XSetWMProperties(xw->dpy, xw->win, NULL, NULL, NULL,
+ 0, sizeh, &wm, &class);
XFree(sizeh);
}
-static int xloadfont(struct st_font *f, FcPattern *pattern)
+static int xloadfont(struct st_window *xw, struct st_font *f,
+ FcPattern *pattern)
{
FcPattern *match;
FcResult result;
@@ -2787,7 +2826,7 @@ static int xloadfont(struct st_font *f, FcPattern *pattern)
return 1;
}
- if (!(f->match = XftFontOpenPattern(xw.dpy, match))) {
+ if (!(f->match = XftFontOpenPattern(xw->dpy, match))) {
FcPatternDestroy(match);
return 1;
}
@@ -2805,7 +2844,8 @@ static int xloadfont(struct st_font *f, FcPattern *pattern)
return 0;
}
-static void xloadfonts(char *fontstr, int fontsize)
+static void xloadfonts(struct st_window *xw,
+ char *fontstr, int fontsize)
{
FcPattern *pattern;
FcResult result;
@@ -2844,32 +2884,32 @@ static void xloadfonts(char *fontstr, int fontsize)
FcConfigSubstitute(0, pattern, FcMatchPattern);
FcDefaultSubstitute(pattern);
- if (xloadfont(&xw.font, pattern))
+ if (xloadfont(xw, &xw->font, pattern))
die("st: can't open font %s\n", fontstr);
/* Setting character width and height. */
- xw.cw = xw.font.width;
- xw.ch = xw.font.height;
+ xw->cw = xw->font.width;
+ xw->ch = xw->font.height;
FcPatternDel(pattern, FC_SLANT);
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
- if (xloadfont(&xw.ifont, pattern))
+ if (xloadfont(xw, &xw->ifont, pattern))
die("st: can't open font %s\n", fontstr);
FcPatternDel(pattern, FC_WEIGHT);
FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
- if (xloadfont(&xw.ibfont, pattern))
+ if (xloadfont(xw, &xw->ibfont, pattern))
die("st: can't open font %s\n", fontstr);
FcPatternDel(pattern, FC_SLANT);
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
- if (xloadfont(&xw.bfont, pattern))
+ if (xloadfont(xw, &xw->bfont, pattern))
die("st: can't open font %s\n", fontstr);
FcPatternDestroy(pattern);
}
-static void xunloadfonts(void)
+static void xunloadfonts(struct st_window *xw)
{
int i, ip;
@@ -2880,34 +2920,34 @@ static void xunloadfonts(void)
for (i = 0, ip = frccur; i < frclen; i++, ip--) {
if (ip < 0)
ip = ARRAY_SIZE(frc) - 1;
- XftFontClose(xw.dpy, frc[ip].font);
+ XftFontClose(xw->dpy, frc[ip].font);
}
frccur = -1;
frclen = 0;
- XftFontClose(xw.dpy, xw.font.match);
- FcPatternDestroy(xw.font.pattern);
- FcFontSetDestroy(xw.font.set);
- XftFontClose(xw.dpy, xw.bfont.match);
- FcPatternDestroy(xw.bfont.pattern);
- FcFontSetDestroy(xw.bfont.set);
- XftFontClose(xw.dpy, xw.ifont.match);
- FcPatternDestroy(xw.ifont.pattern);
- FcFontSetDestroy(xw.ifont.set);
- XftFontClose(xw.dpy, xw.ibfont.match);
- FcPatternDestroy(xw.ibfont.pattern);
- FcFontSetDestroy(xw.ibfont.set);
+ XftFontClose(xw->dpy, xw->font.match);
+ FcPatternDestroy(xw->font.pattern);
+ FcFontSetDestroy(xw->font.set);
+ XftFontClose(xw->dpy, xw->bfont.match);
+ FcPatternDestroy(xw->bfont.pattern);
+ FcFontSetDestroy(xw->bfont.set);
+ XftFontClose(xw->dpy, xw->ifont.match);
+ FcPatternDestroy(xw->ifont.pattern);
+ FcFontSetDestroy(xw->ifont.set);
+ XftFontClose(xw->dpy, xw->ibfont.match);
+ FcPatternDestroy(xw->ibfont.pattern);
+ FcFontSetDestroy(xw->ibfont.set);
}
-static void xzoom(const union st_arg *arg)
+static void xzoom(struct st_window *xw, const union st_arg *arg)
{
- xunloadfonts();
- xloadfonts(usedfont, usedfontsize + arg->i);
- cresize(0, 0);
- redraw(0);
+ xunloadfonts(xw);
+ xloadfonts(xw, usedfont, usedfontsize + arg->i);
+ cresize(xw, 0, 0);
+ redraw(xw, 0);
}
-static void xinit(void)
+static void xinit(struct st_window *xw)
{
XSetWindowAttributes attrs;
XGCValues gcvalues;
@@ -2915,136 +2955,138 @@ static void xinit(void)
Window parent;
int sw, sh;
- if (!(xw.dpy = XOpenDisplay(NULL)))
+ if (!(xw->dpy = XOpenDisplay(NULL)))
die("Can't open display\n");
- xw.scr = XDefaultScreen(xw.dpy);
- xw.vis = XDefaultVisual(xw.dpy, xw.scr);
+ xw->scr = XDefaultScreen(xw->dpy);
+ xw->vis = XDefaultVisual(xw->dpy, xw->scr);
/* font */
if (!FcInit())
die("Could not init fontconfig.\n");
usedfont = (opt_font == NULL) ? font : opt_font;
- xloadfonts(usedfont, 0);
+ xloadfonts(xw, usedfont, 0);
/* colors */
- xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
- xloadcols();
+ xw->cmap = XDefaultColormap(xw->dpy, xw->scr);
+ xloadcols(xw);
/* adjust fixed window geometry */
- if (xw.isfixed) {
- sw = DisplayWidth(xw.dpy, xw.scr);
- sh = DisplayHeight(xw.dpy, xw.scr);
- if (xw.fx < 0)
- xw.fx = sw + xw.fx - xw.fw - 1;
- if (xw.fy < 0)
- xw.fy = sh + xw.fy - xw.fh - 1;
-
- xw.h = xw.fh;
- xw.w = xw.fw;
+ if (xw->isfixed) {
+ sw = DisplayWidth(xw->dpy, xw->scr);
+ sh = DisplayHeight(xw->dpy, xw->scr);
+ if (xw->fx < 0)
+ xw->fx = sw + xw->fx - xw->fw - 1;
+ if (xw->fy < 0)
+ xw->fy = sh + xw->fy - xw->fh - 1;
+
+ xw->h = xw->fh;
+ xw->w = xw->fw;
} else {
/* window - default size */
- xw.h = 2 * borderpx + term.row * xw.ch;
- xw.w = 2 * borderpx + term.col * xw.cw;
- xw.fx = 0;
- xw.fy = 0;
+ xw->h = 2 * borderpx + xw->term.row * xw->ch;
+ xw->w = 2 * borderpx + xw->term.col * xw->cw;
+ xw->fx = 0;
+ xw->fy = 0;
}
/* Events */
- attrs.background_pixel = xw.col[defaultbg].pixel;
- attrs.border_pixel = xw.col[defaultbg].pixel;
+ attrs.background_pixel = xw->col[defaultbg].pixel;
+ attrs.border_pixel = xw->col[defaultbg].pixel;
attrs.bit_gravity = NorthWestGravity;
attrs.event_mask = FocusChangeMask | KeyPressMask
| ExposureMask | VisibilityChangeMask | StructureNotifyMask
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
- attrs.colormap = xw.cmap;
+ attrs.colormap = xw->cmap;
- parent = opt_embed ? strtol(opt_embed, NULL, 0) :
- XRootWindow(xw.dpy, xw.scr);
- xw.win = XCreateWindow(xw.dpy, parent, xw.fx, xw.fy,
- xw.w, xw.h, 0, XDefaultDepth(xw.dpy,
- xw.scr),
- InputOutput, xw.vis,
- CWBackPixel | CWBorderPixel | CWBitGravity |
- CWEventMask | CWColormap, &attrs);
+ parent = xw->embed ? strtol(xw->embed, NULL, 0) :
+ XRootWindow(xw->dpy, xw->scr);
+ xw->win = XCreateWindow(xw->dpy, parent, xw->fx, xw->fy,
+ xw->w, xw->h, 0,
+ XDefaultDepth(xw->dpy, xw->scr),
+ InputOutput, xw->vis,
+ CWBackPixel | CWBorderPixel | CWBitGravity |
+ CWEventMask | CWColormap, &attrs);
memset(&gcvalues, 0, sizeof(gcvalues));
gcvalues.graphics_exposures = False;
- xw.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, &gcvalues);
- xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h,
- DefaultDepth(xw.dpy, xw.scr));
- XSetForeground(xw.dpy, xw.gc, xw.col[defaultbg].pixel);
- XFillRectangle(xw.dpy, xw.buf, xw.gc, 0, 0, xw.w, xw.h);
+ xw->gc = XCreateGC(xw->dpy, parent, GCGraphicsExposures, &gcvalues);
+ xw->buf = XCreatePixmap(xw->dpy, xw->win, xw->w, xw->h,
+ DefaultDepth(xw->dpy, xw->scr));
+ XSetForeground(xw->dpy, xw->gc, xw->col[defaultbg].pixel);
+ XFillRectangle(xw->dpy, xw->buf, xw->gc,
+ 0, 0, xw->w, xw->h);
/* Xft rendering context */
- xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
+ xw->draw = XftDrawCreate(xw->dpy, xw->buf,
+ xw->vis, xw->cmap);
/* input methods */
- if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
+ if ((xw->xim = XOpenIM(xw->dpy, NULL, NULL, NULL)) == NULL) {
XSetLocaleModifiers("@im=local");
- if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
+ if ((xw->xim = XOpenIM(xw->dpy, NULL, NULL, NULL)) == NULL) {
XSetLocaleModifiers("@im=");
- if ((xw.xim = XOpenIM(xw.dpy,
+ if ((xw->xim = XOpenIM(xw->dpy,
NULL, NULL, NULL)) == NULL) {
die("XOpenIM failed. Could not open input"
" device.\n");
}
}
}
- xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing
- | XIMStatusNothing, XNClientWindow, xw.win,
- XNFocusWindow, xw.win, NULL);
- if (xw.xic == NULL)
+ xw->xic = XCreateIC(xw->xim, XNInputStyle, XIMPreeditNothing
+ | XIMStatusNothing, XNClientWindow, xw->win,
+ XNFocusWindow, xw->win, NULL);
+ if (xw->xic == NULL)
die("XCreateIC failed. Could not obtain input method.\n");
/* white cursor, black outline */
- cursor = XCreateFontCursor(xw.dpy, XC_xterm);
- XDefineCursor(xw.dpy, xw.win, cursor);
- XRecolorCursor(xw.dpy, cursor, &(XColor) {
+ cursor = XCreateFontCursor(xw->dpy, XC_xterm);
+ XDefineCursor(xw->dpy, xw->win, cursor);
+ XRecolorCursor(xw->dpy, cursor, &(XColor) {
.red = 0xffff,.green = 0xffff,.blue = 0xffff}
, &(XColor) {
.red = 0x0000,.green = 0x0000,.blue = 0x0000}
);
- xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
- xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
- XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1);
+ xw->xembed = XInternAtom(xw->dpy, "_XEMBED", False);
+ xw->wmdeletewin = XInternAtom(xw->dpy, "WM_DELETE_WINDOW", False);
+ XSetWMProtocols(xw->dpy, xw->win, &xw->wmdeletewin, 1);
- xresettitle();
- XMapWindow(xw.dpy, xw.win);
- xhints();
- XSync(xw.dpy, 0);
+ xresettitle(xw);
+ XMapWindow(xw->dpy, xw->win);
+ xhints(xw);
+ XSync(xw->dpy, 0);
}
-static void expose(XEvent *ev)
+static void expose(struct st_window *xw, XEvent *ev)
{
XExposeEvent *e = &ev->xexpose;
- if (xw.state & WIN_REDRAW) {
+ if (xw->state & WIN_REDRAW) {
if (!e->count)
- xw.state &= ~WIN_REDRAW;
+ xw->state &= ~WIN_REDRAW;
}
- redraw(0);
+ redraw(xw, 0);
}
-static void visibility(XEvent *ev)
+static void visibility(struct st_window *xw, XEvent *ev)
{
XVisibilityEvent *e = &ev->xvisibility;
if (e->state == VisibilityFullyObscured) {
- xw.state &= ~WIN_VISIBLE;
- } else if (!(xw.state & WIN_VISIBLE)) {
+ xw->state &= ~WIN_VISIBLE;
+ } else if (!(xw->state & WIN_VISIBLE)) {
/* need a full redraw for next Expose, not just a buf copy */
- xw.state |= WIN_VISIBLE | WIN_REDRAW;
+ xw->state |= WIN_VISIBLE | WIN_REDRAW;
}
}
-static void unmap(XEvent *ev)
+static void unmap(struct st_window *xw, XEvent *ev)
{
- xw.state &= ~WIN_VISIBLE;
+ xw->state &= ~WIN_VISIBLE;
}
-static void focus(XEvent *ev)
+static void focus(struct st_window *xw, XEvent *ev)
{
XFocusChangeEvent *e = &ev->xfocus;
@@ -3052,71 +3094,71 @@ static void focus(XEvent *ev)
return;
if (ev->type == FocusIn) {
- XSetICFocus(xw.xic);
- xw.state |= WIN_FOCUSED;
- xseturgency(0);
+ XSetICFocus(xw->xic);
+ xw->state |= WIN_FOCUSED;
+ xseturgency(xw, 0);
} else {
- XUnsetICFocus(xw.xic);
- xw.state &= ~WIN_FOCUSED;
+ XUnsetICFocus(xw->xic);
+ xw->state &= ~WIN_FOCUSED;
}
}
-static void numlock(const union st_arg * dummy)
+static void numlock(struct st_window *xw, const union st_arg *dummy)
{
- term.numlock ^= 1;
+ xw->term.numlock ^= 1;
}
-static void cmessage(XEvent *ev)
+static void cmessage(struct st_window *xw, XEvent *ev)
{
/*
* See xembed specs
* http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html
*/
- if (ev->xclient.message_type == xw.xembed
+ if (ev->xclient.message_type == xw->xembed
&& ev->xclient.format == 32) {
if (ev->xclient.data.l[1] == XEMBED_FOCUS_IN) {
- xw.state |= WIN_FOCUSED;
- xseturgency(0);
+ xw->state |= WIN_FOCUSED;
+ xseturgency(xw, 0);
} else if (ev->xclient.data.l[1] == XEMBED_FOCUS_OUT) {
- xw.state &= ~WIN_FOCUSED;
+ xw->state &= ~WIN_FOCUSED;
}
- } else if (ev->xclient.data.l[0] == xw.wmdeletewin) {
+ } else if (ev->xclient.data.l[0] == xw->wmdeletewin) {
/* Send SIGHUP to shell */
kill(pid, SIGHUP);
exit(EXIT_SUCCESS);
}
}
-static void (*handler[LASTEvent]) (XEvent *) = {
-[KeyPress] = kpress,
- [ClientMessage] = cmessage,
- [ConfigureNotify] = resize,
- [VisibilityNotify] = visibility,
- [UnmapNotify] = unmap,
- [Expose] = expose,
- [FocusIn] = focus,
- [FocusOut] = focus,
- [MotionNotify] = bmotion,
- [ButtonPress] = bpress,
- [ButtonRelease] = brelease,
- [SelectionClear] = selclear,
- [SelectionNotify] = selnotify,
- [SelectionRequest] = selrequest,};
-
-static void run(void)
+static void run(struct st_window *xw)
{
XEvent ev;
fd_set rfd;
- int xfd = XConnectionNumber(xw.dpy), xev;
+ int xfd = XConnectionNumber(xw->dpy), xev;
struct timeval drawtimeout, *tv = NULL, now, last;
+ void (*handler[LASTEvent]) (struct st_window *, XEvent *) = {
+ [KeyPress] = kpress,
+ [ClientMessage] = cmessage,
+ [ConfigureNotify] = resize,
+ [VisibilityNotify] = visibility,
+ [UnmapNotify] = unmap,
+ [Expose] = expose,
+ [FocusIn] = focus,
+ [FocusOut] = focus,
+ [MotionNotify] = bmotion,
+ [ButtonPress] = bpress,
+ [ButtonRelease] = brelease,
+ [SelectionClear] = selclear,
+ [SelectionNotify] = selnotify,
+ [SelectionRequest] = selrequest,};
+
gettimeofday(&last, NULL);
for (xev = actionfps;;) {
FD_ZERO(&rfd);
- FD_SET(cmdfd, &rfd);
+ FD_SET(xw->term.cmdfd, &rfd);
FD_SET(xfd, &rfd);
- if (select(max(xfd, cmdfd) + 1, &rfd, NULL, NULL, tv) < 0) {
+ if (select(max(xfd, xw->term.cmdfd) + 1, &rfd, NULL, NULL, tv) < 0) {
if (errno == EINTR)
continue;
die("select failed: %s\n", SERRNO);
@@ -3127,29 +3169,29 @@ static void run(void)
drawtimeout.tv_usec = (1000 / xfps) * 1000;
tv = &drawtimeout;
- if (FD_ISSET(cmdfd, &rfd))
- ttyread();
+ if (FD_ISSET(xw->term.cmdfd, &rfd))
+ ttyread(xw);
if (FD_ISSET(xfd, &rfd))
xev = actionfps;
if (TIMEDIFF(now, last) >
(xev ? (1000 / xfps) : (1000 / actionfps))) {
- while (XPending(xw.dpy)) {
- XNextEvent(xw.dpy, &ev);
+ while (XPending(xw->dpy)) {
+ XNextEvent(xw->dpy, &ev);
if (XFilterEvent(&ev, None))
continue;
if (handler[ev.type])
- (handler[ev.type]) (&ev);
+ (handler[ev.type])(xw, &ev);
}
- draw();
- XFlush(xw.dpy);
+ draw(xw);
+ XFlush(xw->dpy);
last = now;
if (xev && !FD_ISSET(xfd, &rfd))
xev--;
- if (!FD_ISSET(cmdfd, &rfd) && !FD_ISSET(xfd, &rfd))
+ if (!FD_ISSET(xw->term.cmdfd, &rfd) && !FD_ISSET(xfd, &rfd))
tv = NULL;
}
}
@@ -3159,15 +3201,18 @@ int main(int argc, char *argv[])
{
int i, bitm, xr, yr;
unsigned wr, hr;
+ struct st_window xw;
+
+ memset(&xw, 0, sizeof(xw));
- xw.fw = xw.fh = xw.fx = xw.fy = 0;
- xw.isfixed = False;
+ xw.default_title = "st";
+ xw.class = termname;
for (i = 1; i < argc; i++) {
switch (argv[i][0] != '-' || argv[i][2] ? -1 : argv[i][1]) {
case 'c':
if (++i < argc)
- opt_class = argv[i];
+ xw.class = argv[i];
break;
case 'e':
/* eat all remaining arguments */
@@ -3205,14 +3250,14 @@ int main(int argc, char *argv[])
break;
case 't':
if (++i < argc)
- opt_title = argv[i];
+ xw.default_title = argv[i];
break;
case 'v':
default:
die(USAGE);
case 'w':
if (++i < argc)
- opt_embed = argv[i];
+ xw.embed = argv[i];
break;
}
}
@@ -3220,11 +3265,11 @@ int main(int argc, char *argv[])
run:
setlocale(LC_CTYPE, "");
XSetLocaleModifiers("");
- tnew(80, 24);
- xinit();
- ttynew();
- selinit();
- run();
+ tnew(&xw.term, 80, 24);
+ xinit(&xw);
+ ttynew(&xw);
+ selinit(&xw);
+ run(&xw);
return 0;
}