/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
void screen_write_initctx(struct screen_write_ctx *, struct tty_ctx *, int);
void screen_write_overwrite(struct screen_write_ctx *, u_int);
int screen_write_combine(
struct screen_write_ctx *, const struct utf8_data *);
/* Initialise writing with a window. */
void
screen_write_start(
struct screen_write_ctx *ctx, struct window_pane *wp, struct screen *s)
{
ctx->wp = wp;
if (wp != NULL && s == NULL)
ctx->s = wp->screen;
else
ctx->s = s;
}
/* Finish writing. */
void
screen_write_stop(unused struct screen_write_ctx *ctx)
{
}
/* Reset screen state. */
void
screen_write_reset(struct screen_write_ctx *ctx)
{
struct screen *s = ctx->s;
screen_reset_tabs(s);
screen_write_scrollregion(ctx, 0, screen_size_y(s) - 1);
s->mode &= ~(MODE_INSERT|MODE_KCURSOR|MODE_KKEYPAD|MODE_FOCUSON);
s->mode &= ~(ALL_MOUSE_MODES|MODE_MOUSE_UTF8|MODE_MOUSE_SGR);
screen_write_clearscreen(ctx);
screen_write_cursormove(ctx, 0, 0);
}
/* Write character. */
void
screen_write_putc(struct screen_write_ctx *ctx, struct grid_cell *gc,
u_char ch)
{
grid_cell_one(gc, ch);
screen_write_cell(ctx, gc);
}
/* Calculate string length, with embedded formatting. */
size_t printflike2
screen_write_cstrlen(int utf8flag, const char *fmt, ...)
{
va_list ap;
char *msg, *msg2, *ptr, *ptr2;
size_t size;
va_start(ap, fmt);
xvasprintf(&msg, fmt, ap);
va_end(ap);
msg2 = xmalloc(strlen(msg) + 1);
ptr = msg;
ptr2 = msg2;
while (*ptr != '\0') {
if (ptr[0] == '#' && ptr[1] == '[') {
while (*ptr != ']' && *ptr != '\0')
ptr++;
if (*ptr == ']')
ptr++;
continue;
}
*ptr2++ = *ptr++;
}
*ptr2 = '\0';
size = screen_write_strlen(utf8flag, "%s", msg2);
free(msg);
free(msg2);
return (size);
}
/* Calculate string length. */
size_t printflike2
screen_write_strlen(int utf8flag, const char *fmt, ...)
{
va_list ap;
char *msg;
struct utf8_data utf8data;
u_char *ptr;
size_t left, size = 0;
va_start(ap, fmt);
xvasprintf(&msg, fmt, ap);
va_end(ap);
ptr = msg;
while (*ptr != '\0') {
if (utf8flag && *ptr > 0x7f && utf8_open(&utf8data, *ptr)) {
ptr++;
left = strlen(ptr);
if (left < utf8data.size - 1)
break;
while (utf8_append(&utf8data, *ptr))
ptr++;
ptr++;
size += utf8data.width;
} else {
size++;
ptr++;
}
}
free(msg);
return (size);
}
/* Write simple string (no UTF-8 or maximum length). */
void printflike3
screen_write_puts(
struct screen_write_ctx *ctx, struct grid_cell *gc, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
screen_write_vnputs(ctx, -1, gc, 0, fmt, ap);
va_end(ap);
}
/* Write string with length limit (-1 for unlimited). */
void printflike5
screen_write_nputs(struct screen_write_ctx *ctx,
ssize_t maxlen, struct grid_cell *gc, int utf8flag, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
screen_write_vnputs(ctx, maxlen, gc, utf8flag, fmt, ap);
va_end(ap);
}
void
screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen,
struct grid_cell *gc, int utf8flag, const char *fmt, va_list ap)
{
char *msg;
struct utf8_data utf8data;
u_char *ptr;
size_t left, size = 0;
xvasprintf(&msg, fmt, ap);
ptr = msg;
while (*ptr != '\0') {
if (utf8flag && *ptr > 0x7f && utf8_open(&utf8data, *ptr)) {
ptr++;
left = strlen(ptr);
if (left < utf8data.size - 1)
break;
while (utf8_append(&utf8data, *ptr))
ptr++;
ptr++;
if (maxlen > 0 &&
size + utf8data.width > (size_t) maxlen) {
while (size < (size_t) maxlen) {
screen_write_putc(ctx, gc, ' ');
size++;
}
break;
}
size += utf8data.width;
grid_cell_set(gc, &utf8data);
screen_write_cell(ctx, gc);
} else {
if (maxlen > 0 && size + 1 > (size_t) maxlen)
break;
if (*ptr == '\001')
gc->attr ^= GRID_ATTR_CHARSET;
else {
size++;
screen_write_putc(ctx, gc, *ptr);
}
ptr++;
}
}
free(msg);
}
/* Write string, similar to nputs, but with embedded formatting (#[]). */
void printflike5
screen_write_cnputs(struct screen_write_ctx *ctx,
ssize_t maxlen, struct grid_cell *gc, int utf8flag, const char *fmt, ...)
{
struct grid_cell lgc;
struct utf8_data utf8data;
va_list ap;
char *msg;
u_char *ptr, *last;
size_t left, size = 0;
va_start(ap, fmt);
xvasprintf(&msg, fmt, ap);
va_end(ap);
memcpy(&lgc, gc, sizeof lgc);
ptr = msg;
while (*ptr != '\0') {
if (ptr[0] == '#' && ptr[1] == '[') {
ptr += 2;
last = ptr + strcspn(ptr, "]");
if (*last == '\0') {
/* No ]. Not much point in doing anything. */
break;
}
*last = '\0';
style_parse
|