xref: /openbsd-src/usr.bin/tmux/cmd-resize-pane.c (revision 3cfcdd3623f61b7a1113a4502de4bf664bcc0586)
1 /* $OpenBSD: cmd-resize-pane.c,v 1.13 2013/03/22 10:37:39 nicm Exp $ */
2 
3 /*
4  * Copyright (c) 2009 Nicholas Marriott <nicm@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 
23 #include "tmux.h"
24 
25 /*
26  * Increase or decrease pane size.
27  */
28 
29 void		 cmd_resize_pane_key_binding(struct cmd *, int);
30 enum cmd_retval	 cmd_resize_pane_exec(struct cmd *, struct cmd_ctx *);
31 
32 const struct cmd_entry cmd_resize_pane_entry = {
33 	"resize-pane", "resizep",
34 	"DLRt:Ux:y:", 0, 1,
35 	"[-DLRU] [-x width] [-y height] " CMD_TARGET_PANE_USAGE " [adjustment]",
36 	0,
37 	cmd_resize_pane_key_binding,
38 	NULL,
39 	cmd_resize_pane_exec
40 };
41 
42 void
43 cmd_resize_pane_key_binding(struct cmd *self, int key)
44 {
45 	switch (key) {
46 	case KEYC_UP | KEYC_CTRL:
47 		self->args = args_create(0);
48 		args_set(self->args, 'U', NULL);
49 		break;
50 	case KEYC_DOWN | KEYC_CTRL:
51 		self->args = args_create(0);
52 		args_set(self->args, 'D', NULL);
53 		break;
54 	case KEYC_LEFT | KEYC_CTRL:
55 		self->args = args_create(0);
56 		args_set(self->args, 'L', NULL);
57 		break;
58 	case KEYC_RIGHT | KEYC_CTRL:
59 		self->args = args_create(0);
60 		args_set(self->args, 'R', NULL);
61 		break;
62 	case KEYC_UP | KEYC_ESCAPE:
63 		self->args = args_create(1, "5");
64 		args_set(self->args, 'U', NULL);
65 		break;
66 	case KEYC_DOWN | KEYC_ESCAPE:
67 		self->args = args_create(1, "5");
68 		args_set(self->args, 'D', NULL);
69 		break;
70 	case KEYC_LEFT | KEYC_ESCAPE:
71 		self->args = args_create(1, "5");
72 		args_set(self->args, 'L', NULL);
73 		break;
74 	case KEYC_RIGHT | KEYC_ESCAPE:
75 		self->args = args_create(1, "5");
76 		args_set(self->args, 'R', NULL);
77 		break;
78 	default:
79 		self->args = args_create(0);
80 		break;
81 	}
82 }
83 
84 enum cmd_retval
85 cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
86 {
87 	struct args		*args = self->args;
88 	struct winlink		*wl;
89 	const char	       	*errstr;
90 	char			*cause;
91 	struct window_pane	*wp;
92 	u_int			 adjust;
93 	int			 x, y;
94 
95 	if ((wl = cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp)) == NULL)
96 		return (CMD_RETURN_ERROR);
97 
98 	if (args->argc == 0)
99 		adjust = 1;
100 	else {
101 		adjust = strtonum(args->argv[0], 1, INT_MAX, &errstr);
102 		if (errstr != NULL) {
103 			ctx->error(ctx, "adjustment %s", errstr);
104 			return (CMD_RETURN_ERROR);
105 		}
106 	}
107 
108 	if (args_has(self->args, 'x')) {
109 		x = args_strtonum(self->args, 'x', PANE_MINIMUM, INT_MAX,
110 		    &cause);
111 		if (cause != NULL) {
112 			ctx->error(ctx, "width %s", cause);
113 			free(cause);
114 			return (CMD_RETURN_ERROR);
115 		}
116 		layout_resize_pane_to(wp, LAYOUT_LEFTRIGHT, x);
117 	}
118 	if (args_has(self->args, 'y')) {
119 		y = args_strtonum(self->args, 'y', PANE_MINIMUM, INT_MAX,
120 		    &cause);
121 		if (cause != NULL) {
122 			ctx->error(ctx, "height %s", cause);
123 			free(cause);
124 			return (CMD_RETURN_ERROR);
125 		}
126 		layout_resize_pane_to(wp, LAYOUT_TOPBOTTOM, y);
127 	}
128 
129 	if (args_has(self->args, 'L'))
130 		layout_resize_pane(wp, LAYOUT_LEFTRIGHT, -adjust);
131 	else if (args_has(self->args, 'R'))
132 		layout_resize_pane(wp, LAYOUT_LEFTRIGHT, adjust);
133 	else if (args_has(self->args, 'U'))
134 		layout_resize_pane(wp, LAYOUT_TOPBOTTOM, -adjust);
135 	else if (args_has(self->args, 'D'))
136 		layout_resize_pane(wp, LAYOUT_TOPBOTTOM, adjust);
137 	server_redraw_window(wl->window);
138 
139 	return (CMD_RETURN_NORMAL);
140 }
141