/* macros */
#define NUMMAXLEN(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1)
-#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177')
#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
/* config.h for applying patches and the configuration. */
#include "config.h"
-static void execsh(void);
-static void stty(void);
+static void execsh(char **);
+static void stty(char **);
static void sigchld(int);
static void csidump(void);
static void tsetscroll(int, int);
static void tswapscreen(void);
static void tsetmode(int, int, int *, int);
+static int twrite(const char *, int, int);
static void tfulldirt(void);
-static void techo(Rune);
static void tcontrolcode(uchar );
static void tdectest(char );
static void tdefutf8(char);
Selection sel;
int cmdfd;
pid_t pid;
-char **opt_cmd = NULL;
-char *opt_class = NULL;
-char *opt_embed = NULL;
-char *opt_font = NULL;
-char *opt_io = NULL;
-char *opt_line = NULL;
-char *opt_name = NULL;
-char *opt_title = NULL;
int oldbutton = 3; /* button event on startup: 3 = release */
static CSIEscape csiescseq;
}
size_t
-utf8decode(char *c, Rune *u, size_t clen)
+utf8decode(const char *c, Rune *u, size_t clen)
{
size_t i, j, len, type;
Rune udecoded;
}
void
-execsh(void)
+execsh(char **args)
{
- char **args, *sh, *prog;
+ char *sh, *prog;
const struct passwd *pw;
errno = 0;
if ((sh = getenv("SHELL")) == NULL)
sh = (pw->pw_shell[0]) ? pw->pw_shell : shell;
- if (opt_cmd)
- prog = opt_cmd[0];
+ if (args)
+ prog = args[0];
else if (utmp)
prog = utmp;
else
prog = sh;
- args = (opt_cmd) ? opt_cmd : (char *[]) {prog, NULL};
+ DEFAULT(args, ((char *[]) {prog, NULL}));
unsetenv("COLUMNS");
unsetenv("LINES");
void
-stty(void)
+stty(char **args)
{
char cmd[_POSIX_ARG_MAX], **p, *q, *s;
size_t n, siz;
memcpy(cmd, stty_args, n);
q = cmd + n;
siz = sizeof(cmd) - n;
- for (p = opt_cmd; p && (s = *p); ++p) {
+ for (p = args; p && (s = *p); ++p) {
if ((n = strlen(s)) > siz-1)
die("stty parameter length too long\n");
*q++ = ' ';
}
void
-ttynew(void)
+ttynew(char *line, char *out, char **args)
{
int m, s;
struct winsize w = {term.row, term.col, 0, 0};
- if (opt_io) {
+ if (out) {
term.mode |= MODE_PRINT;
- iofd = (!strcmp(opt_io, "-")) ?
- 1 : open(opt_io, O_WRONLY | O_CREAT, 0666);
+ iofd = (!strcmp(out, "-")) ?
+ 1 : open(out, O_WRONLY | O_CREAT, 0666);
if (iofd < 0) {
fprintf(stderr, "Error opening %s:%s\n",
- opt_io, strerror(errno));
+ out, strerror(errno));
}
}
- if (opt_line) {
- if ((cmdfd = open(opt_line, O_RDWR)) < 0)
+ if (line) {
+ if ((cmdfd = open(line, O_RDWR)) < 0)
die("open line failed: %s\n", strerror(errno));
dup2(cmdfd, 0);
- stty();
+ stty(args);
return;
}
die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
close(s);
close(m);
- execsh();
+ execsh(args);
break;
default:
close(s);
{
static char buf[BUFSIZ];
static int buflen = 0;
- char *ptr;
- int charsize; /* size of utf8 char in bytes */
- Rune unicodep;
+ int written;
int ret;
/* append read bytes to unprocessed bytes */
if ((ret = read(cmdfd, buf+buflen, LEN(buf)-buflen)) < 0)
die("Couldn't read from shell: %s\n", strerror(errno));
-
buflen += ret;
- ptr = buf;
- for (;;) {
- if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) {
- /* process a complete utf8 char */
- charsize = utf8decode(ptr, &unicodep, buflen);
- if (charsize == 0)
- break;
- tputc(unicodep);
- ptr += charsize;
- buflen -= charsize;
-
- } else {
- if (buflen <= 0)
- break;
- tputc(*ptr++ & 0xFF);
- buflen--;
- }
- }
+ written = twrite(buf, buflen, 0);
+ buflen -= written;
/* keep any uncomplete utf8 char for the next call */
if (buflen > 0)
- memmove(buf, ptr, buflen);
+ memmove(buf, buf + written, buflen);
return ret;
}
void
ttysend(char *s, size_t n)
{
- int len;
- char *t, *lim;
- Rune u;
-
ttywrite(s, n);
- if (!IS_SET(MODE_ECHO))
- return;
-
- lim = &s[n];
- for (t = s; t < lim; t += len) {
- if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) {
- len = utf8decode(t, &u, n);
- } else {
- u = *t & 0xFF;
- len = 1;
- }
- if (len <= 0)
- break;
- techo(u);
- n -= len;
- }
+ if (IS_SET(MODE_ECHO))
+ twrite(s, n, 1);
}
void
tprinter(char *s, size_t len)
{
if (iofd != -1 && xwrite(iofd, s, len) < 0) {
- fprintf(stderr, "Error writing in %s:%s\n",
- opt_io, strerror(errno));
+ perror("Error writing to output file");
close(iofd);
iofd = -1;
}
term.c.x = LIMIT(x, 0, term.col-1);
}
-void
-techo(Rune u)
-{
- if (ISCONTROL(u)) { /* control code */
- if (u & 0x80) {
- u &= 0x7f;
- tputc('^');
- tputc('[');
- } else if (u != '\n' && u != '\r' && u != '\t') {
- u ^= 0x40;
- tputc('^');
- }
- }
- tputc(u);
-}
-
void
tdefutf8(char ascii)
{
}
}
+int
+twrite(const char *buf, int buflen, int show_ctrl)
+{
+ int charsize;
+ Rune u;
+ int n;
+
+ for (n = 0; n < buflen; n += charsize) {
+ if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) {
+ /* process a complete utf8 char */
+ charsize = utf8decode(buf + n, &u, buflen - n);
+ if (charsize == 0)
+ break;
+ } else {
+ u = buf[n] & 0xFF;
+ charsize = 1;
+ }
+ if (show_ctrl && ISCONTROL(u)) {
+ if (u & 0x80) {
+ u &= 0x7f;
+ tputc('^');
+ tputc('[');
+ } else if (u != '\n' && u != '\r' && u != '\t') {
+ u ^= 0x40;
+ tputc('^');
+ }
+ }
+ tputc(u);
+ }
+ return n;
+}
+
void
tresize(int col, int row)
{
void
resettitle(void)
{
- xsettitle(opt_title ? opt_title : "st");
+ xsettitle(NULL);
}
void