1 /* $Id: cmd-capture-pane.c,v 1.1.1.2 2011/08/17 18:40:04 jmmv Exp $ */
2 
3 /*
4  * Copyright (c) 2009 Jonathan Alvarado <radobobo@users.sourceforge.net>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "tmux.h"
25 
26 /*
27  * Write the entire contents of a pane to a buffer.
28  */
29 
30 int	cmd_capture_pane_exec(struct cmd *, struct cmd_ctx *);
31 
32 const struct cmd_entry cmd_capture_pane_entry = {
33 	"capture-pane", "capturep",
34 	"b:E:S:t:", 0, 0,
35 	"[-b buffer-index] [-E end-line] [-S start-line] [-t target-pane]",
36 	0,
37 	NULL,
38 	NULL,
39 	cmd_capture_pane_exec
40 };
41 
42 int
43 cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
44 {
45 	struct args		*args = self->args;
46 	struct window_pane	*wp;
47 	char 			*buf, *line, *cause;
48 	struct screen		*s;
49 	struct grid		*gd;
50 	int			 buffer, n;
51 	u_int			 i, limit, top, bottom, tmp;
52 	size_t         		 len, linelen;
53 
54 	if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL)
55 		return (-1);
56 	s = &wp->base;
57 	gd = s->grid;
58 
59 	buf = NULL;
60 	len = 0;
61 
62 	n = args_strtonum(args, 'S', SHRT_MIN, SHRT_MAX, &cause);
63 	if (cause != NULL) {
64 		top = gd->hsize;
65 		xfree(cause);
66 	} else if (n < 0 && (u_int) -n > gd->hsize)
67 		top = 0;
68 	else
69 		top = gd->hsize + n;
70 	if (top > gd->hsize + gd->sy - 1)
71 		top = gd->hsize + gd->sy - 1;
72 
73 	n = args_strtonum(args, 'E', SHRT_MIN, SHRT_MAX, &cause);
74 	if (cause != NULL) {
75 		bottom = gd->hsize + gd->sy - 1;
76 		xfree(cause);
77 	} else if (n < 0 && (u_int) -n > gd->hsize)
78 		bottom = 0;
79 	else
80 		bottom = gd->hsize + n;
81 	if (bottom > gd->hsize + gd->sy - 1)
82 		bottom = gd->hsize + gd->sy - 1;
83 
84 	if (bottom < top) {
85 		tmp = bottom;
86 		bottom = top;
87 		top = tmp;
88 	}
89 
90 	for (i = top; i <= bottom; i++) {
91 	       line = grid_string_cells(s->grid, 0, i, screen_size_x(s));
92 	       linelen = strlen(line);
93 
94 	       buf = xrealloc(buf, 1, len + linelen + 1);
95 	       memcpy(buf + len, line, linelen);
96 	       len += linelen;
97 	       buf[len++] = '\n';
98 
99 	       xfree(line);
100 	}
101 
102 	limit = options_get_number(&global_options, "buffer-limit");
103 
104 	if (!args_has(args, 'b')) {
105 		paste_add(&global_buffers, buf, len, limit);
106 		return (0);
107 	}
108 
109 	buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
110 	if (cause != NULL) {
111 		ctx->error(ctx, "buffer %s", cause);
112 		xfree(cause);
113 		return (-1);
114 	}
115 
116 	if (paste_replace(&global_buffers, buffer, buf, len) != 0) {
117 		ctx->error(ctx, "no buffer %d", buffer);
118 		xfree(buf);
119 		return (-1);
120 	}
121 
122 	return (0);
123 }
124