Пример #1
0
/* Update status cache. */
void
status_update_saved(struct session *s)
{
	if (!options_get_number(s->options, "status"))
		s->statusat = -1;
	else if (options_get_number(s->options, "status-position") == 0)
		s->statusat = 0;
	else
		s->statusat = 1;
}
Пример #2
0
/* Translate mouse and output. */
void
input_mouse(struct window_pane *wp, struct session *s, struct mouse_event *m)
{
	char			 buf[40];
	size_t			 len;
	struct paste_buffer	*pb;

	if (wp->screen->mode & ALL_MOUSE_MODES) {
		/*
		 * Use the SGR (1006) extension only if the application
		 * requested it and the underlying terminal also sent the event
		 * in this format (this is because an old style mouse release
		 * event cannot be converted into the new SGR format, since the
		 * released button is unknown). Otherwise pretend that tmux
		 * doesn't speak this extension, and fall back to the UTF-8
		 * (1005) extension if the application requested, or to the
		 * legacy format.
		 */
		if (m->sgr && (wp->screen->mode & MODE_MOUSE_SGR)) {
			len = xsnprintf(buf, sizeof buf, "\033[<%d;%d;%d%c",
			    m->sgr_xb, m->x + 1, m->y + 1,
			    m->sgr_rel ? 'm' : 'M');
		} else if (wp->screen->mode & MODE_MOUSE_UTF8) {
			len = xsnprintf(buf, sizeof buf, "\033[M");
			len += utf8_split2(m->xb + 32, &buf[len]);
			len += utf8_split2(m->x + 33, &buf[len]);
			len += utf8_split2(m->y + 33, &buf[len]);
		} else {
			if (m->xb > 223 || m->x >= 222 || m->y > 222)
				return;
			len = xsnprintf(buf, sizeof buf, "\033[M");
			buf[len++] = m->xb + 32;
			buf[len++] = m->x + 33;
			buf[len++] = m->y + 33;
		}
		bufferevent_write(wp->event, buf, len);
		return;
	}

	if (m->button == 1 && (m->event & MOUSE_EVENT_CLICK) &&
	    options_get_number(&wp->window->options, "mode-mouse") == 1) {
		pb = paste_get_top(&global_buffers);
		if (pb != NULL) {
			paste_send_pane(pb, wp, "\r",
			    wp->screen->mode & MODE_BRACKETPASTE);
		}
	} else if ((m->xb & 3) != 1 &&
	    options_get_number(&wp->window->options, "mode-mouse") == 1) {
		if (window_pane_set_mode(wp, &window_copy_mode) == 0) {
			window_copy_init_from_pane(wp);
			if (wp->mode->mouse != NULL)
				wp->mode->mouse(wp, s, m);
		}
	}
}
Пример #3
0
int
window_copy_update_selection(struct window_pane *wp)
{
	struct window_copy_mode_data	*data = wp->modedata;
	struct screen			*s = &data->screen;
	struct options			*oo = &wp->window->options;
	struct grid_cell		 gc;
	u_int				 sx, sy, ty, cy;

	if (!s->sel.flag)
		return (0);

	/* Set colours. */
	memcpy(&gc, &grid_default_cell, sizeof gc);
	colour_set_fg(&gc, options_get_number(oo, "mode-fg"));
	colour_set_bg(&gc, options_get_number(oo, "mode-bg"));
	gc.attr |= options_get_number(oo, "mode-attr");

	/* Find top of screen. */
	ty = screen_hsize(&wp->base) - data->oy;

	/* Adjust the selection. */
	sx = data->selx;
	sy = data->sely;
	if (sy < ty) {					/* above screen */
		if (!data->rectflag)
			sx = 0;
		sy = 0;
	} else if (sy > ty + screen_size_y(s) - 1) {	/* below screen */
		if (!data->rectflag)
			sx = screen_size_x(s) - 1;
		sy = screen_size_y(s) - 1;
	} else
		sy -= ty;
	sy = screen_hsize(s) + sy;

	screen_set_selection(s,
	    sx, sy, data->cx, screen_hsize(s) + data->cy, data->rectflag, &gc);

	if (data->rectflag) {
		/*
		 * Can't rely on the caller to redraw the right lines for
		 * rectangle selection - find the highest line and the number
		 * of lines, and redraw just past that in both directions
		 */
		cy = data->cy;
		if (sy < cy)
			window_copy_redraw_lines(wp, sy, cy - sy + 1);
		else
			window_copy_redraw_lines(wp, cy, sy - cy + 1);
	}

	return (1);
}
Пример #4
0
/* Get screen line of status line. -1 means off. */
int
status_at_line(struct client *c)
{
	struct session	*s = c->session;

	if (!options_get_number(&s->options, "status"))
		return (-1);

	if (options_get_number(&s->options, "status-position") == 0)
		return (0);
	return (c->tty.sy - 1);
}
Пример #5
0
struct screen *
window_copy_init(struct window_pane *wp)
{
	struct window_copy_mode_data	*data;
	struct screen			*s;
	struct screen_write_ctx	 	 ctx;
	u_int				 i;
	int				 keys;

	wp->modedata = data = xmalloc(sizeof *data);
	data->oy = 0;
	data->cx = wp->base.cx;
	data->cy = wp->base.cy;

	data->lastcx = 0;
	data->lastsx = 0;

	data->rectflag = 0;

	data->inputtype = WINDOW_COPY_OFF;
	data->inputprompt = NULL;
	data->inputstr = xstrdup("");
	data->numprefix = 0;

	data->searchtype = WINDOW_COPY_OFF;
	data->searchstr = NULL;

	wp->flags |= PANE_FREEZE;
	bufferevent_disable(wp->event, EV_READ|EV_WRITE);

	s = &data->screen;
	screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
	if (options_get_number(&wp->window->options, "mode-mouse"))
		s->mode |= MODE_MOUSE;

	keys = options_get_number(&wp->window->options, "mode-keys");
	if (keys == MODEKEY_EMACS)
		mode_key_init(&data->mdata, &mode_key_tree_emacs_copy);
	else
		mode_key_init(&data->mdata, &mode_key_tree_vi_copy);

	s->cx = data->cx;
	s->cy = data->cy;

	screen_write_start(&ctx, NULL, s);
	for (i = 0; i < screen_size_y(s); i++)
		window_copy_write_line(wp, &ctx, i);
	screen_write_cursormove(&ctx, data->cx, data->cy);
	screen_write_stop(&ctx);

	return (s);
}
Пример #6
0
enum cmd_retval
cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct window_pane	*wp;
	struct session		*s;
	struct input_ctx	*ictx;
	const u_char		*str;
	int			 i, key;

	if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
		return (CMD_RETURN_ERROR);

	if (self->entry == &cmd_send_prefix_entry) {
		if (args_has(args, '2'))
			key = options_get_number(&s->options, "prefix2");
		else
			key = options_get_number(&s->options, "prefix");
		window_pane_key(wp, s, key);
		return (CMD_RETURN_NORMAL);
	}

	if (args_has(args, 'R')) {
		ictx = &wp->ictx;

		memcpy(&ictx->cell, &grid_default_cell, sizeof ictx->cell);
		memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
		ictx->old_cx = 0;
		ictx->old_cy = 0;

		if (wp->mode == NULL)
			screen_write_start(&ictx->ctx, wp, &wp->base);
		else
			screen_write_start(&ictx->ctx, NULL, &wp->base);
		screen_write_reset(&ictx->ctx);
		screen_write_stop(&ictx->ctx);
	}

	for (i = 0; i < args->argc; i++) {
		str = args->argv[i];

		if (!args_has(args, 'l') &&
		    (key = key_string_lookup_string(str)) != KEYC_NONE) {
			    window_pane_key(wp, s, key);
		} else {
			for (; *str != '\0'; str++)
			    window_pane_key(wp, s, *str);
		}
	}

	return (CMD_RETURN_NORMAL);
}
Пример #7
0
/* Is there any status (main or aux) at line zero? (1 True, 0 False) */
int
any_status_at_zero(struct client *c)
{
    struct session *s = c->session;

    if (options_get_number(s->options, "status") && 
         (options_get_number(s->options, "status-position")==0))
        return 1;
    if (options_get_number(s->options, "aux-status") && 
         (options_get_number(s->options, "aux-status-position")==0))
        return 1;
    return 0;
}
Пример #8
0
void
window_clock_draw_screen(struct window_pane *wp)
{
	struct window_clock_mode_data	*data = wp->modedata;
	struct screen_write_ctx	 	 ctx;
	int				 colour, style;

	colour = options_get_number(&wp->window->options, "clock-mode-colour");
	style = options_get_number(&wp->window->options, "clock-mode-style");

	screen_write_start(&ctx, NULL, &data->screen);
	clock_draw(&ctx, colour, style);
	screen_write_stop(&ctx);
}
Пример #9
0
struct screen *
window_copy_init(struct window_pane *wp)
{
	struct window_copy_mode_data	*data;
	struct screen			*s;
	int				 keys;

	wp->modedata = data = xmalloc(sizeof *data);
	data->oy = 0;
	data->cx = 0;
	data->cy = 0;

	data->lastcx = 0;
	data->lastsx = 0;

	data->backing_written = 0;

	data->rectflag = 0;

	data->inputtype = WINDOW_COPY_OFF;
	data->inputprompt = NULL;
	data->inputstr = xstrdup("");
	data->numprefix = 0;

	data->searchtype = WINDOW_COPY_OFF;
	data->searchstr = NULL;

	wp->flags |= PANE_FREEZE;
	if (wp->fd != -1)
		bufferevent_disable(wp->event, EV_READ|EV_WRITE);

	data->jumptype = WINDOW_COPY_OFF;
	data->jumpchar = '\0';

	s = &data->screen;
	screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
	if (options_get_number(&wp->window->options, "mode-mouse"))
		s->mode |= MODE_MOUSE_STANDARD;

	keys = options_get_number(&wp->window->options, "mode-keys");
	if (keys == MODEKEY_EMACS)
		mode_key_init(&data->mdata, &mode_key_tree_emacs_copy);
	else
		mode_key_init(&data->mdata, &mode_key_tree_vi_copy);

	data->backing = NULL;

	return (s);
}
Пример #10
0
enum cmd_retval
cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct mouse_event	*m = &cmdq->item->mouse;
	struct window_pane	*wp;
	struct session		*s;
	const char		*str;
	int			 i, key;

	if (args_has(args, 'M')) {
		wp = cmd_mouse_pane(m, &s, NULL);
		if (wp == NULL) {
			cmdq_error(cmdq, "no mouse target");
			return (CMD_RETURN_ERROR);
		}
		window_pane_key(wp, NULL, s, m->key, m);
		return (CMD_RETURN_NORMAL);
	}

	if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
		return (CMD_RETURN_ERROR);

	if (self->entry == &cmd_send_prefix_entry) {
		if (args_has(args, '2'))
			key = options_get_number(&s->options, "prefix2");
		else
			key = options_get_number(&s->options, "prefix");
		window_pane_key(wp, NULL, s, key, NULL);
		return (CMD_RETURN_NORMAL);
	}

	if (args_has(args, 'R'))
		input_reset(wp);

	for (i = 0; i < args->argc; i++) {
		str = args->argv[i];

		if (!args_has(args, 'l') &&
		    (key = key_string_lookup_string(str)) != KEYC_NONE) {
			window_pane_key(wp, NULL, s, key, NULL);
		} else {
			for (; *str != '\0'; str++)
				window_pane_key(wp, NULL, s, *str, NULL);
		}
	}

	return (CMD_RETURN_NORMAL);
}
Пример #11
0
void
window_copy_write_line(
    struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
{
	struct window_copy_mode_data	*data = wp->modedata;
	struct screen			*s = &data->screen;
	struct options			*oo = &wp->window->options;
	struct grid_cell		 gc;
	char				 hdr[32];
	size_t	 			 last, xoff = 0, size = 0;

	memcpy(&gc, &grid_default_cell, sizeof gc);
	colour_set_fg(&gc, options_get_number(oo, "mode-fg"));
	colour_set_bg(&gc, options_get_number(oo, "mode-bg"));
	gc.attr |= options_get_number(oo, "mode-attr");

	last = screen_size_y(s) - 1;
	if (py == 0) {
		size = xsnprintf(hdr, sizeof hdr,
		    "[%u/%u]", data->oy, screen_hsize(data->backing));
		if (size > screen_size_x(s))
			size = screen_size_x(s);
		screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
		screen_write_puts(ctx, &gc, "%s", hdr);
	} else if (py == last && data->inputtype != WINDOW_COPY_OFF) {
		if (data->inputtype == WINDOW_COPY_NUMERICPREFIX) {
			xoff = size = xsnprintf(hdr, sizeof hdr,
			    "Repeat: %u", data->numprefix);
		} else {
			xoff = size = xsnprintf(hdr, sizeof hdr,
			    "%s: %s", data->inputprompt, data->inputstr);
		}
		screen_write_cursormove(ctx, 0, last);
		screen_write_puts(ctx, &gc, "%s", hdr);
	} else
		size = 0;

	screen_write_cursormove(ctx, xoff, py);
	screen_write_copy(ctx, data->backing, xoff,
	    (screen_hsize(data->backing) - data->oy) + py,
	    screen_size_x(s) - size, 1);

	if (py == data->cy && data->cx == screen_size_x(s)) {
		memcpy(&gc, &grid_default_cell, sizeof gc);
		screen_write_cursormove(ctx, screen_size_x(s) - 1, py);
		screen_write_putc(ctx, &gc, '$');
	}
}
Пример #12
0
void
cmd_set_option_flag(struct cmd_ctx *ctx, struct options *oo,
    const struct set_option_entry *entry, char *value)
{
	struct options_entry	*o;
	int			 flag;

	if (value == NULL || *value == '\0')
		flag = !options_get_number(oo, entry->name);
	else {
		if ((value[0] == '1' && value[1] == '\0') ||
		    strcasecmp(value, "on") == 0 ||
		    strcasecmp(value, "yes") == 0)
			flag = 1;
		else if ((value[0] == '0' && value[1] == '\0') ||
		    strcasecmp(value, "off") == 0 ||
		    strcasecmp(value, "no") == 0)
			flag = 0;
		else {
			ctx->error(ctx, "bad value: %s", value);
			return;
		}
	}

	o = options_set_number(oo, entry->name, flag);
	ctx->info(ctx,
	    "set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
Пример #13
0
/* Translate mouse and output. */
void
input_mouse(struct window_pane *wp, struct mouse_event *m)
{
	char	buf[10];
	size_t	len;

	if (wp->screen->mode & ALL_MOUSE_MODES) {
		if (wp->screen->mode & MODE_MOUSE_UTF8) {
			len = xsnprintf(buf, sizeof buf, "\033[M");
			len += utf8_split2(m->b + 32, &buf[len]);
			len += utf8_split2(m->x + 33, &buf[len]);
			len += utf8_split2(m->y + 33, &buf[len]);
		} else {
			if (m->b > 223 || m->x >= 222 || m->y > 222)
				return;
			len = xsnprintf(buf, sizeof buf, "\033[M");
			buf[len++] = m->b + 32;
			buf[len++] = m->x + 33;
			buf[len++] = m->y + 33;
		}
		bufferevent_write(wp->event, buf, len);
	} else if ((m->b & MOUSE_BUTTON) != MOUSE_2) {
		if (options_get_number(&wp->window->options, "mode-mouse") &&
		    window_pane_set_mode(wp, &window_copy_mode) == 0) {
			window_copy_init_from_pane(wp);
			if (wp->mode->mouse != NULL)
				wp->mode->mouse(wp, NULL, m);
		}
	}
}
Пример #14
0
/* Set a flag option. */
struct options_entry *
cmd_set_option_flag(struct cmd *self, struct cmd_ctx *ctx,
    const struct options_table_entry *oe, struct options *oo)
{
	struct cmd_target_data	*data = self->data;
	int			 flag;

	if (data->arg2 == NULL || *data->arg2 == '\0')
		flag = !options_get_number(oo, oe->name);
	else {
		if ((data->arg2[0] == '1' && data->arg2[1] == '\0') ||
		    strcasecmp(data->arg2, "on") == 0 ||
		    strcasecmp(data->arg2, "yes") == 0)
			flag = 1;
		else if ((data->arg2[0] == '0' && data->arg2[1] == '\0') ||
		    strcasecmp(data->arg2, "off") == 0 ||
		    strcasecmp(data->arg2, "no") == 0)
			flag = 0;
		else {
			ctx->error(ctx, "bad value: %s", data->arg2);
			return (NULL);
		}
	}

	return (options_set_number(oo, oe->name, flag));
}
Пример #15
0
void
cmd_load_buffer_callback(struct client *c, void *data)
{
	int	*buffer = data;
	char	*pdata;
	size_t	 psize;
	u_int	 limit;

	/*
	 * Event callback has already checked client is not dead and reduced
	 * its reference count. But tell it to exit.
	 */
	c->flags |= CLIENT_EXIT;

	psize = EVBUFFER_LENGTH(c->stdin_event->input);
	if (psize == 0 || (pdata = malloc(psize + 1)) == NULL) {
		xfree(data);
		return;
	}
	bufferevent_read(c->stdin_event, pdata, psize);
	pdata[psize] = '\0';

	limit = options_get_number(&global_options, "buffer-limit");
	if (*buffer == -1)
		paste_add(&global_buffers, pdata, psize, limit);
	else if (paste_replace(&global_buffers, *buffer, pdata, psize) != 0) {
		/* No context so can't use server_client_msg_error. */
		evbuffer_add_printf(
		    c->stderr_event->output, "no buffer %d\n", *buffer);
		bufferevent_enable(c->stderr_event, EV_WRITE);
	}

	xfree(data);
}
Пример #16
0
/* Set a flag option. */
struct options_entry *
cmd_set_option_flag(unused struct cmd *self, struct cmd_q *cmdq,
    const struct options_table_entry *oe, struct options *oo, const char *value)
{
	int	flag;

	if (value == NULL || *value == '\0')
		flag = !options_get_number(oo, oe->name);
	else {
		if ((value[0] == '1' && value[1] == '\0') ||
		    strcasecmp(value, "on") == 0 ||
		    strcasecmp(value, "yes") == 0)
			flag = 1;
		else if ((value[0] == '0' && value[1] == '\0') ||
		    strcasecmp(value, "off") == 0 ||
		    strcasecmp(value, "no") == 0)
			flag = 0;
		else {
			cmdq_error(cmdq, "bad value: %s", value);
			return (NULL);
		}
	}

	return (options_set_number(oo, oe->name, flag));
}
Пример #17
0
int
cmd_set_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct args	*args = self->args;
	u_int		 limit;
	char		*pdata, *cause;
	size_t		 psize;
	int		 buffer;

	limit = options_get_number(&global_options, "buffer-limit");

	pdata = xstrdup(args->argv[0]);
	psize = strlen(pdata);

	if (!args_has(args, 'b')) {
		paste_add(&global_buffers, pdata, psize, limit);
		return (0);
	}

	buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
	if (cause != NULL) {
		ctx->error(ctx, "buffer %s", cause);
		xfree(cause);
		xfree(pdata);
		return (-1);
	}

	if (paste_replace(&global_buffers, buffer, pdata, psize) != 0) {
		ctx->error(ctx, "no buffer %d", buffer);
		xfree(pdata);
		return (-1);
	}

	return (0);
}
Пример #18
0
int
cmd_set_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
    struct cmd_buffer_data	*data = self->data;
    struct session		*s;
    u_int			 limit;
    char			*pdata;
    size_t			 psize;

    if ((s = cmd_find_session(ctx, data->target)) == NULL)
        return (-1);
    limit = options_get_number(&s->options, "buffer-limit");

    pdata = xstrdup(data->arg);
    psize = strlen(pdata);

    if (data->buffer == -1) {
        paste_add(&s->buffers, pdata, psize, limit);
        return (0);
    }
    if (paste_replace(&s->buffers, data->buffer, pdata, psize) != 0) {
        ctx->error(ctx, "no buffer %d", data->buffer);
        xfree(pdata);
        return (-1);
    }
    return (0);
}
Пример #19
0
int
cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
    struct args		*args = self->args;
    struct winlink		*wl;
    struct session		*s;
    struct window_pane	*wp;
    struct window		*w;
    char			*name;
    char			*cause;
    int			 base_idx;
    struct client		*c;

    if ((wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp)) == NULL)
        return (-1);

    if (window_count_panes(wl->window) == 1) {
        ctx->error(ctx, "can't break with only one pane");
        return (-1);
    }

    w = wl->window;
    TAILQ_REMOVE(&w->panes, wp, entry);
    if (wp == w->active) {
        w->active = w->last;
        w->last = NULL;
        if (w->active == NULL) {
            w->active = TAILQ_PREV(wp, window_panes, entry);
            if (w->active == NULL)
                w->active = TAILQ_NEXT(wp, entry);
        }
    } else if (wp == w->last)
        w->last = NULL;
    layout_close_pane(wp);

    w = wp->window = window_create1(s->sx, s->sy);
    TAILQ_INSERT_HEAD(&w->panes, wp, entry);
    w->active = wp;
    name = default_window_name(w);
    window_set_name(w, name);
    xfree(name);
    layout_init(w);

    base_idx = options_get_number(&s->options, "base-index");
    wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */
    if (!args_has(self->args, 'd'))
        session_select(s, wl->idx);

    server_redraw_session(s);
    server_status_session_group(s);

    /* Output the window ID for control clients. */
    c = cmd_find_client(ctx, NULL);
    if (c->flags & CLIENT_CONTROL) {
        ctx->print(ctx, "%d", w->id);
    }

    return (0);
}
Пример #20
0
/* Is there any status (main or aux) on last line? (1 True, 0 False) */
int
any_status_on_last(struct client *c)
{
    struct session *s = c->session;
    int status, aux_status;

    status = options_get_number(s->options, "status");
    aux_status = options_get_number(s->options, "aux-status");

    if (status && aux_status)
        return 1;
    if (status && options_get_number(s->options, "status-position")!=0)
        return 1;
    if (aux_status && options_get_number(s->options, "aux-status-position")!=0)
        return 1;
    return 0;
}
Пример #21
0
enum cmd_retval
cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
#ifdef TMATE_SLAVE
    return (CMD_RETURN_ERROR);
