xref: /openbsd-src/usr.bin/tmux/cmd-resize-pane.c (revision 48950c12d106c85f315112191a0228d7b83b9510)
1 /* $OpenBSD: cmd-resize-pane.c,v 1.15 2013/03/24 09:57:59 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_q *);
31 
32 const struct cmd_entry cmd_resize_pane_entry = {
33 	"resize-pane", "resizep",
34 	"DLRt:Ux:y:Z", 0, 1,
35 	"[-DLRUZ] [-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 	case 'z':
79 		self->args = args_create(0);
80 		args_set(self->args, 'Z', NULL);
81 		break;
82 	default:
83 		self->args = args_create(0);
84 		break;
85 	}
86 }
87 
88 enum cmd_retval
89 cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
90 {
91 	struct args		*args = self->args;
92 	struct winlink		*wl;
93 	struct window		*w;
94 	const char	       	*errstr;
95 	char			*cause;
96 	struct window_pane	*wp;
97 	u_int			 adjust;
98 	int			 x, y;
99 
100 	if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
101 		return (CMD_RETURN_ERROR);
102 	w = wl->window;
103 
104 	if (args_has(args, 'Z')) {
105 		if (w->flags & WINDOW_ZOOMED)
106 			window_unzoom(w);
107 		else
108 			window_zoom(wp);
109 		server_redraw_window(w);
110 		server_status_window(w);
111 		return (CMD_RETURN_NORMAL);
112 	}
113 	server_unzoom_window(w);
114 
115 	if (args->argc == 0)
116 		adjust = 1;
117 	else {
118 		adjust = strtonum(args->argv[0], 1, INT_MAX, &errstr);
119 		if (errstr != NULL) {
120 			cmdq_error(cmdq, "adjustment %s", errstr);
121 			return (CMD_RETURN_ERROR);
122 		}
123 	}
124 
125 	if (args_has(self->args, 'x')) {
126 		x = args_strtonum(self->args, 'x', PANE_MINIMUM, INT_MAX,
127 		    &cause);
128 		if (cause != NULL) {
129 			cmdq_error(cmdq, "width %s", cause);
130 			free(cause);
131 			return (CMD_RETURN_ERROR);
132 		}
133 		layout_resize_pane_to(wp, LAYOUT_LEFTRIGHT, x);
134 	}
135 	if (args_has(self->args, 'y')) {
136 		y = args_strtonum(self->args, 'y', PANE_MINIMUM, INT_MAX,
137 		    &cause);
138 		if (cause != NULL) {
139 			cmdq_error(cmdq, "height %s", cause);
140 			free(cause);
141 			return (CMD_RETURN_ERROR);
142 		}
143 		layout_resize_pane_to(wp, LAYOUT_TOPBOTTOM, y);
144 	}
145 
146 	if (args_has(self->args, 'L'))
147 		layout_resize_pane(wp, LAYOUT_LEFTRIGHT, -adjust);
148 	else if (args_has(self->args, 'R'))
149 		layout_resize_pane(wp, LAYOUT_LEFTRIGHT, adjust);
150 	else if (args_has(self->args, 'U'))
151 		layout_resize_pane(wp, LAYOUT_TOPBOTTOM, -adjust);
152 	else if (args_has(self->args, 'D'))
153 		layout_resize_pane(wp, LAYOUT_TOPBOTTOM, adjust);
154 	server_redraw_window(wl->window);
155 
156 	return (CMD_RETURN_NORMAL);
157 }
158