Annotation of src/usr.bin/tmux/cmd-new-window.c, Revision 1.1
1.1 ! nicm 1: /* $OpenBSD$ */
! 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]",
! 48: 0,
! 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:
! 129: if (arg_parse_window(data->target, &s, &idx) != 0) {
! 130: ctx->error(ctx, "bad window: %s", data->target);
! 131: return (-1);
! 132: }
! 133: if (s == NULL)
! 134: s = ctx->cursession;
! 135: if (s == NULL)
! 136: s = cmd_current_session(ctx);
! 137: if (s == NULL) {
! 138: ctx->error(ctx, "session not found: %s", data->target);
! 139: return (-1);
! 140: }
! 141:
! 142: wl = NULL;
! 143: if (idx != -1)
! 144: wl = winlink_find_by_index(&s->windows, idx);
! 145: if (wl != NULL) {
! 146: if (data->flag_kill) {
! 147: /*
! 148: * Can't use session_detach as it will destroy session
! 149: * if this makes it empty.
! 150: */
! 151: session_alert_cancel(s, wl);
! 152: winlink_stack_remove(&s->lastw, wl);
! 153: winlink_remove(&s->windows, wl);
! 154:
! 155: /* Force select/redraw if current. */
! 156: if (wl == s->curw) {
! 157: data->flag_detached = 0;
! 158: s->curw = NULL;
! 159: }
! 160: }
! 161: }
! 162:
! 163: cmd = data->cmd;
! 164: if (cmd == NULL)
! 165: cmd = options_get_string(&s->options, "default-command");
! 166: if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL)
! 167: cwd = options_get_string(&global_options, "default-path");
! 168: else
! 169: cwd = ctx->cmdclient->cwd;
! 170:
! 171: wl = session_new(s, data->name, cmd, cwd, idx, &cause);
! 172: if (wl == NULL) {
! 173: ctx->error(ctx, "create window failed: %s", cause);
! 174: xfree(cause);
! 175: return (-1);
! 176: }
! 177: if (!data->flag_detached) {
! 178: session_select(s, wl->idx);
! 179: server_redraw_session(s);
! 180: } else
! 181: server_status_session(s);
! 182:
! 183: return (0);
! 184: }
! 185:
! 186: void
! 187: cmd_new_window_send(struct cmd *self, struct buffer *b)
! 188: {
! 189: struct cmd_new_window_data *data = self->data;
! 190:
! 191: buffer_write(b, data, sizeof *data);
! 192: cmd_send_string(b, data->target);
! 193: cmd_send_string(b, data->name);
! 194: cmd_send_string(b, data->cmd);
! 195: }
! 196:
! 197: void
! 198: cmd_new_window_recv(struct cmd *self, struct buffer *b)
! 199: {
! 200: struct cmd_new_window_data *data;
! 201:
! 202: self->data = data = xmalloc(sizeof *data);
! 203: buffer_read(b, data, sizeof *data);
! 204: data->target = cmd_recv_string(b);
! 205: data->name = cmd_recv_string(b);
! 206: data->cmd = cmd_recv_string(b);
! 207: }
! 208:
! 209: void
! 210: cmd_new_window_free(struct cmd *self)
! 211: {
! 212: struct cmd_new_window_data *data = self->data;
! 213:
! 214: if (data->target != NULL)
! 215: xfree(data->target);
! 216: if (data->name != NULL)
! 217: xfree(data->name);
! 218: if (data->cmd != NULL)
! 219: xfree(data->cmd);
! 220: xfree(data);
! 221: }
! 222:
! 223: size_t
! 224: cmd_new_window_print(struct cmd *self, char *buf, size_t len)
! 225: {
! 226: struct cmd_new_window_data *data = self->data;
! 227: size_t off = 0;
! 228:
! 229: off += xsnprintf(buf, len, "%s", self->entry->name);
! 230: if (data == NULL)
! 231: return (off);
! 232: if (off < len && data->flag_detached)
! 233: off += xsnprintf(buf + off, len - off, " -d");
! 234: if (off < len && data->target != NULL)
! 235: off += cmd_prarg(buf + off, len - off, " -t ", data->target);
! 236: if (off < len && data->name != NULL)
! 237: off += cmd_prarg(buf + off, len - off, " -n ", data->name);
! 238: if (off < len && data->cmd != NULL)
! 239: off += cmd_prarg(buf + off, len - off, " ", data->cmd);
! 240: return (off);
! 241: }