#else
    struct args		*args = self->args;
    struct winlink		*wl = cmdq->state.sflag.wl;
    struct session		*src_s = cmdq->state.sflag.s;
    struct session		*dst_s = cmdq->state.tflag.s;
    struct window_pane	*wp = cmdq->state.sflag.wp;
    struct window		*w = wl->window;
    char			*name;
    char			*cause;
    int			 idx = cmdq->state.tflag.idx;
    struct format_tree	*ft;
    const char		*template;
    char			*cp;

    if (idx != -1 && winlink_find_by_index(&dst_s->windows, idx) != NULL) {
        cmdq_error(cmdq, "index %d already in use", idx);
        return (CMD_RETURN_ERROR);
    }

    if (window_count_panes(w) == 1) {
        cmdq_error(cmdq, "can't break with only one pane");
        return (CMD_RETURN_ERROR);
    }
    server_unzoom_window(w);

    TAILQ_REMOVE(&w->panes, wp, entry);
    window_lost_pane(w, wp);
    layout_close_pane(wp);

    w = wp->window = window_create1(dst_s->sx, dst_s->sy);
    TAILQ_INSERT_HEAD(&w->panes, wp, entry);
    w->active = wp;
    name = default_window_name(w);
    window_set_name(w, name);
    free(name);
    layout_init(w, wp);
    wp->flags |= PANE_CHANGED;

    if (idx == -1)
        idx = -1 - options_get_number(dst_s->options, "base-index");
    wl = session_attach(dst_s, w, idx, &cause); /* can't fail */
    if (!args_has(self->args, 'd'))
        session_select(dst_s, wl->idx);

    server_redraw_session(src_s);
    if (src_s != dst_s)
        server_redraw_session(dst_s);
    server_status_session_group(src_s);
    if (src_s != dst_s)
        server_status_session_group(dst_s);

    if (args_has(args, 'P')) {
        if ((template = args_get(args, 'F')) == NULL)
Пример #22
0
enum cmd_retval
cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct winlink		*wl;
	struct session		*s;
	struct window_pane	*wp;
	struct window		*w;
	char			*name;
	char			*cause;
	int			 base_idx;
	struct client		*c;
	struct format_tree	*ft;
	const char		*template;
	char			*cp;

	if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
		return (CMD_RETURN_ERROR);

	if (window_count_panes(wl->window) == 1) {
		cmdq_error(cmdq, "can't break with only one pane");
		return (CMD_RETURN_ERROR);
	}

	w = wl->window;
	server_unzoom_window(w);

	TAILQ_REMOVE(&w->panes, wp, entry);
	if (wp == w->active) {
		w->active = w->last;
		w->last = NULL;
		if (w->active == NULL) {
			w->active = TAILQ_PREV(wp, window_panes, entry);
			if (w->active == NULL)
				w->active = TAILQ_NEXT(wp, entry);
		}
	} else if (wp == w->last)
		w->last = NULL;
	layout_close_pane(wp);

	w = wp->window = window_create1(s->sx, s->sy);
	TAILQ_INSERT_HEAD(&w->panes, wp, entry);
	w->active = wp;
	name = default_window_name(w);
	window_set_name(w, name);
	free(name);
	layout_init(w, wp);

	base_idx = options_get_number(&s->options, "base-index");
	wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */
	if (!args_has(self->args, 'd'))
		session_select(s, wl->idx);

	server_redraw_session(s);
	server_status_session_group(s);

	if (args_has(args, 'P')) {
		if ((template = args_get(args, 'F')) == NULL)
Пример #23
0
enum cmd_retval
cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct client		*c;
	struct window_pane	*wp;
	char			*buf, *cause;
	int			 buffer;
	u_int			 limit;
	size_t			 len;

	if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
		return (CMD_RETURN_ERROR);

	len = 0;
	if (args_has(args, 'P'))
		buf = cmd_capture_pane_pending(args, wp, &len);
	else
		buf = cmd_capture_pane_history(args, cmdq, wp, &len);
	if (buf == NULL)
		return (CMD_RETURN_ERROR);

	if (args_has(args, 'p')) {
		c = cmdq->client;
		if (c == NULL ||
		    (c->session != NULL && !(c->flags & CLIENT_CONTROL))) {
			cmdq_error(cmdq, "can't write to stdout");
			return (CMD_RETURN_ERROR);
		}
		evbuffer_add(c->stdout_data, buf, len);
		if (args_has(args, 'P') && len > 0)
		    evbuffer_add(c->stdout_data, "\n", 1);
		server_push_stdout(c);
	} else {
		limit = options_get_number(&global_options, "buffer-limit");
		if (!args_has(args, 'b')) {
			paste_add(buf, len, limit);
			return (CMD_RETURN_NORMAL);
		}

		buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "buffer %s", cause);
			free(buf);
			free(cause);
			return (CMD_RETURN_ERROR);
		}

		if (paste_replace(buffer, buf, len) != 0) {
			cmdq_error(cmdq, "no buffer %d", buffer);
			free(buf);
			return (CMD_RETURN_ERROR);
		}
	}

	return (CMD_RETURN_NORMAL);
}
Пример #24
0
int
cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct cmd_buffer_data	*data = self->data;
	struct session		*s;
	FILE			*f;
	char		      	*pdata, *new_pdata;
	size_t			 psize;
	u_int			 limit;
	int			 ch;

	if ((s = cmd_find_session(ctx, data->target)) == NULL)
		return (-1);

	if ((f = fopen(data->arg, "rb")) == NULL) {
		ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
		return (-1);
	}

	pdata = NULL;
	psize = 0;
	while ((ch = getc(f)) != EOF) {
		/* Do not let the server die due to memory exhaustion. */
		if ((new_pdata = realloc(pdata, psize + 2)) == NULL) {
			ctx->error(ctx, "realloc error: %s", strerror(errno));
			goto error;
		}
		pdata = new_pdata;
		pdata[psize++] = ch;
	}
	if (ferror(f)) {
		ctx->error(ctx, "%s: read error", data->arg);
		goto error;
	}
	if (pdata != NULL)
		pdata[psize] = '\0';

	fclose(f);

	limit = options_get_number(&s->options, "buffer-limit");
	if (data->buffer == -1) {
		paste_add(&s->buffers, pdata, psize, limit);
		return (0);
	}
	if (paste_replace(&s->buffers, data->buffer, pdata, psize) != 0) {
		ctx->error(ctx, "no buffer %d", data->buffer);
		goto error;
	}

	return (0);

