aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-06-02 21:33:16 -0400
committerLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-06-03 10:26:06 -0400
commit5ea4a4d3eec897b915003ad7fc2b2e274d1a59c1 (patch)
tree8d077f70c7bc462f1987e8d57003a2b11de718ca
parentMerge pull request #2093 from emersion/damage-debug (diff)
downloadsway-5ea4a4d3eec897b915003ad7fc2b2e274d1a59c1.tar.gz
sway-5ea4a4d3eec897b915003ad7fc2b2e274d1a59c1.tar.zst
sway-5ea4a4d3eec897b915003ad7fc2b2e274d1a59c1.zip
Refactor cmd_output to use config_subcommand
-rw-r--r--include/sway/commands.h9
-rw-r--r--include/sway/config.h5
-rw-r--r--sway/commands/output.c296
-rw-r--r--sway/commands/output/background.c105
-rw-r--r--sway/commands/output/disable.c13
-rw-r--r--sway/commands/output/dpms.c24
-rw-r--r--sway/commands/output/enable.c14
-rw-r--r--sway/commands/output/mode.c55
-rw-r--r--sway/commands/output/position.c46
-rw-r--r--sway/commands/output/scale.c23
-rw-r--r--sway/commands/output/transform.c39
-rw-r--r--sway/meson.build9
12 files changed, 371 insertions, 267 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h
index 593ae0f1..7ca0bda8 100644
--- a/include/sway/commands.h
+++ b/include/sway/commands.h
@@ -216,6 +216,15 @@ sway_cmd input_cmd_xkb_options;
216sway_cmd input_cmd_xkb_rules; 216sway_cmd input_cmd_xkb_rules;
217sway_cmd input_cmd_xkb_variant; 217sway_cmd input_cmd_xkb_variant;
218 218
219sway_cmd output_cmd_background;
220sway_cmd output_cmd_disable;
221sway_cmd output_cmd_dpms;
222sway_cmd output_cmd_enable;
223sway_cmd output_cmd_mode;
224sway_cmd output_cmd_position;
225sway_cmd output_cmd_scale;
226sway_cmd output_cmd_transform;
227
219sway_cmd seat_cmd_attach; 228sway_cmd seat_cmd_attach;
220sway_cmd seat_cmd_fallback; 229sway_cmd seat_cmd_fallback;
221sway_cmd seat_cmd_cursor; 230sway_cmd seat_cmd_cursor;
diff --git a/include/sway/config.h b/include/sway/config.h
index b597da75..81e9c382 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -372,10 +372,15 @@ struct sway_config {
372 // Context for command handlers 372 // Context for command handlers
373 struct { 373 struct {
374 struct input_config *input_config; 374 struct input_config *input_config;
375 struct output_config *output_config;
375 struct seat_config *seat_config; 376 struct seat_config *seat_config;
376 struct sway_seat *seat; 377 struct sway_seat *seat;
377 struct sway_container *current_container; 378 struct sway_container *current_container;
378 bool using_criteria; 379 bool using_criteria;
380 struct {
381 int argc;
382 char **argv;
383 } leftovers;
379 } handler_context; 384 } handler_context;
380}; 385};
381 386
diff --git a/sway/commands/output.c b/sway/commands/output.c
index e8881f77..a7d325ec 100644
--- a/sway/commands/output.c
+++ b/sway/commands/output.c
@@ -1,254 +1,24 @@
1#define _XOPEN_SOURCE 500
2#include <ctype.h>
3#include <libgen.h>
4#include <stdlib.h>
5#include <string.h>
6#include <strings.h>
7#include <unistd.h>
8#include <wordexp.h>
9#include "sway/commands.h" 1#include "sway/commands.h"
10#include "sway/config.h" 2#include "sway/config.h"
11#include "list.h" 3#include "list.h"
12#include "log.h" 4#include "log.h"
13#include "stringop.h"
14 5
15static char *bg_options[] = { 6// must be in order for the bsearch
16 "stretch", 7static struct cmd_handler output_handlers[] = {
17 "center", 8 { "background", output_cmd_background },
18 "fill", 9 { "bg", output_cmd_background },
19 "fit", 10 { "disable", output_cmd_disable },
20 "tile", 11 { "dpms", output_cmd_dpms },
12 { "enable", output_cmd_enable },
13 { "mode", output_cmd_mode },
14 { "pos", output_cmd_position },
15 { "position", output_cmd_position },
16 { "res", output_cmd_mode },
17 { "resolution", output_cmd_mode },
18 { "scale", output_cmd_scale },
19 { "transform", output_cmd_transform },
21}; 20};
22 21
23static struct cmd_results *cmd_output_dpms(struct output_config *output,
24 int *i, int argc, char **argv) {
25
26 if (++*i >= argc) {
27 return cmd_results_new(CMD_INVALID, "output", "Missing dpms argument.");
28 }
29
30 char *value = argv[*i];
31 if (strcmp(value, "on") == 0) {
32 output->dpms_state = DPMS_ON;
33 } else if (strcmp(value, "off") == 0) {
34 output->dpms_state = DPMS_OFF;
35 } else {
36 return cmd_results_new(CMD_INVALID, "output",
37 "Invalid dpms state, valid states are on/off.");
38 }
39 return NULL;
40}
41
42static struct cmd_results *cmd_output_mode(struct output_config *output,
43 int *i, int argc, char **argv) {
44 if (++*i >= argc) {
45 return cmd_results_new(CMD_INVALID, "output", "Missing mode argument.");
46 }
47
48 char *end;
49 output->width = strtol(argv[*i], &end, 10);
50 if (*end) {
51 // Format is 1234x4321
52 if (*end != 'x') {
53 return cmd_results_new(CMD_INVALID, "output",
54 "Invalid mode width.");
55 }
56 ++end;
57 output->height = strtol(end, &end, 10);
58 if (*end) {
59 if (*end != '@') {
60 return cmd_results_new(CMD_INVALID, "output",
61 "Invalid mode height.");
62 }
63 ++end;
64 output->refresh_rate = strtof(end, &end);
65 if (strcasecmp("Hz", end) != 0) {
66 return cmd_results_new(CMD_INVALID, "output",
67 "Invalid mode refresh rate.");
68 }
69 }
70 } else {
71 // Format is 1234 4321
72 if (++*i >= argc) {
73 return cmd_results_new(CMD_INVALID, "output",
74 "Missing mode argument (height).");
75 }
76 output->height = strtol(argv[*i], &end, 10);
77 if (*end) {
78 return cmd_results_new(CMD_INVALID, "output",
79 "Invalid mode height.");
80 }
81 }
82
83 return NULL;
84}
85
86static struct cmd_results *cmd_output_position(struct output_config *output,
87 int *i, int argc, char **argv) {
88 if (++*i >= argc) {
89 return cmd_results_new(CMD_INVALID, "output",
90 "Missing position argument.");
91 }
92
93 char *end;
94 output->x = strtol(argv[*i], &end, 10);
95 if (*end) {
96 // Format is 1234,4321
97 if (*end != ',') {
98 return cmd_results_new(CMD_INVALID, "output",
99 "Invalid position x.");
100 }
101 ++end;
102 output->y = strtol(end, &end, 10);
103 if (*end) {
104 return cmd_results_new(CMD_INVALID, "output",
105 "Invalid position y.");
106 }
107 } else {
108 // Format is 1234 4321 (legacy)
109 if (++*i >= argc) {
110 return cmd_results_new(CMD_INVALID, "output",
111 "Missing position argument (y).");
112 }
113 output->y = strtol(argv[*i], &end, 10);
114 if (*end) {
115 return cmd_results_new(CMD_INVALID, "output",
116 "Invalid position y.");
117 }
118 }
119
120 return NULL;
121}
122
123static struct cmd_results *cmd_output_scale(struct output_config *output,
124 int *i, int argc, char **argv) {
125 if (++*i >= argc) {
126 return cmd_results_new(CMD_INVALID, "output",
127 "Missing scale argument.");
128 }
129
130 char *end;
131 output->scale = strtof(argv[*i], &end);
132 if (*end) {
133 return cmd_results_new(CMD_INVALID, "output", "Invalid scale.");
134 }
135
136 return NULL;
137}
138
139static struct cmd_results *cmd_output_transform(struct output_config *output,
140 int *i, int argc, char **argv) {
141 if (++*i >= argc) {
142 return cmd_results_new(CMD_INVALID, "output",
143 "Missing transform argument.");
144 }
145
146 char *value = argv[*i];
147 if (strcmp(value, "normal") == 0) {
148 output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
149 } else if (strcmp(value, "90") == 0) {
150 output->transform = WL_OUTPUT_TRANSFORM_90;
151 } else if (strcmp(value, "180") == 0) {
152 output->transform = WL_OUTPUT_TRANSFORM_180;
153 } else if (strcmp(value, "270") == 0) {
154 output->transform = WL_OUTPUT_TRANSFORM_270;
155 } else if (strcmp(value, "flipped") == 0) {
156 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED;
157 } else if (strcmp(value, "flipped-90") == 0) {
158 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_90;
159 } else if (strcmp(value, "flipped-180") == 0) {
160 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_180;
161 } else if (strcmp(value, "flipped-270") == 0) {
162 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_270;
163 } else {
164 return cmd_results_new(CMD_INVALID, "output",
165 "Invalid output transform.");
166 }
167
168 return NULL;
169}
170
171static struct cmd_results *cmd_output_background(struct output_config *output,
172 int *i, int argc, char **argv) {
173 if (++*i >= argc) {
174 return cmd_results_new(CMD_INVALID, "output",
175 "Missing background file or color specification.");
176 }
177 const char *background = argv[*i];
178 if (*i + 1 >= argc) {
179 return cmd_results_new(CMD_INVALID, "output",
180 "Missing background scaling mode or `solid_color`.");
181 }
182 const char *background_option = argv[*i];
183
184 if (strcasecmp(background_option, "solid_color") == 0) {
185 output->background = strdup(background);
186 output->background_option = strdup("solid_color");
187 } else {
188 bool valid = false;
189 char *mode;
190 size_t j;
191 for (j = 0; j < (size_t)(argc - *i); ++j) {
192 mode = argv[*i + j];
193 size_t n = sizeof(bg_options) / sizeof(char *);
194 for (size_t k = 0; k < n; ++k) {
195 if (strcasecmp(mode, bg_options[k]) == 0) {
196 valid = true;
197 break;
198 }
199 }
200 if (valid) {
201 break;
202 }
203 }
204 if (!valid) {
205 return cmd_results_new(CMD_INVALID, "output",
206 "Missing background scaling mode.");
207 }
208
209 wordexp_t p;
210 char *src = join_args(argv + *i, j);
211 if (wordexp(src, &p, 0) != 0 || p.we_wordv[0] == NULL) {
212 return cmd_results_new(CMD_INVALID, "output",
213 "Invalid syntax (%s).", src);
214 }
215 free(src);
216 src = p.we_wordv[0];
217 if (config->reading && *src != '/') {
218 char *conf = strdup(config->current_config);
219 if (conf) {
220 char *conf_path = dirname(conf);
221 src = malloc(strlen(conf_path) + strlen(src) + 2);
222 if (src) {
223 sprintf(src, "%s/%s", conf_path, p.we_wordv[0]);
224 } else {
225 wlr_log(L_ERROR,
226 "Unable to allocate background source");
227 }
228 free(conf);
229 } else {
230 wlr_log(L_ERROR, "Unable to allocate background source");
231 }
232 }
233 if (!src || access(src, F_OK) == -1) {
234 wordfree(&p);
235 return cmd_results_new(CMD_INVALID, "output",
236 "Background file unreadable (%s).", src);
237 }
238
239 output->background = strdup(src);
240 output->background_option = strdup(mode);
241 if (src != p.we_wordv[0]) {
242 free(src);
243 }
244 wordfree(&p);
245
246 *i += j;
247 }
248
249 return NULL;
250}
251
252struct cmd_results *cmd_output(int argc, char **argv) { 22struct cmd_results *cmd_output(int argc, char **argv) {
253 struct cmd_results *error = checkarg(argc, "output", EXPECTED_AT_LEAST, 1); 23 struct cmd_results *error = checkarg(argc, "output", EXPECTED_AT_LEAST, 1);
254 if (error != NULL) { 24 if (error != NULL) {
@@ -260,40 +30,31 @@ struct cmd_results *cmd_output(int argc, char **argv) {
260 wlr_log(L_ERROR, "Failed to allocate output config"); 30 wlr_log(L_ERROR, "Failed to allocate output config");
261 return NULL; 31 return NULL;
262 } 32 }
33 argc--; argv++;
263 34
264 for (int i = 1; i < argc; ++i) { 35 config->handler_context.output_config = output;
265 const char *command = argv[i];
266 36
267 if (strcasecmp(command, "enable") == 0) { 37 while (argc > 0) {
268 output->enabled = 1; 38 if (find_handler(*argv, output_handlers, sizeof(output_handlers))) {
269 } else if (strcasecmp(command, "disable") == 0) { 39 error = config_subcommand(argv, argc, output_handlers,
270 output->enabled = 0; 40 sizeof(output_handlers));
271 } else if (strcasecmp(command, "mode") == 0 ||
272 strcasecmp(command, "resolution") == 0 ||
273 strcasecmp(command, "res") == 0) {
274 error = cmd_output_mode(output, &i, argc, argv);
275 } else if (strcasecmp(command, "position") == 0 ||
276 strcasecmp(command, "pos") == 0) {
277 error = cmd_output_position(output, &i, argc, argv);
278 } else if (strcasecmp(command, "scale") == 0) {
279 error = cmd_output_scale(output, &i, argc, argv);
280 } else if (strcasecmp(command, "transform") == 0) {
281 error = cmd_output_transform(output, &i, argc, argv);
282 } else if (strcasecmp(command, "background") == 0 ||
283 strcasecmp(command, "bg") == 0) {
284 error = cmd_output_background(output, &i, argc, argv);
285 } else if (strcasecmp(command, "dpms") == 0) {
286 error = cmd_output_dpms(output, &i, argc, argv);
287 } else { 41 } else {
288 error = cmd_results_new(CMD_INVALID, "output", 42 error = cmd_results_new(CMD_INVALID, "output",
289 "Invalid output subcommand: %s.", command); 43 "Invalid output subcommand: %s.", *argv);
290 } 44 }
291 45
292 if (error != NULL) { 46 if (error != NULL) {
293 goto fail; 47 goto fail;
294 } 48 }
49
50 argc = config->handler_context.leftovers.argc;
51 argv = config->handler_context.leftovers.argv;
295 } 52 }
296 53
54 config->handler_context.output_config = NULL;
55 config->handler_context.leftovers.argc = 0;
56 config->handler_context.leftovers.argv = NULL;
57
297 int i = list_seq_find(config->output_configs, output_name_cmp, output->name); 58 int i = list_seq_find(config->output_configs, output_name_cmp, output->name);
298 if (i >= 0) { 59 if (i >= 0) {
299 // Merge existing config 60 // Merge existing config
@@ -338,6 +99,7 @@ struct cmd_results *cmd_output(int argc, char **argv) {
338 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 99 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
339 100
340fail: 101fail:
102 config->handler_context.output_config = NULL;
341 free_output_config(output); 103 free_output_config(output);
342 return error; 104 return error;
343} 105}
diff --git a/sway/commands/output/background.c b/sway/commands/output/background.c
new file mode 100644
index 00000000..f039c9c9
--- /dev/null
+++ b/sway/commands/output/background.c
@@ -0,0 +1,105 @@
1#define _XOPEN_SOURCE 500
2#include <libgen.h>
3#include <strings.h>
4#include <unistd.h>
5#include <wordexp.h>
6#include "sway/commands.h"
7#include "sway/config.h"
8#include "log.h"
9#include "stringop.h"
10
11static char *bg_options[] = {
12 "stretch",
13 "center",
14 "fill",
15 "fit",
16 "tile",
17};
18
19struct cmd_results *output_cmd_background(int argc, char **argv) {
20 if (!config->handler_context.output_config) {
21 return cmd_results_new(CMD_FAILURE, "output", "Missing output config");
22 }
23 if (!argc) {
24 return cmd_results_new(CMD_INVALID, "output",
25 "Missing background file or color specification.");
26 }
27 if (argc < 2) {
28 return cmd_results_new(CMD_INVALID, "output",
29 "Missing background scaling mode or `solid_color`.");
30 }
31
32 struct output_config *output = config->handler_context.output_config;
33
34 if (strcasecmp(argv[1], "solid_color") == 0) {
35 output->background = calloc(1, strlen(argv[0]) + 3);
36 snprintf(output->background, strlen(argv[0]) + 3, "\"%s\"", argv[0]);
37 output->background_option = strdup("solid_color");
38 argc -= 2; argv += 2;
39 } else {
40 bool valid = false;
41 char *mode;
42 size_t j;
43 for (j = 0; j < (size_t)argc; ++j) {
44 mode = argv[j];
45 size_t n = sizeof(bg_options) / sizeof(char *);
46 for (size_t k = 0; k < n; ++k) {
47 if (strcasecmp(mode, bg_options[k]) == 0) {
48 valid = true;
49 break;
50 }
51 }
52 if (valid) {
53 break;
54 }
55 }
56 if (!valid) {
57 return cmd_results_new(CMD_INVALID, "output",
58 "Missing background scaling mode.");
59 }
60
61 wordexp_t p;
62 char *src = join_args(argv, j);
63 if (wordexp(src, &p, 0) != 0 || p.we_wordv[0] == NULL) {
64 return cmd_results_new(CMD_INVALID, "output",
65 "Invalid syntax (%s).", src);
66 }
67 free(src);
68 src = p.we_wordv[0];
69 if (config->reading && *src != '/') {
70 char *conf = strdup(config->current_config);
71 if (conf) {
72 char *conf_path = dirname(conf);
73 src = malloc(strlen(conf_path) + strlen(src) + 2);
74 if (src) {
75 sprintf(src, "%s/%s", conf_path, p.we_wordv[0]);
76 } else {
77 wlr_log(L_ERROR,
78 "Unable to allocate background source");
79 }
80 free(conf);
81 } else {
82 wlr_log(L_ERROR, "Unable to allocate background source");
83 }
84 }
85 if (!src || access(src, F_OK) == -1) {
86 wordfree(&p);
87 return cmd_results_new(CMD_INVALID, "output",
88 "Background file unreadable (%s).", src);
89 }
90
91 output->background = strdup(src);
92 output->background_option = strdup(mode);
93 if (src != p.we_wordv[0]) {
94 free(src);
95 }
96 wordfree(&p);
97
98 argc -= j + 1; argv += j + 1;
99 }
100
101 config->handler_context.leftovers.argc = argc;
102 config->handler_context.leftovers.argv = argv;
103 return NULL;
104}
105
diff --git a/sway/commands/output/disable.c b/sway/commands/output/disable.c
new file mode 100644
index 00000000..65517c49
--- /dev/null
+++ b/sway/commands/output/disable.c
@@ -0,0 +1,13 @@
1#include "sway/commands.h"
2#include "sway/config.h"
3
4struct cmd_results *output_cmd_disable(int argc, char **argv) {
5 if (!config->handler_context.output_config) {
6 return cmd_results_new(CMD_FAILURE, "output", "Missing output config");
7 }
8 config->handler_context.output_config->enabled = 0;
9
10 config->handler_context.leftovers.argc = argc;
11 config->handler_context.leftovers.argv = argv;
12 return NULL;
13}
diff --git a/sway/commands/output/dpms.c b/sway/commands/output/dpms.c
new file mode 100644
index 00000000..0959ea6b
--- /dev/null
+++ b/sway/commands/output/dpms.c
@@ -0,0 +1,24 @@
1#include "sway/commands.h"
2#include "sway/config.h"
3
4struct cmd_results *output_cmd_dpms(int argc, char **argv) {
5 if (!config->handler_context.output_config) {
6 return cmd_results_new(CMD_FAILURE, "output", "Missing output config");
7 }
8 if (!argc) {
9 return cmd_results_new(CMD_INVALID, "output", "Missing dpms argument.");
10 }
11
12 if (strcmp(*argv, "on") == 0) {
13 config->handler_context.output_config->dpms_state = DPMS_ON;
14 } else if (strcmp(*argv, "off") == 0) {
15 config->handler_context.output_config->dpms_state = DPMS_OFF;
16 } else {
17 return cmd_results_new(CMD_INVALID, "output",
18 "Invalid dpms state, valid states are on/off.");
19 }
20
21 config->handler_context.leftovers.argc = argc - 1;
22 config->handler_context.leftovers.argv = argv + 1;
23 return NULL;
24}
diff --git a/sway/commands/output/enable.c b/sway/commands/output/enable.c
new file mode 100644
index 00000000..8e3314f8
--- /dev/null
+++ b/sway/commands/output/enable.c
@@ -0,0 +1,14 @@
1#include "sway/commands.h"
2#include "sway/config.h"
3
4struct cmd_results *output_cmd_enable(int argc, char **argv) {
5 if (!config->handler_context.output_config) {
6 return cmd_results_new(CMD_FAILURE, "output", "Missing output config");
7 }
8 config->handler_context.output_config->enabled = 1;
9
10 config->handler_context.leftovers.argc = argc;
11 config->handler_context.leftovers.argv = argv;
12 return NULL;
13}
14
diff --git a/sway/commands/output/mode.c b/sway/commands/output/mode.c
new file mode 100644
index 00000000..daec6d44
--- /dev/null
+++ b/sway/commands/output/mode.c
@@ -0,0 +1,55 @@
1#include <strings.h>
2#include "sway/commands.h"
3#include "sway/config.h"
4
5struct cmd_results *output_cmd_mode(int argc, char **argv) {
6 if (!config->handler_context.output_config) {
7 return cmd_results_new(CMD_FAILURE, "output", "Missing output config");
8 }
9 if (!argc) {
10 return cmd_results_new(CMD_INVALID, "output", "Missing mode argument.");
11 }
12
13 struct output_config *output = config->handler_context.output_config;
14
15 char *end;
16 output->width = strtol(*argv, &end, 10);
17 if (*end) {
18 // Format is 1234x4321
19 if (*end != 'x') {
20 return cmd_results_new(CMD_INVALID, "output",
21 "Invalid mode width.");
22 }
23 ++end;
24 output->height = strtol(end, &end, 10);
25 if (*end) {
26 if (*end != '@') {
27 return cmd_results_new(CMD_INVALID, "output",
28 "Invalid mode height.");
29 }
30 ++end;
31 output->refresh_rate = strtof(end, &end);
32 if (strcasecmp("Hz", end) != 0) {
33 return cmd_results_new(CMD_INVALID, "output",
34 "Invalid mode refresh rate.");
35 }
36 }
37 } else {
38 // Format is 1234 4321
39 if (!argc) {
40 return cmd_results_new(CMD_INVALID, "output",
41 "Missing mode argument (height).");
42 }
43 argc--; argv++;
44 output->height = strtol(*argv, &end, 10);
45 if (*end) {
46 return cmd_results_new(CMD_INVALID, "output",
47 "Invalid mode height.");
48 }
49 }
50
51 config->handler_context.leftovers.argc = argc - 1;
52 config->handler_context.leftovers.argv = argv + 1;
53 return NULL;
54}
55
diff --git a/sway/commands/output/position.c b/sway/commands/output/position.c
new file mode 100644
index 00000000..c2aeb281
--- /dev/null
+++ b/sway/commands/output/position.c
@@ -0,0 +1,46 @@
1#include <strings.h>
2#include "sway/commands.h"
3#include "sway/config.h"
4
5struct cmd_results *output_cmd_position(int argc, char **argv) {
6 if (!config->handler_context.output_config) {
7 return cmd_results_new(CMD_FAILURE, "output", "Missing output config");
8 }
9 if (!argc) {
10 return cmd_results_new(CMD_INVALID, "output",
11 "Missing position argument.");
12 }
13
14 char *end;
15 config->handler_context.output_config->x = strtol(*argv, &end, 10);
16 if (*end) {
17 // Format is 1234,4321
18 if (*end != ',') {
19 return cmd_results_new(CMD_INVALID, "output",
20 "Invalid position x.");
21 }
22 ++end;
23 config->handler_context.output_config->y = strtol(end, &end, 10);
24 if (*end) {
25 return cmd_results_new(CMD_INVALID, "output",
26 "Invalid position y.");
27 }
28 } else {
29 // Format is 1234 4321 (legacy)
30 if (!argc) {
31 return cmd_results_new(CMD_INVALID, "output",
32 "Missing position argument (y).");
33 }
34 argc--; argv++;
35 config->handler_context.output_config->y = strtol(*argv, &end, 10);
36 if (*end) {
37 return cmd_results_new(CMD_INVALID, "output",
38 "Invalid position y.");
39 }
40 }
41
42 config->handler_context.leftovers.argc = argc - 1;
43 config->handler_context.leftovers.argv = argv + 1;
44 return NULL;
45}
46
diff --git a/sway/commands/output/scale.c b/sway/commands/output/scale.c
new file mode 100644
index 00000000..0b4cc131
--- /dev/null
+++ b/sway/commands/output/scale.c
@@ -0,0 +1,23 @@
1#include <strings.h>
2#include "sway/commands.h"
3#include "sway/config.h"
4
5struct cmd_results *output_cmd_scale(int argc, char **argv) {
6 if (!config->handler_context.output_config) {
7 return cmd_results_new(CMD_FAILURE, "output", "Missing output config");
8 }
9 if (!argc) {
10 return cmd_results_new(CMD_INVALID, "output",
11 "Missing scale argument.");
12 }
13
14 char *end;
15 config->handler_context.output_config->scale = strtof(*argv, &end);
16 if (*end) {
17 return cmd_results_new(CMD_INVALID, "output", "Invalid scale.");
18 }
19
20 config->handler_context.leftovers.argc = argc - 1;
21 config->handler_context.leftovers.argv = argv + 1;
22 return NULL;
23}
diff --git a/sway/commands/output/transform.c b/sway/commands/output/transform.c
new file mode 100644
index 00000000..f9a94d64
--- /dev/null
+++ b/sway/commands/output/transform.c
@@ -0,0 +1,39 @@
1#include <string.h>
2#include "sway/commands.h"
3#include "sway/config.h"
4
5struct cmd_results *output_cmd_transform(int argc, char **argv) {
6 if (!config->handler_context.output_config) {
7 return cmd_results_new(CMD_FAILURE, "output", "Missing output config");
8 }
9 if (!argc) {
10 return cmd_results_new(CMD_INVALID, "output",
11 "Missing transform argument.");
12 }
13
14 struct output_config *output = config->handler_context.output_config;
15 if (strcmp(*argv, "normal") == 0) {
16 output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
17 } else if (strcmp(*argv, "90") == 0) {
18 output->transform = WL_OUTPUT_TRANSFORM_90;
19 } else if (strcmp(*argv, "180") == 0) {
20 output->transform = WL_OUTPUT_TRANSFORM_180;
21 } else if (strcmp(*argv, "270") == 0) {
22 output->transform = WL_OUTPUT_TRANSFORM_270;
23 } else if (strcmp(*argv, "flipped") == 0) {
24 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED;
25 } else if (strcmp(*argv, "flipped-90") == 0) {
26 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_90;
27 } else if (strcmp(*argv, "flipped-180") == 0) {
28 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_180;
29 } else if (strcmp(*argv, "flipped-270") == 0) {
30 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_270;
31 } else {
32 return cmd_results_new(CMD_INVALID, "output",
33 "Invalid output transform.");
34 }
35
36 config->handler_context.leftovers.argc = argc - 1;
37 config->handler_context.leftovers.argv = argv + 1;
38 return NULL;
39}
diff --git a/sway/meson.build b/sway/meson.build
index 4c038583..b6bb02a7 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -120,6 +120,15 @@ sway_sources = files(
120 'commands/input/xkb_rules.c', 120 'commands/input/xkb_rules.c',
121 'commands/input/xkb_variant.c', 121 'commands/input/xkb_variant.c',
122 122
123 'commands/output/background.c',
124 'commands/output/disable.c',
125 'commands/output/dpms.c',
126 'commands/output/enable.c',
127 'commands/output/mode.c',
128 'commands/output/position.c',
129 'commands/output/scale.c',
130 'commands/output/transform.c',
131
123 'tree/arrange.c', 132 'tree/arrange.c',
124 'tree/container.c', 133 'tree/container.c',
125 'tree/layout.c', 134 'tree/layout.c',