4 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
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.
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.
19 #include <sys/types.h>
30 int cmd_set_option_exec(struct cmd
*, struct cmd_ctx
*);
32 int cmd_set_option_unset(struct cmd
*, struct cmd_ctx
*,
33 const struct options_table_entry
*, struct options
*,
35 int cmd_set_option_set(struct cmd
*, struct cmd_ctx
*,
36 const struct options_table_entry
*, struct options
*,
39 struct options_entry
*cmd_set_option_string(struct cmd
*, struct cmd_ctx
*,
40 const struct options_table_entry
*, struct options
*,
42 struct options_entry
*cmd_set_option_number(struct cmd
*, struct cmd_ctx
*,
43 const struct options_table_entry
*, struct options
*,
45 struct options_entry
*cmd_set_option_key(struct cmd
*, struct cmd_ctx
*,
46 const struct options_table_entry
*, struct options
*,
48 struct options_entry
*cmd_set_option_colour(struct cmd
*, struct cmd_ctx
*,
49 const struct options_table_entry
*, struct options
*,
51 struct options_entry
*cmd_set_option_attributes(struct cmd
*, struct cmd_ctx
*,
52 const struct options_table_entry
*, struct options
*,
54 struct options_entry
*cmd_set_option_flag(struct cmd
*, struct cmd_ctx
*,
55 const struct options_table_entry
*, struct options
*,
57 struct options_entry
*cmd_set_option_choice(struct cmd
*, struct cmd_ctx
*,
58 const struct options_table_entry
*, struct options
*,
61 const struct cmd_entry cmd_set_option_entry
= {
64 "[-agsquw] [-t target-session|target-window] option [value]",
71 const struct cmd_entry cmd_set_window_option_entry
= {
72 "set-window-option", "setw",
74 "[-agqu] " CMD_TARGET_WINDOW_USAGE
" option [value]",
82 cmd_set_option_exec(struct cmd
*self
, struct cmd_ctx
*ctx
)
84 struct args
*args
= self
->args
;
85 const struct options_table_entry
*table
, *oe
;
91 const char *optstr
, *valstr
;
94 /* Get the option name and value. */
95 optstr
= args
->argv
[0];
96 if (*optstr
== '\0') {
97 ctx
->error(ctx
, "invalid option");
103 valstr
= args
->argv
[1];
105 /* Find the option entry, try each table. */
107 if (options_table_find(optstr
, &table
, &oe
) != 0) {
108 ctx
->error(ctx
, "ambiguous option: %s", optstr
);
112 ctx
->error(ctx
, "unknown option: %s", optstr
);
116 /* Work out the tree from the table. */
117 if (table
== server_options_table
)
118 oo
= &global_options
;
119 else if (table
== window_options_table
) {
120 if (args_has(self
->args
, 'g'))
121 oo
= &global_w_options
;
123 wl
= cmd_find_window(ctx
, args_get(args
, 't'), NULL
);
126 oo
= &wl
->window
->options
;
128 } else if (table
== session_options_table
) {
129 if (args_has(self
->args
, 'g'))
130 oo
= &global_s_options
;
132 s
= cmd_find_session(ctx
, args_get(args
, 't'), 0);
138 ctx
->error(ctx
, "unknown table");
142 /* Unset or set the option. */
143 if (args_has(args
, 'u')) {
144 if (cmd_set_option_unset(self
, ctx
, oe
, oo
, valstr
) != 0)
147 if (cmd_set_option_set(self
, ctx
, oe
, oo
, valstr
) != 0)
151 /* Start or stop timers when automatic-rename changed. */
152 if (strcmp (oe
->name
, "automatic-rename") == 0) {
153 for (i
= 0; i
< ARRAY_LENGTH(&windows
); i
++) {
154 if ((w
= ARRAY_ITEM(&windows
, i
)) == NULL
)
156 if (options_get_number(&w
->options
, "automatic-rename"))
157 queue_window_name(w
);
158 else if (event_initialized(&w
->name_timer
))
159 evtimer_del(&w
->name_timer
);
163 /* Update sizes and redraw. May not need it but meh. */
165 for (i
= 0; i
< ARRAY_LENGTH(&clients
); i
++) {
166 c
= ARRAY_ITEM(&clients
, i
);
167 if (c
!= NULL
&& c
->session
!= NULL
)
168 server_redraw_client(c
);
174 /* Unset an option. */
176 cmd_set_option_unset(struct cmd
*self
, struct cmd_ctx
*ctx
,
177 const struct options_table_entry
*oe
, struct options
*oo
, const char *value
)
179 struct args
*args
= self
->args
;
181 if (args_has(args
, 'g')) {
182 ctx
->error(ctx
, "can't unset global option: %s", oe
->name
);
186 ctx
->error(ctx
, "value passed to unset option: %s", oe
->name
);
190 options_remove(oo
, oe
->name
);
191 if (!args_has(args
, 'q'))
192 ctx
->info(ctx
, "unset option: %s", oe
->name
);
198 cmd_set_option_set(struct cmd
*self
, struct cmd_ctx
*ctx
,
199 const struct options_table_entry
*oe
, struct options
*oo
, const char *value
)
201 struct args
*args
= self
->args
;
202 struct options_entry
*o
;
205 if (oe
->type
!= OPTIONS_TABLE_FLAG
&& value
== NULL
) {
206 ctx
->error(ctx
, "empty value");
212 case OPTIONS_TABLE_STRING
:
213 o
= cmd_set_option_string(self
, ctx
, oe
, oo
, value
);
215 case OPTIONS_TABLE_NUMBER
:
216 o
= cmd_set_option_number(self
, ctx
, oe
, oo
, value
);
218 case OPTIONS_TABLE_KEY
:
219 o
= cmd_set_option_key(self
, ctx
, oe
, oo
, value
);
221 case OPTIONS_TABLE_COLOUR
:
222 o
= cmd_set_option_colour(self
, ctx
, oe
, oo
, value
);
224 case OPTIONS_TABLE_ATTRIBUTES
:
225 o
= cmd_set_option_attributes(self
, ctx
, oe
, oo
, value
);
227 case OPTIONS_TABLE_FLAG
:
228 o
= cmd_set_option_flag(self
, ctx
, oe
, oo
, value
);
230 case OPTIONS_TABLE_CHOICE
:
231 o
= cmd_set_option_choice(self
, ctx
, oe
, oo
, value
);
237 s
= options_table_print_entry(oe
, o
);
238 if (!args_has(args
, 'q'))
239 ctx
->info(ctx
, "set option: %s -> %s", oe
->name
, s
);
243 /* Set a string option. */
244 struct options_entry
*
245 cmd_set_option_string(struct cmd
*self
, unused
struct cmd_ctx
*ctx
,
246 const struct options_table_entry
*oe
, struct options
*oo
, const char *value
)
248 struct args
*args
= self
->args
;
249 struct options_entry
*o
;
250 char *oldval
, *newval
;
252 if (args_has(args
, 'a')) {
253 oldval
= options_get_string(oo
, oe
->name
);
254 xasprintf(&newval
, "%s%s", oldval
, value
);
256 newval
= xstrdup(value
);
258 o
= options_set_string(oo
, oe
->name
, "%s", newval
);
264 /* Set a number option. */
265 struct options_entry
*
266 cmd_set_option_number(unused
struct cmd
*self
, struct cmd_ctx
*ctx
,
267 const struct options_table_entry
*oe
, struct options
*oo
, const char *value
)
272 ll
= strtonum(value
, oe
->minimum
, oe
->maximum
, &errstr
);
273 if (errstr
!= NULL
) {
274 ctx
->error(ctx
, "value is %s: %s", errstr
, value
);
278 return (options_set_number(oo
, oe
->name
, ll
));
281 /* Set a key option. */
282 struct options_entry
*
283 cmd_set_option_key(unused
struct cmd
*self
, struct cmd_ctx
*ctx
,
284 const struct options_table_entry
*oe
, struct options
*oo
, const char *value
)
288 if ((key
= key_string_lookup_string(value
)) == KEYC_NONE
) {
289 ctx
->error(ctx
, "bad key: %s", value
);
293 return (options_set_number(oo
, oe
->name
, key
));
296 /* Set a colour option. */
297 struct options_entry
*
298 cmd_set_option_colour(unused
struct cmd
*self
, struct cmd_ctx
*ctx
,
299 const struct options_table_entry
*oe
, struct options
*oo
, const char *value
)
303 if ((colour
= colour_fromstring(value
)) == -1) {
304 ctx
->error(ctx
, "bad colour: %s", value
);
308 return (options_set_number(oo
, oe
->name
, colour
));
311 /* Set an attributes option. */
312 struct options_entry
*
313 cmd_set_option_attributes(unused
struct cmd
*self
, struct cmd_ctx
*ctx
,
314 const struct options_table_entry
*oe
, struct options
*oo
, const char *value
)
318 if ((attr
= attributes_fromstring(value
)) == -1) {
319 ctx
->error(ctx
, "bad attributes: %s", value
);
323 return (options_set_number(oo
, oe
->name
, attr
));
326 /* Set a flag option. */
327 struct options_entry
*
328 cmd_set_option_flag(unused
struct cmd
*self
, struct cmd_ctx
*ctx
,
329 const struct options_table_entry
*oe
, struct options
*oo
, const char *value
)
333 if (value
== NULL
|| *value
== '\0')
334 flag
= !options_get_number(oo
, oe
->name
);
336 if ((value
[0] == '1' && value
[1] == '\0') ||
337 strcasecmp(value
, "on") == 0 ||
338 strcasecmp(value
, "yes") == 0)
340 else if ((value
[0] == '0' && value
[1] == '\0') ||
341 strcasecmp(value
, "off") == 0 ||
342 strcasecmp(value
, "no") == 0)
345 ctx
->error(ctx
, "bad value: %s", value
);
350 return (options_set_number(oo
, oe
->name
, flag
));
353 /* Set a choice option. */
354 struct options_entry
*
355 cmd_set_option_choice(unused
struct cmd
*self
, struct cmd_ctx
*ctx
,
356 const struct options_table_entry
*oe
, struct options
*oo
, const char *value
)
358 const char **choicep
;
362 for (choicep
= oe
->choices
; *choicep
!= NULL
; choicep
++) {
364 if (strncmp(*choicep
, value
, strlen(value
)) != 0)
368 ctx
->error(ctx
, "ambiguous value: %s", value
);
374 ctx
->error(ctx
, "unknown value: %s", value
);
378 return (options_set_number(oo
, oe
->name
, choice
));