mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 01:34:18 +00:00 
			
		
		
		
	Merge branch 'obsd-master'
This commit is contained in:
		@@ -154,6 +154,7 @@ dist_tmux_SOURCES = \
 | 
				
			|||||||
	options-table.c \
 | 
						options-table.c \
 | 
				
			||||||
	options.c \
 | 
						options.c \
 | 
				
			||||||
	paste.c \
 | 
						paste.c \
 | 
				
			||||||
 | 
						popup.c \
 | 
				
			||||||
	proc.c \
 | 
						proc.c \
 | 
				
			||||||
	regsub.c \
 | 
						regsub.c \
 | 
				
			||||||
	resize.c \
 | 
						resize.c \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,6 +29,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static enum cmd_retval	cmd_display_menu_exec(struct cmd *,
 | 
					static enum cmd_retval	cmd_display_menu_exec(struct cmd *,
 | 
				
			||||||
			    struct cmdq_item *);
 | 
								    struct cmdq_item *);
 | 
				
			||||||
 | 
					static enum cmd_retval	cmd_display_popup_exec(struct cmd *,
 | 
				
			||||||
 | 
								    struct cmdq_item *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct cmd_entry cmd_display_menu_entry = {
 | 
					const struct cmd_entry cmd_display_menu_entry = {
 | 
				
			||||||
	.name = "display-menu",
 | 
						.name = "display-menu",
 | 
				
			||||||
@@ -44,6 +46,21 @@ const struct cmd_entry cmd_display_menu_entry = {
 | 
				
			|||||||
	.exec = cmd_display_menu_exec
 | 
						.exec = cmd_display_menu_exec
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_display_popup_entry = {
 | 
				
			||||||
 | 
						.name = "display-popup",
 | 
				
			||||||
 | 
						.alias = "popup",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.args = { "CEKc:d:h:R:t:w:x:y:", 0, -1 },
 | 
				
			||||||
 | 
						.usage = "[-CEK] [-c target-client] [-d start-directory] [-h height] "
 | 
				
			||||||
 | 
						         "[-R shell-command] " CMD_TARGET_PANE_USAGE " [-w width] "
 | 
				
			||||||
 | 
						         "[-x position] [-y position] [command line ...]",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.target = { 't', CMD_FIND_PANE, 0 },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.flags = CMD_AFTERHOOK,
 | 
				
			||||||
 | 
						.exec = cmd_display_popup_exec
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
cmd_display_menu_get_position(struct client *c, struct cmdq_item *item,
 | 
					cmd_display_menu_get_position(struct client *c, struct cmdq_item *item,
 | 
				
			||||||
    struct args *args, u_int *px, u_int *py, u_int w, u_int h)
 | 
					    struct args *args, u_int *px, u_int *py, u_int w, u_int h)
 | 
				
			||||||
@@ -190,3 +207,79 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
		return (CMD_RETURN_NORMAL);
 | 
							return (CMD_RETURN_NORMAL);
 | 
				
			||||||
	return (CMD_RETURN_WAIT);
 | 
						return (CMD_RETURN_WAIT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static enum cmd_retval
 | 
				
			||||||
 | 
					cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct args		*args = self->args;
 | 
				
			||||||
 | 
						struct client		*c;
 | 
				
			||||||
 | 
						struct cmd_find_state	*fs = &item->target;
 | 
				
			||||||
 | 
						const char		*value, *cmd = NULL, **lines = NULL;
 | 
				
			||||||
 | 
						const char		*shellcmd = NULL;
 | 
				
			||||||
 | 
						char			*cwd, *cause;
 | 
				
			||||||
 | 
						int			 flags = 0;
 | 
				
			||||||
 | 
						u_int			 px, py, w, h, nlines = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((c = cmd_find_client(item, args_get(args, 'c'), 0)) == NULL)
 | 
				
			||||||
 | 
							return (CMD_RETURN_ERROR);
 | 
				
			||||||
 | 
						if (args_has(args, 'C')) {
 | 
				
			||||||
 | 
							server_client_clear_overlay(c);
 | 
				
			||||||
 | 
							return (CMD_RETURN_NORMAL);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (c->overlay_draw != NULL)
 | 
				
			||||||
 | 
							return (CMD_RETURN_NORMAL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (args->argc >= 1)
 | 
				
			||||||
 | 
							cmd = args->argv[0];
 | 
				
			||||||
 | 
						if (args->argc >= 2) {
 | 
				
			||||||
 | 
							lines = (const char **)args->argv + 1;
 | 
				
			||||||
 | 
							nlines = args->argc - 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (nlines != 0)
 | 
				
			||||||
 | 
							h = nlines + 2;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							h = c->tty.sy / 2;
 | 
				
			||||||
 | 
						if (args_has(args, 'h')) {
 | 
				
			||||||
 | 
							h = args_percentage(args, 'h', 1, c->tty.sy, c->tty.sy, &cause);
 | 
				
			||||||
 | 
							if (cause != NULL) {
 | 
				
			||||||
 | 
								cmdq_error(item, "height %s", cause);
 | 
				
			||||||
 | 
								free(cause);
 | 
				
			||||||
 | 
								return (CMD_RETURN_ERROR);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (nlines != 0)
 | 
				
			||||||
 | 
							w = popup_width(item, nlines, lines, c, fs) + 2;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							w = c->tty.sx / 2;
 | 
				
			||||||
 | 
						if (args_has(args, 'w')) {
 | 
				
			||||||
 | 
							w = args_percentage(args, 'w', 1, c->tty.sx, c->tty.sx, &cause);
 | 
				
			||||||
 | 
							if (cause != NULL) {
 | 
				
			||||||
 | 
								cmdq_error(item, "width %s", cause);
 | 
				
			||||||
 | 
								free(cause);
 | 
				
			||||||
 | 
								return (CMD_RETURN_ERROR);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_display_menu_get_position(c, item, args, &px, &py, w, h);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = args_get(args, 'd');
 | 
				
			||||||
 | 
						if (value != NULL)
 | 
				
			||||||
 | 
							cwd = format_single(NULL, value, c, fs->s, fs->wl, fs->wp);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							cwd = xstrdup(server_client_get_cwd(c, fs->s));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = args_get(args, 'R');
 | 
				
			||||||
 | 
						if (value != NULL)
 | 
				
			||||||
 | 
							shellcmd = format_single(NULL, value, c, fs->s, fs->wl, fs->wp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (args_has(args, 'K'))
 | 
				
			||||||
 | 
							flags |= POPUP_WRITEKEYS;
 | 
				
			||||||
 | 
						if (args_has(args, 'E'))
 | 
				
			||||||
 | 
							flags |= POPUP_CLOSEEXIT;
 | 
				
			||||||
 | 
						if (popup_display(flags, item, px, py, w, h, nlines, lines, shellcmd,
 | 
				
			||||||
 | 
						    cmd, cwd, c, fs) != 0)
 | 
				
			||||||
 | 
							return (CMD_RETURN_NORMAL);
 | 
				
			||||||
 | 
						return (CMD_RETURN_WAIT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -273,7 +273,7 @@ cmd_display_panes_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	else
 | 
						else
 | 
				
			||||||
		cdata->item = item;
 | 
							cdata->item = item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	server_client_set_overlay(c, delay, cmd_display_panes_draw,
 | 
						server_client_set_overlay(c, delay, NULL, NULL, cmd_display_panes_draw,
 | 
				
			||||||
	    cmd_display_panes_key, cmd_display_panes_free, cdata);
 | 
						    cmd_display_panes_key, cmd_display_panes_free, cdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (args_has(args, 'b'))
 | 
						if (args_has(args, 'b'))
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								cmd.c
									
									
									
									
									
								
							@@ -43,6 +43,7 @@ extern const struct cmd_entry cmd_delete_buffer_entry;
 | 
				
			|||||||
extern const struct cmd_entry cmd_detach_client_entry;
 | 
					extern const struct cmd_entry cmd_detach_client_entry;
 | 
				
			||||||
extern const struct cmd_entry cmd_display_menu_entry;
 | 
					extern const struct cmd_entry cmd_display_menu_entry;
 | 
				
			||||||
extern const struct cmd_entry cmd_display_message_entry;
 | 
					extern const struct cmd_entry cmd_display_message_entry;
 | 
				
			||||||
 | 
					extern const struct cmd_entry cmd_display_popup_entry;
 | 
				
			||||||
extern const struct cmd_entry cmd_display_panes_entry;
 | 
					extern const struct cmd_entry cmd_display_panes_entry;
 | 
				
			||||||
extern const struct cmd_entry cmd_down_pane_entry;
 | 
					extern const struct cmd_entry cmd_down_pane_entry;
 | 
				
			||||||
extern const struct cmd_entry cmd_find_window_entry;
 | 
					extern const struct cmd_entry cmd_find_window_entry;
 | 
				
			||||||
@@ -132,6 +133,7 @@ const struct cmd_entry *cmd_table[] = {
 | 
				
			|||||||
	&cmd_detach_client_entry,
 | 
						&cmd_detach_client_entry,
 | 
				
			||||||
	&cmd_display_menu_entry,
 | 
						&cmd_display_menu_entry,
 | 
				
			||||||
	&cmd_display_message_entry,
 | 
						&cmd_display_message_entry,
 | 
				
			||||||
 | 
						&cmd_display_popup_entry,
 | 
				
			||||||
	&cmd_display_panes_entry,
 | 
						&cmd_display_panes_entry,
 | 
				
			||||||
	&cmd_find_window_entry,
 | 
						&cmd_find_window_entry,
 | 
				
			||||||
	&cmd_has_session_entry,
 | 
						&cmd_has_session_entry,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								job.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								job.c
									
									
									
									
									
								
							@@ -17,6 +17,7 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/ioctl.h>
 | 
				
			||||||
#include <sys/socket.h>
 | 
					#include <sys/socket.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <fcntl.h>
 | 
					#include <fcntl.h>
 | 
				
			||||||
@@ -203,6 +204,24 @@ job_free(struct job *job)
 | 
				
			|||||||
	free(job);
 | 
						free(job);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Resize job. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					job_resize(struct job *job, u_int sx, u_int sy)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct winsize	 ws;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (job->fd == -1 || (~job->flags & JOB_PTY))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log_debug("resize job %p: %ux%u", job, sx, sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(&ws, 0, sizeof ws);
 | 
				
			||||||
 | 
						ws.ws_col = sx;
 | 
				
			||||||
 | 
						ws.ws_row = sy;
 | 
				
			||||||
 | 
						if (ioctl(job->fd, TIOCSWINSZ, &ws) == -1)
 | 
				
			||||||
 | 
							fatal("ioctl failed");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Job buffer read callback. */
 | 
					/* Job buffer read callback. */
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
job_read_callback(__unused struct bufferevent *bufev, void *data)
 | 
					job_read_callback(__unused struct bufferevent *bufev, void *data)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										17
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								menu.c
									
									
									
									
									
								
							@@ -130,6 +130,16 @@ menu_free(struct menu *menu)
 | 
				
			|||||||
	free(menu);
 | 
						free(menu);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					menu_mode_cb(struct client *c, __unused u_int *cx, __unused u_int *cy)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct menu_data	*md = c->overlay_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (~md->flags & MENU_NOMOUSE)
 | 
				
			||||||
 | 
							return (MODE_MOUSE_ALL);
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
menu_draw_cb(struct client *c, __unused struct screen_redraw_ctx *ctx0)
 | 
					menu_draw_cb(struct client *c, __unused struct screen_redraw_ctx *ctx0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -147,9 +157,6 @@ menu_draw_cb(struct client *c, __unused struct screen_redraw_ctx *ctx0)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < screen_size_y(&md->s); i++)
 | 
						for (i = 0; i < screen_size_y(&md->s); i++)
 | 
				
			||||||
		tty_draw_line(tty, NULL, s, 0, i, menu->width + 4, px, py + i);
 | 
							tty_draw_line(tty, NULL, s, 0, i, menu->width + 4, px, py + i);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (~md->flags & MENU_NOMOUSE)
 | 
					 | 
				
			||||||
		tty_update_mode(tty, MODE_MOUSE_ALL, NULL);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@@ -317,7 +324,7 @@ menu_display(struct menu *menu, int flags, struct cmdq_item *item, u_int px,
 | 
				
			|||||||
	md->cb = cb;
 | 
						md->cb = cb;
 | 
				
			||||||
	md->data = data;
 | 
						md->data = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	server_client_set_overlay(c, 0, menu_draw_cb, menu_key_cb, menu_free_cb,
 | 
						server_client_set_overlay(c, 0, NULL, menu_mode_cb, menu_draw_cb,
 | 
				
			||||||
	    md);
 | 
						    menu_key_cb, menu_free_cb, md);
 | 
				
			||||||
	return (0);
 | 
						return (0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										447
									
								
								popup.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										447
									
								
								popup.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,447 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2020 Nicholas Marriott <nicholas.marriott@gmail.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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 <sys/wait.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <signal.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct popup_data {
 | 
				
			||||||
 | 
						struct client		 *c;
 | 
				
			||||||
 | 
						struct cmdq_item	 *item;
 | 
				
			||||||
 | 
						int			  flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char			**lines;
 | 
				
			||||||
 | 
						u_int			  nlines;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char			 *cmd;
 | 
				
			||||||
 | 
						struct cmd_find_state	  fs;
 | 
				
			||||||
 | 
						struct screen		  s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct job		 *job;
 | 
				
			||||||
 | 
						struct input_ctx	 *ictx;
 | 
				
			||||||
 | 
						int			  status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u_int			  px;
 | 
				
			||||||
 | 
						u_int			  py;
 | 
				
			||||||
 | 
						u_int			  sx;
 | 
				
			||||||
 | 
						u_int			  sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum { OFF, MOVE, SIZE }  dragging;
 | 
				
			||||||
 | 
						u_int			  dx;
 | 
				
			||||||
 | 
						u_int			  dy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u_int			  lx;
 | 
				
			||||||
 | 
						u_int			  ly;
 | 
				
			||||||
 | 
						u_int			  lb;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					popup_write_screen(struct client *c, struct popup_data *pd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmdq_item	*item = pd->item;
 | 
				
			||||||
 | 
						struct screen_write_ctx	 ctx;
 | 
				
			||||||
 | 
						char			*copy, *next, *loop, *tmp;
 | 
				
			||||||
 | 
						struct format_tree	*ft;
 | 
				
			||||||
 | 
						u_int			 i, y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ft = format_create(item->client, item, FORMAT_NONE, 0);
 | 
				
			||||||
 | 
						if (cmd_find_valid_state(&pd->fs))
 | 
				
			||||||
 | 
							format_defaults(ft, c, pd->fs.s, pd->fs.wl, pd->fs.wp);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							format_defaults(ft, c, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						screen_write_start(&ctx, NULL, &pd->s);
 | 
				
			||||||
 | 
						screen_write_clearscreen(&ctx, 8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						y = 0;
 | 
				
			||||||
 | 
						for (i = 0; i < pd->nlines; i++) {
 | 
				
			||||||
 | 
							if (y == pd->sy - 2)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							copy = next = xstrdup(pd->lines[i]);
 | 
				
			||||||
 | 
							while ((loop = strsep(&next, "\n")) != NULL) {
 | 
				
			||||||
 | 
								if (y == pd->sy - 2)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								tmp = format_expand(ft, loop);
 | 
				
			||||||
 | 
								screen_write_cursormove(&ctx, 0, y, 0);
 | 
				
			||||||
 | 
								format_draw(&ctx, &grid_default_cell, pd->sx - 2, tmp,
 | 
				
			||||||
 | 
								    NULL);
 | 
				
			||||||
 | 
								free(tmp);
 | 
				
			||||||
 | 
								y++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							free(copy);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						format_free(ft);
 | 
				
			||||||
 | 
						screen_write_cursormove(&ctx, 0, y, 0);
 | 
				
			||||||
 | 
						screen_write_stop(&ctx);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					popup_mode_cb(struct client *c, u_int *cx, u_int *cy)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct popup_data	*pd = c->overlay_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pd->ictx == NULL)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						*cx = pd->px + 1 + pd->s.cx;
 | 
				
			||||||
 | 
						*cy = pd->py + 1 + pd->s.cy;
 | 
				
			||||||
 | 
						return (pd->s.mode);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					popup_check_cb(struct client *c, u_int px, u_int py)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct popup_data	*pd = c->overlay_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (px < pd->px || px > pd->px + pd->sx - 1)
 | 
				
			||||||
 | 
							return (1);
 | 
				
			||||||
 | 
						if (py < pd->py || py > pd->py + pd->sy - 1)
 | 
				
			||||||
 | 
							return (1);
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					popup_draw_cb(struct client *c, __unused struct screen_redraw_ctx *ctx0)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct popup_data	*pd = c->overlay_data;
 | 
				
			||||||
 | 
						struct tty		*tty = &c->tty;
 | 
				
			||||||
 | 
						struct screen		 s;
 | 
				
			||||||
 | 
						struct screen_write_ctx	 ctx;
 | 
				
			||||||
 | 
						u_int			 i, px = pd->px, py = pd->py;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						screen_init(&s, pd->sx, pd->sy, 0);
 | 
				
			||||||
 | 
						screen_write_start(&ctx, NULL, &s);
 | 
				
			||||||
 | 
						screen_write_clearscreen(&ctx, 8);
 | 
				
			||||||
 | 
						screen_write_box(&ctx, pd->sx, pd->sy);
 | 
				
			||||||
 | 
						screen_write_cursormove(&ctx, 1, 1, 0);
 | 
				
			||||||
 | 
						screen_write_fast_copy(&ctx, &pd->s, 0, 0, pd->sx - 2, pd->sy - 2);
 | 
				
			||||||
 | 
						screen_write_stop(&ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c->overlay_check = NULL;
 | 
				
			||||||
 | 
						for (i = 0; i < pd->sy; i++)
 | 
				
			||||||
 | 
							tty_draw_line(tty, NULL, &s, 0, i, pd->sx, px, py + i);
 | 
				
			||||||
 | 
						c->overlay_check = popup_check_cb;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					popup_free_cb(struct client *c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct popup_data	*pd = c->overlay_data;
 | 
				
			||||||
 | 
						struct cmdq_item	*item = pd->item;
 | 
				
			||||||
 | 
						u_int			 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (item != NULL) {
 | 
				
			||||||
 | 
							if (pd->ictx != NULL &&
 | 
				
			||||||
 | 
							    item->client != NULL &&
 | 
				
			||||||
 | 
							    item->client->session == NULL)
 | 
				
			||||||
 | 
								item->client->retval = pd->status;
 | 
				
			||||||
 | 
							cmdq_continue(item);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						server_client_unref(pd->c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pd->job != NULL)
 | 
				
			||||||
 | 
							job_free(pd->job);
 | 
				
			||||||
 | 
						if (pd->ictx != NULL)
 | 
				
			||||||
 | 
							input_free(pd->ictx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < pd->nlines; i++)
 | 
				
			||||||
 | 
							free(pd->lines[i]);
 | 
				
			||||||
 | 
						free(pd->lines);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						screen_free(&pd->s);
 | 
				
			||||||
 | 
						free(pd->cmd);
 | 
				
			||||||
 | 
						free(pd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					popup_handle_drag(struct client *c, struct popup_data *pd,
 | 
				
			||||||
 | 
					    struct mouse_event *m)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	px, py;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!MOUSE_DRAG(m->b))
 | 
				
			||||||
 | 
							pd->dragging = OFF;
 | 
				
			||||||
 | 
						else if (pd->dragging == MOVE) {
 | 
				
			||||||
 | 
							if (m->x < pd->dx)
 | 
				
			||||||
 | 
								px = 0;
 | 
				
			||||||
 | 
							else if (m->x - pd->dx + pd->sx > c->tty.sx)
 | 
				
			||||||
 | 
								px = c->tty.sx - pd->sx;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								px = m->x - pd->dx;
 | 
				
			||||||
 | 
							if (m->y < pd->dy)
 | 
				
			||||||
 | 
								py = 0;
 | 
				
			||||||
 | 
							else if (m->y - pd->dy + pd->sy > c->tty.sy)
 | 
				
			||||||
 | 
								py = c->tty.sy - pd->sy;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								py = m->y - pd->dy;
 | 
				
			||||||
 | 
							pd->px = px;
 | 
				
			||||||
 | 
							pd->py = py;
 | 
				
			||||||
 | 
							pd->dx = m->x - pd->px;
 | 
				
			||||||
 | 
							pd->dy = m->y - pd->py;
 | 
				
			||||||
 | 
							server_redraw_client(c);
 | 
				
			||||||
 | 
						} else if (pd->dragging == SIZE) {
 | 
				
			||||||
 | 
							if (m->x < pd->px + 2)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							if (m->y < pd->py + 2)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							pd->sx = m->x - pd->px;
 | 
				
			||||||
 | 
							pd->sy = m->y - pd->py;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							screen_resize(&pd->s, pd->sx, pd->sy, 0);
 | 
				
			||||||
 | 
							if (pd->ictx == NULL)
 | 
				
			||||||
 | 
								popup_write_screen(c, pd);
 | 
				
			||||||
 | 
							else if (pd->job != NULL)
 | 
				
			||||||
 | 
								job_resize(pd->job, pd->sx - 2, pd->sy - 2);
 | 
				
			||||||
 | 
							server_redraw_client(c);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					popup_key_cb(struct client *c, struct key_event *event)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct popup_data	*pd = c->overlay_data;
 | 
				
			||||||
 | 
						struct mouse_event	*m = &event->m;
 | 
				
			||||||
 | 
						struct cmd_find_state	*fs = &pd->fs;
 | 
				
			||||||
 | 
						struct cmdq_item	*new_item;
 | 
				
			||||||
 | 
						struct cmd_parse_result	*pr;
 | 
				
			||||||
 | 
						struct format_tree	*ft;
 | 
				
			||||||
 | 
						const char		*cmd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (KEYC_IS_MOUSE(event->key)) {
 | 
				
			||||||
 | 
							if (pd->dragging != OFF) {
 | 
				
			||||||
 | 
								popup_handle_drag(c, pd, m);
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (m->x < pd->px ||
 | 
				
			||||||
 | 
							    m->x > pd->px + pd->sx - 1 ||
 | 
				
			||||||
 | 
							    m->y < pd->py ||
 | 
				
			||||||
 | 
							    m->y > pd->py + pd->sy - 1) {
 | 
				
			||||||
 | 
								if (MOUSE_BUTTONS (m->b) == 1)
 | 
				
			||||||
 | 
									return (1);
 | 
				
			||||||
 | 
								return (0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if ((m->b & MOUSE_MASK_META) ||
 | 
				
			||||||
 | 
							    m->x == pd->px ||
 | 
				
			||||||
 | 
							    m->x == pd->px + pd->sx - 1 ||
 | 
				
			||||||
 | 
							    m->y == pd->py ||
 | 
				
			||||||
 | 
							    m->y == pd->py + pd->sy - 1) {
 | 
				
			||||||
 | 
								if (!MOUSE_DRAG(m->b))
 | 
				
			||||||
 | 
									goto out;
 | 
				
			||||||
 | 
								if (MOUSE_BUTTONS(m->lb) == 0)
 | 
				
			||||||
 | 
									pd->dragging = MOVE;
 | 
				
			||||||
 | 
								else if (MOUSE_BUTTONS(m->lb) == 2)
 | 
				
			||||||
 | 
									pd->dragging = SIZE;
 | 
				
			||||||
 | 
								pd->dx = m->lx - pd->px;
 | 
				
			||||||
 | 
								pd->dy = m->ly - pd->py;
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pd->ictx != NULL && (pd->flags & POPUP_WRITEKEYS)) {
 | 
				
			||||||
 | 
							if (KEYC_IS_MOUSE(event->key))
 | 
				
			||||||
 | 
								return (0);
 | 
				
			||||||
 | 
							if ((~pd->flags & POPUP_CLOSEEXIT) &&
 | 
				
			||||||
 | 
							    (event->key == '\033' || event->key == '\003'))
 | 
				
			||||||
 | 
								return (1);
 | 
				
			||||||
 | 
							if (pd->job == NULL)
 | 
				
			||||||
 | 
								return (0);
 | 
				
			||||||
 | 
							input_key(NULL, &pd->s, job_get_event(pd->job), event->key);
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pd->cmd == NULL)
 | 
				
			||||||
 | 
							return (1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ft = format_create(NULL, pd->item, FORMAT_NONE, 0);
 | 
				
			||||||
 | 
						if (cmd_find_valid_state(fs))
 | 
				
			||||||
 | 
							format_defaults(ft, c, fs->s, fs->wl, fs->wp);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							format_defaults(ft, c, NULL, NULL, NULL);
 | 
				
			||||||
 | 
						format_add(ft, "popup_key", "%s", key_string_lookup_key(event->key));
 | 
				
			||||||
 | 
						if (KEYC_IS_MOUSE(event->key)) {
 | 
				
			||||||
 | 
							format_add(ft, "popup_mouse", "1");
 | 
				
			||||||
 | 
							format_add(ft, "popup_mouse_x", "%u", m->x - pd->px);
 | 
				
			||||||
 | 
							format_add(ft, "popup_mouse_y", "%u", m->y - pd->py);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						cmd = format_expand(ft, pd->cmd);
 | 
				
			||||||
 | 
						format_free(ft);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pr = cmd_parse_from_string(cmd, NULL);
 | 
				
			||||||
 | 
						switch (pr->status) {
 | 
				
			||||||
 | 
						case CMD_PARSE_EMPTY:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case CMD_PARSE_ERROR:
 | 
				
			||||||
 | 
							new_item = cmdq_get_error(pr->error);
 | 
				
			||||||
 | 
							free(pr->error);
 | 
				
			||||||
 | 
							cmdq_append(c, new_item);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case CMD_PARSE_SUCCESS:
 | 
				
			||||||
 | 
							if (pd->item != NULL)
 | 
				
			||||||
 | 
								m = &pd->item->shared->mouse;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								m = NULL;
 | 
				
			||||||
 | 
							new_item = cmdq_get_command(pr->cmdlist, fs, m, 0);
 | 
				
			||||||
 | 
							cmd_list_free(pr->cmdlist);
 | 
				
			||||||
 | 
							cmdq_append(c, new_item);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						pd->lx = m->x;
 | 
				
			||||||
 | 
						pd->ly = m->y;
 | 
				
			||||||
 | 
						pd->lb = m->b;
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					popup_job_update_cb(struct job *job)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct popup_data	*pd = job_get_data(job);
 | 
				
			||||||
 | 
						struct evbuffer		*evb = job_get_event(job)->input;
 | 
				
			||||||
 | 
						struct screen		*s = &pd->s;
 | 
				
			||||||
 | 
						void			*data = EVBUFFER_DATA(evb);
 | 
				
			||||||
 | 
						size_t			 size = EVBUFFER_LENGTH(evb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (size != 0) {
 | 
				
			||||||
 | 
							input_parse_screen(pd->ictx, s, data, size);
 | 
				
			||||||
 | 
							evbuffer_drain(evb, size);
 | 
				
			||||||
 | 
							pd->c->flags |= CLIENT_REDRAWOVERLAY;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					popup_job_complete_cb(struct job *job)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct popup_data	*pd = job_get_data(job);
 | 
				
			||||||
 | 
						int			 status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						status = job_get_status(pd->job);
 | 
				
			||||||
 | 
						if (WIFEXITED(status))
 | 
				
			||||||
 | 
							pd->status = WEXITSTATUS(status);
 | 
				
			||||||
 | 
						else if (WIFSIGNALED(status))
 | 
				
			||||||
 | 
							pd->status = WTERMSIG(status);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							pd->status = 0;
 | 
				
			||||||
 | 
						pd->job = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pd->flags & POPUP_CLOSEEXIT)
 | 
				
			||||||
 | 
							server_client_clear_overlay(pd->c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u_int
 | 
				
			||||||
 | 
					popup_width(struct cmdq_item *item, u_int nlines, const char **lines,
 | 
				
			||||||
 | 
					    struct client *c, struct cmd_find_state *fs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char			*copy, *next, *loop, *tmp;
 | 
				
			||||||
 | 
						struct format_tree	*ft;
 | 
				
			||||||
 | 
						u_int			 i, width = 0, tmpwidth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ft = format_create(item->client, item, FORMAT_NONE, 0);
 | 
				
			||||||
 | 
						if (fs != NULL && cmd_find_valid_state(fs))
 | 
				
			||||||
 | 
							format_defaults(ft, c, fs->s, fs->wl, fs->wp);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							format_defaults(ft, c, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < nlines; i++) {
 | 
				
			||||||
 | 
							copy = next = xstrdup(lines[i]);
 | 
				
			||||||
 | 
							while ((loop = strsep(&next, "\n")) != NULL) {
 | 
				
			||||||
 | 
								tmp = format_expand(ft, loop);
 | 
				
			||||||
 | 
								tmpwidth = format_width(tmp);
 | 
				
			||||||
 | 
								if (tmpwidth > width)
 | 
				
			||||||
 | 
									width = tmpwidth;
 | 
				
			||||||
 | 
								free(tmp);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						free(copy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						format_free(ft);
 | 
				
			||||||
 | 
						return (width);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					popup_display(int flags, struct cmdq_item *item, u_int px, u_int py, u_int sx,
 | 
				
			||||||
 | 
					    u_int sy, u_int nlines, const char **lines, const char *shellcmd,
 | 
				
			||||||
 | 
					    const char *cmd, const char *cwd, struct client *c,
 | 
				
			||||||
 | 
					    struct cmd_find_state *fs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct popup_data	*pd;
 | 
				
			||||||
 | 
						u_int			 i;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						int			 jobflags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sx < 3 || sy < 3)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						if (c->tty.sx < sx || c->tty.sy < sy)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						if (nlines > sy - 2)
 | 
				
			||||||
 | 
							nlines = sy - 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pd = xcalloc(1, sizeof *pd);
 | 
				
			||||||
 | 
						pd->item = item;
 | 
				
			||||||
 | 
						pd->flags = flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pd->c = c;
 | 
				
			||||||
 | 
						pd->c->references++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pd->status = 128 + SIGHUP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (fs != NULL)
 | 
				
			||||||
 | 
							cmd_find_copy_state(&pd->fs, fs);
 | 
				
			||||||
 | 
						screen_init(&pd->s, sx - 2, sy - 2, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cmd != NULL)
 | 
				
			||||||
 | 
							pd->cmd = xstrdup(cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pd->px = px;
 | 
				
			||||||
 | 
						pd->py = py;
 | 
				
			||||||
 | 
						pd->sx = sx;
 | 
				
			||||||
 | 
						pd->sy = sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pd->nlines = nlines;
 | 
				
			||||||
 | 
						if (pd->nlines != 0)
 | 
				
			||||||
 | 
							pd->lines = xreallocarray(NULL, pd->nlines, sizeof *pd->lines);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < pd->nlines; i++)
 | 
				
			||||||
 | 
							pd->lines[i] = xstrdup(lines[i]);
 | 
				
			||||||
 | 
						popup_write_screen(c, pd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (shellcmd != NULL) {
 | 
				
			||||||
 | 
							pd->ictx = input_init(NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (fs != NULL)
 | 
				
			||||||
 | 
								s = fs->s;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								s = NULL;
 | 
				
			||||||
 | 
							jobflags = JOB_NOWAIT|JOB_PTY;
 | 
				
			||||||
 | 
							if (flags & POPUP_WRITEKEYS)
 | 
				
			||||||
 | 
							    jobflags |= JOB_KEEPWRITE;
 | 
				
			||||||
 | 
							pd->job = job_run(shellcmd, s, cwd, popup_job_update_cb,
 | 
				
			||||||
 | 
							    popup_job_complete_cb, NULL, pd, jobflags, pd->sx - 2,
 | 
				
			||||||
 | 
							    pd->sy - 2);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						server_client_set_overlay(c, 0, popup_check_cb, popup_mode_cb,
 | 
				
			||||||
 | 
						    popup_draw_cb, popup_key_cb, popup_free_cb, pd);
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -482,6 +482,8 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j,
 | 
				
			|||||||
	u_int			 type, x = ctx->ox + i, y = ctx->oy + j;
 | 
						u_int			 type, x = ctx->ox + i, y = ctx->oy + j;
 | 
				
			||||||
	int			 flag, pane_status = ctx->pane_status;
 | 
						int			 flag, pane_status = ctx->pane_status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (c->overlay_check != NULL && !c->overlay_check(c, x, y))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
	type = screen_redraw_check_cell(c, x, y, pane_status, &wp);
 | 
						type = screen_redraw_check_cell(c, x, y, pane_status, &wp);
 | 
				
			||||||
	if (type == CELL_INSIDE)
 | 
						if (type == CELL_INSIDE)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,7 +41,6 @@ static void	server_client_check_redraw(struct client *);
 | 
				
			|||||||
static void	server_client_set_title(struct client *);
 | 
					static void	server_client_set_title(struct client *);
 | 
				
			||||||
static void	server_client_reset_state(struct client *);
 | 
					static void	server_client_reset_state(struct client *);
 | 
				
			||||||
static int	server_client_assume_paste(struct session *);
 | 
					static int	server_client_assume_paste(struct session *);
 | 
				
			||||||
static void	server_client_clear_overlay(struct client *);
 | 
					 | 
				
			||||||
static void	server_client_resize_event(int, short, void *);
 | 
					static void	server_client_resize_event(int, short, void *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void	server_client_dispatch(struct imsg *, void *);
 | 
					static void	server_client_dispatch(struct imsg *, void *);
 | 
				
			||||||
@@ -79,8 +78,10 @@ server_client_overlay_timer(__unused int fd, __unused short events, void *data)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* Set an overlay on client. */
 | 
					/* Set an overlay on client. */
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
server_client_set_overlay(struct client *c, u_int delay, overlay_draw_cb drawcb,
 | 
					server_client_set_overlay(struct client *c, u_int delay,
 | 
				
			||||||
    overlay_key_cb keycb, overlay_free_cb freecb, void *data)
 | 
					    overlay_check_cb checkcb, overlay_mode_cb modecb,
 | 
				
			||||||
 | 
					    overlay_draw_cb drawcb, overlay_key_cb keycb, overlay_free_cb freecb,
 | 
				
			||||||
 | 
					    void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct timeval	tv;
 | 
						struct timeval	tv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -96,17 +97,21 @@ server_client_set_overlay(struct client *c, u_int delay, overlay_draw_cb drawcb,
 | 
				
			|||||||
	if (delay != 0)
 | 
						if (delay != 0)
 | 
				
			||||||
		evtimer_add(&c->overlay_timer, &tv);
 | 
							evtimer_add(&c->overlay_timer, &tv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c->overlay_check = checkcb;
 | 
				
			||||||
 | 
						c->overlay_mode = modecb;
 | 
				
			||||||
	c->overlay_draw = drawcb;
 | 
						c->overlay_draw = drawcb;
 | 
				
			||||||
	c->overlay_key = keycb;
 | 
						c->overlay_key = keycb;
 | 
				
			||||||
	c->overlay_free = freecb;
 | 
						c->overlay_free = freecb;
 | 
				
			||||||
	c->overlay_data = data;
 | 
						c->overlay_data = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c->tty.flags |= (TTY_FREEZE|TTY_NOCURSOR);
 | 
						c->tty.flags |= TTY_FREEZE;
 | 
				
			||||||
 | 
						if (c->overlay_mode == NULL)
 | 
				
			||||||
 | 
							c->tty.flags |= TTY_NOCURSOR;
 | 
				
			||||||
	server_redraw_client(c);
 | 
						server_redraw_client(c);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Clear overlay mode on client. */
 | 
					/* Clear overlay mode on client. */
 | 
				
			||||||
static void
 | 
					void
 | 
				
			||||||
server_client_clear_overlay(struct client *c)
 | 
					server_client_clear_overlay(struct client *c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (c->overlay_draw == NULL)
 | 
						if (c->overlay_draw == NULL)
 | 
				
			||||||
@@ -118,8 +123,12 @@ server_client_clear_overlay(struct client *c)
 | 
				
			|||||||
	if (c->overlay_free != NULL)
 | 
						if (c->overlay_free != NULL)
 | 
				
			||||||
		c->overlay_free(c);
 | 
							c->overlay_free(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c->overlay_check = NULL;
 | 
				
			||||||
 | 
						c->overlay_mode = NULL;
 | 
				
			||||||
	c->overlay_draw = NULL;
 | 
						c->overlay_draw = NULL;
 | 
				
			||||||
	c->overlay_key = NULL;
 | 
						c->overlay_key = NULL;
 | 
				
			||||||
 | 
						c->overlay_free = NULL;
 | 
				
			||||||
 | 
						c->overlay_data = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c->tty.flags &= ~(TTY_FREEZE|TTY_NOCURSOR);
 | 
						c->tty.flags &= ~(TTY_FREEZE|TTY_NOCURSOR);
 | 
				
			||||||
	server_redraw_client(c);
 | 
						server_redraw_client(c);
 | 
				
			||||||
@@ -1483,21 +1492,33 @@ server_client_reset_state(struct client *c)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	struct window		*w = c->session->curw->window;
 | 
						struct window		*w = c->session->curw->window;
 | 
				
			||||||
	struct window_pane	*wp = w->active, *loop;
 | 
						struct window_pane	*wp = w->active, *loop;
 | 
				
			||||||
	struct screen		*s = wp->screen;
 | 
						struct screen		*s;
 | 
				
			||||||
	struct options		*oo = c->session->options;
 | 
						struct options		*oo = c->session->options;
 | 
				
			||||||
	int			 mode, cursor = 0;
 | 
						int			 mode, cursor = 0;
 | 
				
			||||||
	u_int			 cx = 0, cy = 0, ox, oy, sx, sy;
 | 
						u_int			 cx = 0, cy = 0, ox, oy, sx, sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
 | 
						if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	if (c->overlay_draw != NULL)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	mode = s->mode;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Get mode from overlay if any, else from screen. */
 | 
				
			||||||
 | 
						if (c->overlay_draw != NULL) {
 | 
				
			||||||
 | 
							s = NULL;
 | 
				
			||||||
 | 
							if (c->overlay_mode == NULL)
 | 
				
			||||||
 | 
								mode = 0;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								mode = c->overlay_mode(c, &cx, &cy);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							s = wp->screen;
 | 
				
			||||||
 | 
							mode = s->mode;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						log_debug("%s: client %s mode %x", __func__, c->name, mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Reset region and margin. */
 | 
				
			||||||
	tty_region_off(&c->tty);
 | 
						tty_region_off(&c->tty);
 | 
				
			||||||
	tty_margin_off(&c->tty);
 | 
						tty_margin_off(&c->tty);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Move cursor to pane cursor and offset. */
 | 
						/* Move cursor to pane cursor and offset. */
 | 
				
			||||||
 | 
						if (c->overlay_draw == NULL) {
 | 
				
			||||||
		cursor = 0;
 | 
							cursor = 0;
 | 
				
			||||||
		tty_window_offset(&c->tty, &ox, &oy, &sx, &sy);
 | 
							tty_window_offset(&c->tty, &ox, &oy, &sx, &sy);
 | 
				
			||||||
		if (wp->xoff + s->cx >= ox && wp->xoff + s->cx <= ox + sx &&
 | 
							if (wp->xoff + s->cx >= ox && wp->xoff + s->cx <= ox + sx &&
 | 
				
			||||||
@@ -1512,6 +1533,7 @@ server_client_reset_state(struct client *c)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		if (!cursor)
 | 
							if (!cursor)
 | 
				
			||||||
			mode &= ~MODE_CURSOR;
 | 
								mode &= ~MODE_CURSOR;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	tty_cursor(&c->tty, cx, cy);
 | 
						tty_cursor(&c->tty, cx, cy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
@@ -1520,16 +1542,18 @@ server_client_reset_state(struct client *c)
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (options_get_number(oo, "mouse")) {
 | 
						if (options_get_number(oo, "mouse")) {
 | 
				
			||||||
		mode &= ~ALL_MOUSE_MODES;
 | 
							mode &= ~ALL_MOUSE_MODES;
 | 
				
			||||||
 | 
							if (c->overlay_draw == NULL) {
 | 
				
			||||||
			TAILQ_FOREACH(loop, &w->panes, entry) {
 | 
								TAILQ_FOREACH(loop, &w->panes, entry) {
 | 
				
			||||||
				if (loop->screen->mode & MODE_MOUSE_ALL)
 | 
									if (loop->screen->mode & MODE_MOUSE_ALL)
 | 
				
			||||||
					mode |= MODE_MOUSE_ALL;
 | 
										mode |= MODE_MOUSE_ALL;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if (~mode & MODE_MOUSE_ALL)
 | 
							if (~mode & MODE_MOUSE_ALL)
 | 
				
			||||||
			mode |= MODE_MOUSE_BUTTON;
 | 
								mode |= MODE_MOUSE_BUTTON;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Clear bracketed paste mode if at the prompt. */
 | 
						/* Clear bracketed paste mode if at the prompt. */
 | 
				
			||||||
	if (c->prompt_string != NULL)
 | 
						if (c->overlay_draw == NULL && c->prompt_string != NULL)
 | 
				
			||||||
		mode &= ~MODE_BRACKETPASTE;
 | 
							mode &= ~MODE_BRACKETPASTE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set the terminal mode and reset attributes. */
 | 
						/* Set the terminal mode and reset attributes. */
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										89
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								tmux.1
									
									
									
									
									
								
							@@ -4384,6 +4384,9 @@ The following variables are available, where appropriate:
 | 
				
			|||||||
.It Li "pane_tty" Ta "" Ta "Pseudo terminal of pane"
 | 
					.It Li "pane_tty" Ta "" Ta "Pseudo terminal of pane"
 | 
				
			||||||
.It Li "pane_width" Ta "" Ta "Width of pane"
 | 
					.It Li "pane_width" Ta "" Ta "Width of pane"
 | 
				
			||||||
.It Li "pid" Ta "" Ta "Server PID"
 | 
					.It Li "pid" Ta "" Ta "Server PID"
 | 
				
			||||||
 | 
					.It Li "popup_key" Ta "" Ta "Key pressed in popup"
 | 
				
			||||||
 | 
					.It Li "popup_mouse_x" Ta "" Ta "Mouse X position in popup"
 | 
				
			||||||
 | 
					.It Li "popup_mouse_y" Ta "" Ta "Mouse Y position in popup"
 | 
				
			||||||
.It Li "rectangle_toggle" Ta "" Ta "1 if rectangle selection is activated"
 | 
					.It Li "rectangle_toggle" Ta "" Ta "1 if rectangle selection is activated"
 | 
				
			||||||
.It Li "scroll_position" Ta "" Ta "Scroll position in copy mode"
 | 
					.It Li "scroll_position" Ta "" Ta "Scroll position in copy mode"
 | 
				
			||||||
.It Li "scroll_region_lower" Ta "" Ta "Bottom of scroll region in pane"
 | 
					.It Li "scroll_region_lower" Ta "" Ta "Bottom of scroll region in pane"
 | 
				
			||||||
@@ -4973,6 +4976,92 @@ lists the format variables and their values.
 | 
				
			|||||||
.Fl I
 | 
					.Fl I
 | 
				
			||||||
forwards any input read from stdin to the empty pane given by
 | 
					forwards any input read from stdin to the empty pane given by
 | 
				
			||||||
.Ar target-pane .
 | 
					.Ar target-pane .
 | 
				
			||||||
 | 
					.It Xo Ic display-popup
 | 
				
			||||||
 | 
					.Op Fl CEK
 | 
				
			||||||
 | 
					.Op Fl c Ar target-client
 | 
				
			||||||
 | 
					.Op Fl d Ar start-directory
 | 
				
			||||||
 | 
					.Op Fl h Ar height
 | 
				
			||||||
 | 
					.Op Fl R Ar shell-command
 | 
				
			||||||
 | 
					.Op Fl t Ar target-pane
 | 
				
			||||||
 | 
					.Op Fl w Ar width
 | 
				
			||||||
 | 
					.Op Fl x Ar position
 | 
				
			||||||
 | 
					.Op Fl y Ar position
 | 
				
			||||||
 | 
					.Op Ar command Ar line Ar ...
 | 
				
			||||||
 | 
					.Xc
 | 
				
			||||||
 | 
					.D1 (alias: Ic popup )
 | 
				
			||||||
 | 
					Display a popup on
 | 
				
			||||||
 | 
					.Ar target-client .
 | 
				
			||||||
 | 
					A popup is a rectangular box drawn over the top of any panes.
 | 
				
			||||||
 | 
					Panes are not updated while a popup is present.
 | 
				
			||||||
 | 
					The popup content may be given in two ways:
 | 
				
			||||||
 | 
					.Bl -enum -offset Ds
 | 
				
			||||||
 | 
					.It
 | 
				
			||||||
 | 
					A set of lines as arguments.
 | 
				
			||||||
 | 
					Each line is a format which is expanded using
 | 
				
			||||||
 | 
					.Ar target-pane
 | 
				
			||||||
 | 
					as the target.
 | 
				
			||||||
 | 
					If a line contains newlines it is split into multiple lines.
 | 
				
			||||||
 | 
					Lines may use styles, see the
 | 
				
			||||||
 | 
					.Sx STYLES
 | 
				
			||||||
 | 
					section.
 | 
				
			||||||
 | 
					.It
 | 
				
			||||||
 | 
					A shell command given by
 | 
				
			||||||
 | 
					.Fl R
 | 
				
			||||||
 | 
					which is run and any output shown in the pane.
 | 
				
			||||||
 | 
					.El
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
 | 
					The first argument,
 | 
				
			||||||
 | 
					.Ar command ,
 | 
				
			||||||
 | 
					is a
 | 
				
			||||||
 | 
					.Nm
 | 
				
			||||||
 | 
					command which is run when a key is pressed.
 | 
				
			||||||
 | 
					The key is available in the
 | 
				
			||||||
 | 
					.Ql popup_key
 | 
				
			||||||
 | 
					format.
 | 
				
			||||||
 | 
					After
 | 
				
			||||||
 | 
					.Ar command
 | 
				
			||||||
 | 
					is run, the popup is closed.
 | 
				
			||||||
 | 
					It may be empty to discard any key presses.
 | 
				
			||||||
 | 
					If
 | 
				
			||||||
 | 
					.Fl K
 | 
				
			||||||
 | 
					is given together with
 | 
				
			||||||
 | 
					.Fl R,
 | 
				
			||||||
 | 
					key presses are instead passed to the
 | 
				
			||||||
 | 
					.Fl R
 | 
				
			||||||
 | 
					shell command.
 | 
				
			||||||
 | 
					.Fl E
 | 
				
			||||||
 | 
					closes the popup automatically when
 | 
				
			||||||
 | 
					.Ar shell-command
 | 
				
			||||||
 | 
					exits.
 | 
				
			||||||
 | 
					With
 | 
				
			||||||
 | 
					.Fl K ,
 | 
				
			||||||
 | 
					.Ql Escape
 | 
				
			||||||
 | 
					and
 | 
				
			||||||
 | 
					.Ql C-c
 | 
				
			||||||
 | 
					close the popup unless
 | 
				
			||||||
 | 
					.Fl E
 | 
				
			||||||
 | 
					is also given.
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
 | 
					.Fl x
 | 
				
			||||||
 | 
					and
 | 
				
			||||||
 | 
					.Fl y
 | 
				
			||||||
 | 
					give the position of the popup, they have the same meaning as for the
 | 
				
			||||||
 | 
					.Ic display-menu
 | 
				
			||||||
 | 
					command.
 | 
				
			||||||
 | 
					.Fl w
 | 
				
			||||||
 | 
					and
 | 
				
			||||||
 | 
					.Fl h
 | 
				
			||||||
 | 
					give the width and height - both may be a percentage (followed by
 | 
				
			||||||
 | 
					.Ql % ) .
 | 
				
			||||||
 | 
					If omitted, without
 | 
				
			||||||
 | 
					.Fl R
 | 
				
			||||||
 | 
					they are calculated from the given lines and with
 | 
				
			||||||
 | 
					.Fl R
 | 
				
			||||||
 | 
					they use half the terminal size.
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
 | 
					The
 | 
				
			||||||
 | 
					.Fl C
 | 
				
			||||||
 | 
					flag closes any popup on the client.
 | 
				
			||||||
.El
 | 
					.El
 | 
				
			||||||
.Sh BUFFERS
 | 
					.Sh BUFFERS
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										20
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1517,6 +1517,8 @@ RB_HEAD(client_files, client_file);
 | 
				
			|||||||
/* Client connection. */
 | 
					/* Client connection. */
 | 
				
			||||||
typedef int (*prompt_input_cb)(struct client *, void *, const char *, int);
 | 
					typedef int (*prompt_input_cb)(struct client *, void *, const char *, int);
 | 
				
			||||||
typedef void (*prompt_free_cb)(void *);
 | 
					typedef void (*prompt_free_cb)(void *);
 | 
				
			||||||
 | 
					typedef int (*overlay_check_cb)(struct client *, u_int, u_int);
 | 
				
			||||||
 | 
					typedef int (*overlay_mode_cb)(struct client *, u_int *, u_int *);
 | 
				
			||||||
typedef void (*overlay_draw_cb)(struct client *, struct screen_redraw_ctx *);
 | 
					typedef void (*overlay_draw_cb)(struct client *, struct screen_redraw_ctx *);
 | 
				
			||||||
typedef int (*overlay_key_cb)(struct client *, struct key_event *);
 | 
					typedef int (*overlay_key_cb)(struct client *, struct key_event *);
 | 
				
			||||||
typedef void (*overlay_free_cb)(struct client *);
 | 
					typedef void (*overlay_free_cb)(struct client *);
 | 
				
			||||||
@@ -1632,6 +1634,8 @@ struct client {
 | 
				
			|||||||
	u_int		 pan_ox;
 | 
						u_int		 pan_ox;
 | 
				
			||||||
	u_int		 pan_oy;
 | 
						u_int		 pan_oy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						overlay_check_cb overlay_check;
 | 
				
			||||||
 | 
						overlay_mode_cb	 overlay_mode;
 | 
				
			||||||
	overlay_draw_cb	 overlay_draw;
 | 
						overlay_draw_cb	 overlay_draw;
 | 
				
			||||||
	overlay_key_cb	 overlay_key;
 | 
						overlay_key_cb	 overlay_key;
 | 
				
			||||||
	overlay_free_cb	 overlay_free;
 | 
						overlay_free_cb	 overlay_free;
 | 
				
			||||||
@@ -1936,6 +1940,7 @@ struct job	*job_run(const char *, struct session *, const char *,
 | 
				
			|||||||
		     job_update_cb, job_complete_cb, job_free_cb, void *, int,
 | 
							     job_update_cb, job_complete_cb, job_free_cb, void *, int,
 | 
				
			||||||
		     int, int);
 | 
							     int, int);
 | 
				
			||||||
void		 job_free(struct job *);
 | 
					void		 job_free(struct job *);
 | 
				
			||||||
 | 
					void		 job_resize(struct job *, u_int, u_int);
 | 
				
			||||||
void		 job_check_died(pid_t, int);
 | 
					void		 job_check_died(pid_t, int);
 | 
				
			||||||
int		 job_get_status(struct job *);
 | 
					int		 job_get_status(struct job *);
 | 
				
			||||||
void		*job_get_data(struct job *);
 | 
					void		*job_get_data(struct job *);
 | 
				
			||||||
@@ -2218,8 +2223,10 @@ void	 server_add_accept(int);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* server-client.c */
 | 
					/* server-client.c */
 | 
				
			||||||
u_int	 server_client_how_many(void);
 | 
					u_int	 server_client_how_many(void);
 | 
				
			||||||
void	 server_client_set_overlay(struct client *, u_int, overlay_draw_cb,
 | 
					void	 server_client_set_overlay(struct client *, u_int, overlay_check_cb,
 | 
				
			||||||
    overlay_key_cb, overlay_free_cb, void *);
 | 
						     overlay_mode_cb, overlay_draw_cb, overlay_key_cb,
 | 
				
			||||||
 | 
						     overlay_free_cb, void *);
 | 
				
			||||||
 | 
					void	 server_client_clear_overlay(struct client *);
 | 
				
			||||||
void	 server_client_set_key_table(struct client *, const char *);
 | 
					void	 server_client_set_key_table(struct client *, const char *);
 | 
				
			||||||
const char *server_client_get_key_table(struct client *);
 | 
					const char *server_client_get_key_table(struct client *);
 | 
				
			||||||
int	 server_client_check_nested(struct client *);
 | 
					int	 server_client_check_nested(struct client *);
 | 
				
			||||||
@@ -2755,6 +2762,15 @@ int		 menu_display(struct menu *, int, struct cmdq_item *, u_int,
 | 
				
			|||||||
		    u_int, struct client *, struct cmd_find_state *,
 | 
							    u_int, struct client *, struct cmd_find_state *,
 | 
				
			||||||
		    menu_choice_cb, void *);
 | 
							    menu_choice_cb, void *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* popup.c */
 | 
				
			||||||
 | 
					#define POPUP_WRITEKEYS 0x1
 | 
				
			||||||
 | 
					#define POPUP_CLOSEEXIT 0x2
 | 
				
			||||||
 | 
					u_int		 popup_width(struct cmdq_item *, u_int, const char **,
 | 
				
			||||||
 | 
							    struct client *, struct cmd_find_state *);
 | 
				
			||||||
 | 
					int		 popup_display(int, struct cmdq_item *, u_int, u_int, u_int,
 | 
				
			||||||
 | 
							    u_int, u_int, const char **, const char *, const char *,
 | 
				
			||||||
 | 
							    const char *, struct client *, struct cmd_find_state *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* style.c */
 | 
					/* style.c */
 | 
				
			||||||
int		 style_parse(struct style *,const struct grid_cell *,
 | 
					int		 style_parse(struct style *,const struct grid_cell *,
 | 
				
			||||||
		     const char *);
 | 
							     const char *);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								tty.c
									
									
									
									
									
								
							@@ -1250,6 +1250,16 @@ tty_check_codeset(struct tty *tty, const struct grid_cell *gc)
 | 
				
			|||||||
	return (&new);
 | 
						return (&new);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					tty_check_overlay(struct tty *tty, u_int px, u_int py)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct client	*c = tty->client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (c->overlay_check == NULL)
 | 
				
			||||||
 | 
							return (1);
 | 
				
			||||||
 | 
						return (c->overlay_check(c, px, py));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
tty_draw_line(struct tty *tty, struct window_pane *wp, struct screen *s,
 | 
					tty_draw_line(struct tty *tty, struct window_pane *wp, struct screen *s,
 | 
				
			||||||
    u_int px, u_int py, u_int nx, u_int atx, u_int aty)
 | 
					    u_int px, u_int py, u_int nx, u_int atx, u_int aty)
 | 
				
			||||||
@@ -1329,7 +1339,8 @@ tty_draw_line(struct tty *tty, struct window_pane *wp, struct screen *s,
 | 
				
			|||||||
		grid_view_get_cell(gd, px + i, py, &gc);
 | 
							grid_view_get_cell(gd, px + i, py, &gc);
 | 
				
			||||||
		gcp = tty_check_codeset(tty, &gc);
 | 
							gcp = tty_check_codeset(tty, &gc);
 | 
				
			||||||
		if (len != 0 &&
 | 
							if (len != 0 &&
 | 
				
			||||||
		    ((gcp->attr & GRID_ATTR_CHARSET) ||
 | 
							    (!tty_check_overlay(tty, atx + ux + width, aty) ||
 | 
				
			||||||
 | 
							    (gcp->attr & GRID_ATTR_CHARSET) ||
 | 
				
			||||||
		    gcp->flags != last.flags ||
 | 
							    gcp->flags != last.flags ||
 | 
				
			||||||
		    gcp->attr != last.attr ||
 | 
							    gcp->attr != last.attr ||
 | 
				
			||||||
		    gcp->fg != last.fg ||
 | 
							    gcp->fg != last.fg ||
 | 
				
			||||||
@@ -1358,7 +1369,9 @@ tty_draw_line(struct tty *tty, struct window_pane *wp, struct screen *s,
 | 
				
			|||||||
			screen_select_cell(s, &last, gcp);
 | 
								screen_select_cell(s, &last, gcp);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			memcpy(&last, gcp, sizeof last);
 | 
								memcpy(&last, gcp, sizeof last);
 | 
				
			||||||
		if (ux + gcp->data.width > nx) {
 | 
							if (!tty_check_overlay(tty, atx + ux, aty))
 | 
				
			||||||
 | 
								ux += gcp->data.width;
 | 
				
			||||||
 | 
							else if (ux + gcp->data.width > nx) {
 | 
				
			||||||
			tty_attributes(tty, &last, wp);
 | 
								tty_attributes(tty, &last, wp);
 | 
				
			||||||
			tty_cursor(tty, atx + ux, aty);
 | 
								tty_cursor(tty, atx + ux, aty);
 | 
				
			||||||
			for (j = 0; j < gcp->data.width; j++) {
 | 
								for (j = 0; j < gcp->data.width; j++) {
 | 
				
			||||||
@@ -1372,7 +1385,7 @@ tty_draw_line(struct tty *tty, struct window_pane *wp, struct screen *s,
 | 
				
			|||||||
			tty_cursor(tty, atx + ux, aty);
 | 
								tty_cursor(tty, atx + ux, aty);
 | 
				
			||||||
			for (j = 0; j < gcp->data.size; j++)
 | 
								for (j = 0; j < gcp->data.size; j++)
 | 
				
			||||||
				tty_putc(tty, gcp->data.data[j]);
 | 
									tty_putc(tty, gcp->data.data[j]);
 | 
				
			||||||
			ux += gc.data.width;
 | 
								ux += gcp->data.width;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			memcpy(buf + len, gcp->data.data, gcp->data.size);
 | 
								memcpy(buf + len, gcp->data.data, gcp->data.size);
 | 
				
			||||||
			len += gcp->data.size;
 | 
								len += gcp->data.size;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user