xref: /openbsd/usr.bin/tmux/cmd-send-keys.c (revision 17df1aa7)
1 /* $OpenBSD: cmd-send-keys.c,v 1.7 2009/12/03 22:50:10 nicm Exp $ */
2 
3 /*
4  * Copyright (c) 2008 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  * Send keys to client.
27  */
28 
29 int	cmd_send_keys_parse(struct cmd *, int, char **, char **);
30 int	cmd_send_keys_exec(struct cmd *, struct cmd_ctx *);
31 void	cmd_send_keys_free(struct cmd *);
32 size_t	cmd_send_keys_print(struct cmd *, char *, size_t);
33 
34 struct cmd_send_keys_data {
35 	char	*target;
36 	u_int	 nkeys;
37 	int	*keys;
38 };
39 
40 const struct cmd_entry cmd_send_keys_entry = {
41 	"send-keys", "send",
42 	"[-t target-pane] key ...",
43 	0, "",
44 	NULL,
45 	cmd_send_keys_parse,
46 	cmd_send_keys_exec,
47 	cmd_send_keys_free,
48 	cmd_send_keys_print
49 };
50 
51 int
52 cmd_send_keys_parse(struct cmd *self, int argc, char **argv, char **cause)
53 {
54 	struct cmd_send_keys_data	*data;
55 	int				 opt, key;
56 	char				*s;
57 
58 	self->data = data = xmalloc(sizeof *data);
59 	data->target = NULL;
60 	data->nkeys = 0;
61 	data->keys = NULL;
62 
63 	while ((opt = getopt(argc, argv, "t:")) != -1) {
64 		switch (opt) {
65 		case 't':
66 			if (data->target == NULL)
67 				data->target = xstrdup(optarg);
68 			break;
69 		default:
70 			goto usage;
71 		}
72 	}
73 	argc -= optind;
74 	argv += optind;
75 	if (argc == 0)
76 		goto usage;
77 
78 	while (argc-- != 0) {
79 		if ((key = key_string_lookup_string(*argv)) != KEYC_NONE) {
80 			data->keys = xrealloc(
81 			    data->keys, data->nkeys + 1, sizeof *data->keys);
82 			data->keys[data->nkeys++] = key;
83 		} else {
84 			for (s = *argv; *s != '\0'; s++) {
85 				data->keys = xrealloc(data->keys,
86 				    data->nkeys + 1, sizeof *data->keys);
87 				data->keys[data->nkeys++] = *s;
88 			}
89 		}
90 
91 		argv++;
92 	}
93 
94 	return (0);
95 
96 usage:
97 	xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
98 
99 	self->entry->free(self);
100 	return (-1);
101 }
102 
103 int
104 cmd_send_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
105 {
106 	struct cmd_send_keys_data	*data = self->data;
107 	struct window_pane		*wp;
108 	u_int				 i;
109 
110 	if (data == NULL)
111 		return (-1);
112 
113 	if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
114 		return (-1);
115 
116 	for (i = 0; i < data->nkeys; i++)
117 		window_pane_key(wp, ctx->curclient, data->keys[i]);
118 
119 	return (0);
120 }
121 
122 void
123 cmd_send_keys_free(struct cmd *self)
124 {
125 	struct cmd_send_keys_data	*data = self->data;
126 
127 	if (data->target != NULL)
128 		xfree(data->target);
129 	xfree(data);
130 }
131 
132 size_t
133 cmd_send_keys_print(struct cmd *self, char *buf, size_t len)
134 {
135 	struct cmd_send_keys_data	*data = self->data;
136 	size_t				 off = 0;
137 	u_int				 i;
138 
139 	off += xsnprintf(buf, len, "%s", self->entry->name);
140 	if (data == NULL)
141 		return (off);
142 	if (off < len && data->target != NULL)
143 		off += cmd_prarg(buf + off, len - off, " -t ", data->target);
144 
145 	for (i = 0; i < data->nkeys; i++) {
146 		if (off >= len)
147 			break;
148 		off += xsnprintf(buf + off,
149 		    len - off, " %s", key_string_lookup_key(data->keys[i]));
150 	}
151 	return (off);
152 }
153