Annotation of src/usr.bin/tmux/cmd-new-window.c, Revision 1.4
1.4 ! nicm 1: /* $OpenBSD: cmd-new-window.c,v 1.3 2009/07/13 17:47:46 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2007 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: * Create a new window.
27: */
28:
29: int cmd_new_window_parse(struct cmd *, int, char **, char **);
30: int cmd_new_window_exec(struct cmd *, struct cmd_ctx *);
31: void cmd_new_window_send(struct cmd *, struct buffer *);
32: void cmd_new_window_recv(struct cmd *, struct buffer *);
33: void cmd_new_window_free(struct cmd *);
34: void cmd_new_window_init(struct cmd *, int);
35: size_t cmd_new_window_print(struct cmd *, char *, size_t);
36:
37: struct cmd_new_window_data {
38: char *target;
39: char *name;
40: char *cmd;
41: int flag_detached;
42: int flag_kill;
43: };
44:
45: const struct cmd_entry cmd_new_window_entry = {
46: "new-window", "neww",
47: "[-dk] [-n window-name] [-t target-window] [command]",
1.4 ! nicm 48: 0, 0,
1.1 nicm 49: cmd_new_window_init,
50: cmd_new_window_parse,
51: cmd_new_window_exec,
52: cmd_new_window_send,
53: cmd_new_window_recv,
54: cmd_new_window_free,
55: cmd_new_window_print
56: };
57:
58: void
59: cmd_new_window_init(struct cmd *self, unused int arg)
60: {
61: struct cmd_new_window_data *data;
62:
63: self->data = data = xmalloc(sizeof *data);
64: data->target = NULL;
65: data->name = NULL;
66: data->cmd = NULL;
67: data->flag_detached = 0;
68: data->flag_kill = 0;
69: }
70:
71: int
72: cmd_new_window_parse(struct cmd *self, int argc, char **argv, char **cause)
73: {
74: struct cmd_new_window_data *data;
75: int opt;
76:
77: self->entry->init(self, 0);
78: data = self->data;
79:
80: while ((opt = getopt(argc, argv, "dkt:n:")) != -1) {
81: switch (opt) {
82: case 'd':
83: data->flag_detached = 1;
84: break;
85: case 'k':
86: data->flag_kill = 1;
87: break;
88: case 't':
89: if (data->target == NULL)
90: data->target = xstrdup(optarg);
91: break;
92: case 'n':
93: if (data->name == NULL)
94: data->name = xstrdup(optarg);
95: break;
96: default:
97: goto usage;
98: }
99: }
100: argc -= optind;
101: argv += optind;
102: if (argc != 0 && argc != 1)
103: goto usage;
104:
105: if (argc == 1)
106: data->cmd = xstrdup(argv[0]);
107:
108: return (0);
109:
110: usage:
111: xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
112:
113: self->entry->free(self);
114: return (-1);
115: }
116:
117: int
118: cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
119: {
120: struct cmd_new_window_data *data = self->data;
121: struct session *s;
122: struct winlink *wl;
123: char *cmd, *cwd, *cause;
124: int idx;
125:
126: if (data == NULL)
127: return (0);
128:
1.3 nicm 129: if ((idx = cmd_find_index(ctx, data->target, &s)) == -2)
1.1 nicm 130: return (-1);
131:
132: wl = NULL;
133: if (idx != -1)
134: wl = winlink_find_by_index(&s->windows, idx);
135: if (wl != NULL) {
136: if (data->flag_kill) {
137: /*
138: * Can't use session_detach as it will destroy session
139: * if this makes it empty.
140: */
141: session_alert_cancel(s, wl);
142: winlink_stack_remove(&s->lastw, wl);
143: winlink_remove(&s->windows, wl);
144:
145: /* Force select/redraw if current. */
146: if (wl == s->curw) {
147: data->flag_detached = 0;
148: s->curw = NULL;
149: }
150: }
151: }
152:
153: cmd = data->cmd;
154: if (cmd == NULL)
155: cmd = options_get_string(&s->options, "default-command");
156: if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL)
1.2 nicm 157: cwd = options_get_string(&s->options, "default-path");
1.1 nicm 158: else
159: cwd = ctx->cmdclient->cwd;
160:
161: wl = session_new(s, data->name, cmd, cwd, idx, &cause);
162: if (wl == NULL) {
163: ctx->error(ctx, "create window failed: %s", cause);
164: xfree(cause);
165: return (-1);
166: }
167: if (!data->flag_detached) {
168: session_select(s, wl->idx);
169: server_redraw_session(s);
170: } else
171: server_status_session(s);
172:
173: return (0);
174: }
175:
176: void
177: cmd_new_window_send(struct cmd *self, struct buffer *b)
178: {
179: struct cmd_new_window_data *data = self->data;
180:
181: buffer_write(b, data, sizeof *data);
182: cmd_send_string(b, data->target);
183: cmd_send_string(b, data->name);
184: cmd_send_string(b, data->cmd);
185: }
186:
187: void
188: cmd_new_window_recv(struct cmd *self, struct buffer *b)
189: {
190: struct cmd_new_window_data *data;
191:
192: self->data = data = xmalloc(sizeof *data);
193: buffer_read(b, data, sizeof *data);
194: data->target = cmd_recv_string(b);
195: data->name = cmd_recv_string(b);
196: data->cmd = cmd_recv_string(b);
197: }
198:
199: void
200: cmd_new_window_free(struct cmd *self)
201: {
202: struct cmd_new_window_data *data = self->data;
203:
204: if (data->target != NULL)
205: xfree(data->target);
206: if (data->name != NULL)
207: xfree(data->name);
208: if (data->cmd != NULL)
209: xfree(data->cmd);
210: xfree(data);
211: }
212:
213: size_t
214: cmd_new_window_print(struct cmd *self, char *buf, size_t len)
215: {
216: struct cmd_new_window_data *data = self->data;
217: size_t off = 0;
218:
219: off += xsnprintf(buf, len, "%s", self->entry->name);
220: if (data == NULL)
221: return (off);
222: if (off < len && data->flag_detached)
223: off += xsnprintf(buf + off, len - off, " -d");
224: if (off < len && data->target != NULL)
225: off += cmd_prarg(buf + off, len - off, " -t ", data->target);
226: if (off < len && data->name != NULL)
227: off += cmd_prarg(buf + off, len - off, " -n ", data->name);
228: if (off < len && data->cmd != NULL)
229: off += cmd_prarg(buf + off, len - off, " ", data->cmd);
230: return (off);
231: }