error:
	if (pdata != NULL)
		xfree(pdata);
	fclose(f);
	return (-1);
}
Пример #25
0
void
window_copy_search_down(struct window_pane *wp, const char *searchstr)
{
	struct window_copy_mode_data	*data = wp->modedata;
	struct screen			*s = &wp->base, ss;
	struct screen_write_ctx		 ctx;
	struct grid			*gd = s->grid, *sgd;
	struct grid_cell	 	 gc;
	size_t				 searchlen;
	u_int				 i, first, fx, fy, px;
	int				 utf8flag, n, wrapped;

	if (*searchstr == '\0')
		return;
	utf8flag = options_get_number(&wp->window->options, "utf8");
	searchlen = screen_write_strlen(utf8flag, "%s", searchstr);

	screen_init(&ss, searchlen, 1, 0);
	screen_write_start(&ctx, NULL, &ss);
	memcpy(&gc, &grid_default_cell, sizeof gc);
	screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
	screen_write_stop(&ctx);

	fx = data->cx;
	fy = gd->hsize - data->oy + data->cy;

	if (fx == gd->sx - 1) {
		if (fy == gd->hsize + gd->sy)
			return;
		fx = 0;
		fy++;
	} else
		fx++;
	n = wrapped = 0;

retry:
	sgd = ss.grid;
	for (i = fy + 1; i < gd->hsize + gd->sy; i++) {
		first = 0;
		if (i == fy + 1)
			first = fx;
		n = window_copy_search_lr(gd, sgd, &px, i - 1, first, gd->sx);
		if (n) {
			window_copy_scroll_to(wp, px, i - 1);
			break;
		}
	}
	if (!n && !wrapped) {
		fx = 0;
		fy = 0;
		wrapped = 1;
		goto retry;
	}

	screen_free(&ss);
}
Пример #26
0
enum cmd_retval
cmd_move_window_exec(struct cmd *self, struct cmd_q *cmdq)
{
#ifdef TMATE
	cmdq_error(cmdq, "move window is not supported with tmate");
	return (CMD_RETURN_ERROR);
#else
	struct args	*args = self->args;
	struct session	*src = cmdq->state.sflag.s;
	struct session	*dst = cmdq->state.tflag.s;
	struct winlink	*wl = cmdq->state.sflag.wl;
	char		*cause;
	int		 idx = cmdq->state.tflag.idx, kflag, dflag, sflag;

	kflag = args_has(self->args, 'k');
	dflag = args_has(self->args, 'd');

	if (args_has(args, 'r')) {
		session_renumber_windows(dst);
		recalculate_sizes();

		return (CMD_RETURN_NORMAL);
	}

	kflag = args_has(self->args, 'k');
	dflag = args_has(self->args, 'd');
	sflag = args_has(self->args, 's');

	if (args_has(self->args, 'a')) {
		if ((idx = winlink_shuffle_up(dst, dst->curw)) == -1)
			return (CMD_RETURN_ERROR);
	}

	if (server_link_window(src, wl, dst, idx, kflag, !dflag,
	    &cause) != 0) {
		cmdq_error(cmdq, "can't link window: %s", cause);
		free(cause);
		return (CMD_RETURN_ERROR);
	}
	if (self->entry == &cmd_move_window_entry)
		server_unlink_window(src, wl);

	/*
	 * Renumber the winlinks in the src session only, the destination
	 * session already has the correct winlink id to us, either
	 * automatically or specified by -s.
	 */
	if (!sflag && options_get_number(src->options, "renumber-windows"))
		session_renumber_windows(src);

	recalculate_sizes();

	return (CMD_RETURN_NORMAL);
#endif
}
Пример #27
0
enum cmd_retval
cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct paste_buffer	*pb;
	u_int			 limit;
	char			*pdata, *cause;
	size_t			 psize, newsize;
	int			 buffer;

	limit = options_get_number(&global_options, "buffer-limit");

	psize = 0;
	pdata = NULL;

	pb = NULL;
	buffer = -1;

	if (args_has(args, 'b')) {
		buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "buffer %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}
		pb = paste_get_index(&global_buffers, buffer);
		if (pb == NULL) {
			cmdq_error(cmdq, "no buffer %d", buffer);
			return (CMD_RETURN_ERROR);
		}
	} else if (args_has(args, 'a')) {
		pb = paste_get_top(&global_buffers);
		if (pb != NULL)
			buffer = 0;
	}

	if (args_has(args, 'a') && pb != NULL) {
		psize = pb->size;
		pdata = xmalloc(psize);
		memcpy(pdata, pb->data, psize);
	}

	newsize = strlen(args->argv[0]);

	pdata = xrealloc(pdata, 1, psize + newsize);
	memcpy(pdata + psize, args->argv[0], newsize);
	psize += newsize;

	if (buffer == -1)
		paste_add(&global_buffers, pdata, psize, limit);
	else
		paste_replace(&global_buffers, buffer, pdata, psize);

	return (CMD_RETURN_NORMAL);
}
Пример #28
0
/* Translate mouse and output. */
void
input_mouse(struct window_pane *wp, struct session *s, struct mouse_event *m)
{
	char			 buf[10];
	size_t			 len;
	struct paste_buffer	*pb;

	if (wp->screen->mode & ALL_MOUSE_MODES) {
		if (wp->screen->mode & MODE_MOUSE_UTF8) {
			len = xsnprintf(buf, sizeof buf, "\033[M");
			len += utf8_split2(m->xb + 32, &buf[len]);
			len += utf8_split2(m->x + 33, &buf[len]);
			len += utf8_split2(m->y + 33, &buf[len]);
		} else {
			if (m->xb > 223 || m->x >= 222 || m->y > 222)
				return;
			len = xsnprintf(buf, sizeof buf, "\033[M");
			buf[len++] = m->xb + 32;
			buf[len++] = m->x + 33;
			buf[len++] = m->y + 33;
		}
		bufferevent_write(wp->event, buf, len);
		return;
	}

	if (m->button == 1 && (m->event & MOUSE_EVENT_CLICK) &&
	    options_get_number(&wp->window->options, "mode-mouse") == 1) {
		pb = paste_get_top(&global_buffers);
		if (pb != NULL) {
			paste_send_pane(pb, wp, "\r",
			    wp->screen->mode & MODE_BRACKETPASTE);
		}
	} else if ((m->xb & 3) != 1 &&
	    options_get_number(&wp->window->options, "mode-mouse") == 1) {
		if (window_pane_set_mode(wp, &window_copy_mode) == 0) {
			window_copy_init_from_pane(wp);
			if (wp->mode->mouse != NULL)
				wp->mode->mouse(wp, s, m);
		}
	}
}
Пример #29
0
void
check_window_name(struct window *w)
{
	struct timeval	 tv, next;
	char		*name;
	int		 left;

	if (w->active == NULL)
		return;

	if (!options_get_number(w->options, "automatic-rename"))
		return;

	if (~w->active->flags & PANE_CHANGED) {
		log_debug("@%u active pane not changed", w->id);
		return;
	}
	log_debug("@%u active pane changed", w->id);

	gettimeofday(&tv, NULL);
	left = name_time_expired(w, &tv);
	if (left != 0) {
		if (!event_initialized(&w->name_event))
			evtimer_set(&w->name_event, name_time_callback, w);
		if (!evtimer_pending(&w->name_event, NULL)) {
			log_debug("@%u name timer queued (%d left)", w->id,
			    left);
			timerclear(&next);
			next.tv_usec = left;
			event_add(&w->name_event, &next);
		} else {
			log_debug("@%u name timer already queued (%d left)",
			    w->id, left);
		}
		return;
	}
	memcpy(&w->name_time, &tv, sizeof w->name_time);
	if (event_initialized(&w->name_event))
		evtimer_del(&w->name_event);

	w->active->flags &= ~PANE_CHANGED;

	name = format_window_name(w);
	if (strcmp(name, w->name) != 0) {
		log_debug("@%u new name %s (was %s)", w->id, name, w->name);
		window_set_name(w, name);
		server_status_window(w);
	} else
		log_debug("@%u name not changed (still %s)", w->id, w->name);

	free(name);
}
Пример #30
0
/* Open UTF-8 character. */
int
input_utf8_open(struct input_ctx *ictx)
{
	if (!options_get_number(&ictx->wp->window->options, "utf8")) {
		/* Print, and do not switch state. */
		input_print(ictx);
		return (-1);
	}
	log_debug("%s", __func__);

	utf8_open(&ictx->utf8data, ictx->ch);
	return (0);
}