aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/config.h2
-rw-r--r--sway/commands/output.c441
-rw-r--r--sway/config/output.c7
-rw-r--r--sway/main.c48
-rw-r--r--sway/server.c13
-rw-r--r--swaymsg/main.c19
6 files changed, 278 insertions, 252 deletions
diff --git a/include/sway/config.h b/include/sway/config.h
index 7146623e..bf047d40 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -398,7 +398,7 @@ struct seat_attachment_config *seat_config_get_attachment(
398void apply_seat_config(struct seat_config *seat); 398void apply_seat_config(struct seat_config *seat);
399 399
400int output_name_cmp(const void *item, const void *data); 400int output_name_cmp(const void *item, const void *data);
401struct output_config *new_output_config(); 401struct output_config *new_output_config(const char *name);
402void merge_output_config(struct output_config *dst, struct output_config *src); 402void merge_output_config(struct output_config *dst, struct output_config *src);
403void apply_output_config(struct output_config *oc, swayc_t *output); 403void apply_output_config(struct output_config *oc, swayc_t *output);
404void free_output_config(struct output_config *oc); 404void free_output_config(struct output_config *oc);
diff --git a/sway/commands/output.c b/sway/commands/output.c
index 7988e3e4..8cc74bcc 100644
--- a/sway/commands/output.c
+++ b/sway/commands/output.c
@@ -20,253 +20,260 @@ static char *bg_options[] = {
20 "tile", 20 "tile",
21}; 21};
22 22
23static struct cmd_results *cmd_output_mode(struct output_config *output,
24 int *i, int argc, char **argv) {
25 if (++*i >= argc) {
26 return cmd_results_new(CMD_INVALID, "output", "Missing mode argument.");
27 }
28
29 char *end;
30 output->width = strtol(argv[*i], &end, 10);
31 if (*end) {
32 // Format is 1234x4321
33 if (*end != 'x') {
34 return cmd_results_new(CMD_INVALID, "output",
35 "Invalid mode width.");
36 }
37 ++end;
38 output->height = strtol(end, &end, 10);
39 if (*end) {
40 if (*end != '@') {
41 return cmd_results_new(CMD_INVALID, "output",
42 "Invalid mode height.");
43 }
44 ++end;
45 output->refresh_rate = strtof(end, &end);
46 if (strcasecmp("Hz", end) != 0) {
47 return cmd_results_new(CMD_INVALID, "output",
48 "Invalid mode refresh rate.");
49 }
50 }
51 } else {
52 // Format is 1234 4321
53 if (++*i >= argc) {
54 return cmd_results_new(CMD_INVALID, "output",
55 "Missing mode argument (height).");
56 }
57 output->height = strtol(argv[*i], &end, 10);
58 if (*end) {
59 return cmd_results_new(CMD_INVALID, "output",
60 "Invalid mode height.");
61 }
62 }
63
64 return NULL;
65}
66
67static struct cmd_results *cmd_output_position(struct output_config *output,
68 int *i, int argc, char **argv) {
69 if (++*i >= argc) {
70 return cmd_results_new(CMD_INVALID, "output",
71 "Missing position argument.");
72 }
73
74 char *end;
75 output->x = strtol(argv[*i], &end, 10);
76 if (*end) {
77 // Format is 1234,4321
78 if (*end != ',') {
79 return cmd_results_new(CMD_INVALID, "output",
80 "Invalid position x.");
81 }
82 ++end;
83 output->y = strtol(end, &end, 10);
84 if (*end) {
85 return cmd_results_new(CMD_INVALID, "output",
86 "Invalid position y.");
87 }
88 } else {
89 // Format is 1234 4321 (legacy)
90 if (++*i >= argc) {
91 return cmd_results_new(CMD_INVALID, "output",
92 "Missing position argument (y).");
93 }
94 output->y = strtol(argv[*i], &end, 10);
95 if (*end) {
96 return cmd_results_new(CMD_INVALID, "output",
97 "Invalid position y.");
98 }
99 }
100
101 return NULL;
102}
103
104static struct cmd_results *cmd_output_scale(struct output_config *output,
105 int *i, int argc, char **argv) {
106 if (++*i >= argc) {
107 return cmd_results_new(CMD_INVALID, "output",
108 "Missing scale argument.");
109 }
110
111 char *end;
112 output->scale = strtof(argv[*i], &end);
113 if (*end) {
114 return cmd_results_new(CMD_INVALID, "output", "Invalid scale.");
115 }
116
117 return NULL;
118}
119
120static struct cmd_results *cmd_output_transform(struct output_config *output,
121 int *i, int argc, char **argv) {
122 if (++*i >= argc) {
123 return cmd_results_new(CMD_INVALID, "output",
124 "Missing transform argument.");
125 }
126
127 char *value = argv[*i];
128 if (strcmp(value, "normal") == 0) {
129 output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
130 } else if (strcmp(value, "90") == 0) {
131 output->transform = WL_OUTPUT_TRANSFORM_90;
132 } else if (strcmp(value, "180") == 0) {
133 output->transform = WL_OUTPUT_TRANSFORM_180;
134 } else if (strcmp(value, "270") == 0) {
135 output->transform = WL_OUTPUT_TRANSFORM_270;
136 } else if (strcmp(value, "flipped") == 0) {
137 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED;
138 } else if (strcmp(value, "flipped-90") == 0) {
139 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_90;
140 } else if (strcmp(value, "flipped-180") == 0) {
141 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_180;
142 } else if (strcmp(value, "flipped-270") == 0) {
143 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_270;
144 } else {
145 return cmd_results_new(CMD_INVALID, "output",
146 "Invalid output transform.");
147 }
148
149 return NULL;
150}
151
152static struct cmd_results *cmd_output_background(struct output_config *output,
153 int *i, int argc, char **argv) {
154 if (++*i >= argc) {
155 return cmd_results_new(CMD_INVALID, "output",
156 "Missing background file or color specification.");
157 }
158 const char *background = argv[*i];
159 if (*i + 1 >= argc) {
160 return cmd_results_new(CMD_INVALID, "output",
161 "Missing background scaling mode or `solid_color`.");
162 }
163 const char *background_option = argv[*i];
164
165 if (strcasecmp(background_option, "solid_color") == 0) {
166 output->background = strdup(background);
167 output->background_option = strdup("solid_color");
168 } else {
169 bool valid = false;
170 char *mode;
171 size_t j;
172 for (j = 0; j < (size_t)(argc - *i); ++j) {
173 mode = argv[*i + j];
174 size_t n = sizeof(bg_options) / sizeof(char *);
175 for (size_t k = 0; k < n; ++k) {
176 if (strcasecmp(mode, bg_options[k]) == 0) {
177 valid = true;
178 break;
179 }
180 }
181 if (valid) {
182 break;
183 }
184 }
185 if (!valid) {
186 return cmd_results_new(CMD_INVALID, "output",
187 "Missing background scaling mode.");
188 }
189
190 wordexp_t p;
191 char *src = join_args(argv + *i - 1, j);
192 if (wordexp(src, &p, 0) != 0 || p.we_wordv[0] == NULL) {
193 return cmd_results_new(CMD_INVALID, "output",
194 "Invalid syntax (%s).", src);
195 }
196 free(src);
197 src = p.we_wordv[0];
198 if (config->reading && *src != '/') {
199 char *conf = strdup(config->current_config);
200 if (conf) {
201 char *conf_path = dirname(conf);
202 src = malloc(strlen(conf_path) + strlen(src) + 2);
203 if (src) {
204 sprintf(src, "%s/%s", conf_path, p.we_wordv[0]);
205 } else {
206 sway_log(L_ERROR,
207 "Unable to allocate background source");
208 }
209 free(conf);
210 } else {
211 sway_log(L_ERROR, "Unable to allocate background source");
212 }
213 }
214 if (!src || access(src, F_OK) == -1) {
215 wordfree(&p);
216 return cmd_results_new(CMD_INVALID, "output",
217 "Background file unreadable (%s).", src);
218 }
219
220 output->background = strdup(src);
221 output->background_option = strdup(mode);
222 if (src != p.we_wordv[0]) {
223 free(src);
224 }
225 wordfree(&p);
226
227 *i += j;
228 }
229
230 return NULL;
231}
232
23struct cmd_results *cmd_output(int argc, char **argv) { 233struct cmd_results *cmd_output(int argc, char **argv) {
24 struct cmd_results *error = NULL; 234 struct cmd_results *error = NULL;
25 if ((error = checkarg(argc, "output", EXPECTED_AT_LEAST, 1))) { 235 if ((error = checkarg(argc, "output", EXPECTED_AT_LEAST, 1))) {
26 return error; 236 return error;
27 } 237 }
28 const char *name = argv[0];
29 238
30 struct output_config *output = new_output_config(); 239 struct output_config *output = new_output_config(argv[0]);
31 if (!output) { 240 if (!output) {
32 sway_log(L_ERROR, "Failed to allocate output config"); 241 sway_log(L_ERROR, "Failed to allocate output config");
33 return NULL; 242 return NULL;
34 } 243 }
35 output->name = strdup(name);
36 244
37 int i; 245 for (int i = 1; i < argc; ++i) {
38 for (i = 1; i < argc; ++i) {
39 const char *command = argv[i]; 246 const char *command = argv[i];
40 247
41 if (strcasecmp(command, "disable") == 0) { 248 if (strcasecmp(command, "enable") == 0) {
249 output->enabled = 1;
250 } else if (strcasecmp(command, "disable") == 0) {
42 output->enabled = 0; 251 output->enabled = 0;
43 } else if (strcasecmp(command, "mode") == 0 || 252 } else if (strcasecmp(command, "mode") == 0 ||
44 strcasecmp(command, "resolution") == 0 || 253 strcasecmp(command, "resolution") == 0 ||
45 strcasecmp(command, "res") == 0) { 254 strcasecmp(command, "res") == 0) {
46 if (++i >= argc) { 255 error = cmd_output_mode(output, &i, argc, argv);
47 error = cmd_results_new(CMD_INVALID, "output",
48 "Missing mode argument.");
49 goto fail;
50 }
51
52 int width = -1, height = -1;
53 float refresh_rate = -1;
54
55 char *end;
56 width = strtol(argv[i], &end, 10);
57 if (*end) {
58 // Format is 1234x4321
59 if (*end != 'x') {
60 error = cmd_results_new(CMD_INVALID, "output",
61 "Invalid mode width.");
62 goto fail;
63 }
64 ++end;
65 height = strtol(end, &end, 10);
66 if (*end) {
67 if (*end != '@') {
68 error = cmd_results_new(CMD_INVALID, "output",
69 "Invalid mode height.");
70 goto fail;
71 }
72 ++end;
73 refresh_rate = strtof(end, &end);
74 if (strcasecmp("Hz", end) != 0) {
75 error = cmd_results_new(CMD_INVALID, "output",
76 "Invalid mode refresh rate.");
77 goto fail;
78 }
79 }
80 } else {
81 // Format is 1234 4321
82 if (++i >= argc) {
83 error = cmd_results_new(CMD_INVALID, "output",
84 "Missing mode argument (height).");
85 goto fail;
86 }
87 height = strtol(argv[i], &end, 10);
88 if (*end) {
89 error = cmd_results_new(CMD_INVALID, "output",
90 "Invalid mode height.");
91 goto fail;
92 }
93 }
94 output->width = width;
95 output->height = height;
96 output->refresh_rate = refresh_rate;
97 } else if (strcasecmp(command, "position") == 0 || 256 } else if (strcasecmp(command, "position") == 0 ||
98 strcasecmp(command, "pos") == 0) { 257 strcasecmp(command, "pos") == 0) {
99 if (++i >= argc) { 258 error = cmd_output_position(output, &i, argc, argv);
100 error = cmd_results_new(CMD_INVALID, "output",
101 "Missing position argument.");
102 goto fail;
103 }
104
105 int x = -1, y = -1;
106
107 char *end;
108 x = strtol(argv[i], &end, 10);
109 if (*end) {
110 // Format is 1234,4321
111 if (*end != ',') {
112 error = cmd_results_new(CMD_INVALID, "output",
113 "Invalid position x.");
114 goto fail;
115 }
116 ++end;
117 y = strtol(end, &end, 10);
118 if (*end) {
119 error = cmd_results_new(CMD_INVALID, "output",
120 "Invalid position y.");
121 goto fail;
122 }
123 } else {
124 // Format is 1234 4321 (legacy)
125 if (++i >= argc) {
126 error = cmd_results_new(CMD_INVALID, "output",
127 "Missing position argument (y).");
128 goto fail;
129 }
130 y = strtol(argv[i], &end, 10);
131 if (*end) {
132 error = cmd_results_new(CMD_INVALID, "output",
133 "Invalid position y.");
134 goto fail;
135 }
136 }
137
138 output->x = x;
139 output->y = y;
140 } else if (strcasecmp(command, "scale") == 0) { 259 } else if (strcasecmp(command, "scale") == 0) {
141 if (++i >= argc) { 260 error = cmd_output_scale(output, &i, argc, argv);
142 error = cmd_results_new(CMD_INVALID, "output",
143 "Missing scale parameter.");
144 goto fail;
145 }
146 char *end;
147 output->scale = strtof(argv[i], &end);
148 if (*end) {
149 error = cmd_results_new(CMD_INVALID, "output",
150 "Invalid scale.");
151 goto fail;
152 }
153 } else if (strcasecmp(command, "transform") == 0) { 261 } else if (strcasecmp(command, "transform") == 0) {
154 if (++i >= argc) { 262 error = cmd_output_transform(output, &i, argc, argv);
155 error = cmd_results_new(CMD_INVALID, "output",
156 "Missing transform parameter.");
157 goto fail;
158 }
159 char *value = argv[i];
160 if (strcmp(value, "normal") == 0) {
161 output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
162 } else if (strcmp(value, "90") == 0) {
163 output->transform = WL_OUTPUT_TRANSFORM_90;
164 } else if (strcmp(value, "180") == 0) {
165 output->transform = WL_OUTPUT_TRANSFORM_180;
166 } else if (strcmp(value, "270") == 0) {
167 output->transform = WL_OUTPUT_TRANSFORM_270;
168 } else if (strcmp(value, "flipped") == 0) {
169 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED;
170 } else if (strcmp(value, "flipped-90") == 0) {
171 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_90;
172 } else if (strcmp(value, "flipped-180") == 0) {
173 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_180;
174 } else if (strcmp(value, "flipped-270") == 0) {
175 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_270;
176 } else {
177 error = cmd_results_new(CMD_INVALID, "output",
178 "Invalid output transform.");
179 goto fail;
180 }
181 } else if (strcasecmp(command, "background") == 0 || 263 } else if (strcasecmp(command, "background") == 0 ||
182 strcasecmp(command, "bg") == 0) { 264 strcasecmp(command, "bg") == 0) {
183 wordexp_t p; 265 error = cmd_output_background(output, &i, argc, argv);
184 if (++i >= argc) {
185 error = cmd_results_new(CMD_INVALID, "output",
186 "Missing background file or color specification.");
187 goto fail;
188 }
189 if (i + 1 >= argc) {
190 error = cmd_results_new(CMD_INVALID, "output",
191 "Missing background scaling mode or `solid_color`.");
192 goto fail;
193 }
194 if (strcasecmp(argv[i + 1], "solid_color") == 0) {
195 output->background = strdup(argv[argc - 2]);
196 output->background_option = strdup("solid_color");
197 } else {
198 // argv[i+j]=bg_option
199 bool valid = false;
200 char *mode;
201 size_t j;
202 for (j = 0; j < (size_t) (argc - i); ++j) {
203 mode = argv[i + j];
204 size_t n = sizeof(bg_options) / sizeof(char *);
205 for (size_t k = 0; k < n; ++k) {
206 if (strcasecmp(mode, bg_options[k]) == 0) {
207 valid = true;
208 break;
209 }
210 }
211 if (valid) {
212 break;
213 }
214 }
215 if (!valid) {
216 error = cmd_results_new(CMD_INVALID, "output",
217 "Missing background scaling mode.");
218 goto fail;
219 }
220
221 char *src = join_args(argv + i, j);
222 if (wordexp(src, &p, 0) != 0 || p.we_wordv[0] == NULL) {
223 error = cmd_results_new(CMD_INVALID, "output",
224 "Invalid syntax (%s).", src);
225 goto fail;
226 }
227 free(src);
228 src = p.we_wordv[0];
229 if (config->reading && *src != '/') {
230 char *conf = strdup(config->current_config);
231 if (conf) {
232 char *conf_path = dirname(conf);
233 src = malloc(strlen(conf_path) + strlen(src) + 2);
234 if (src) {
235 sprintf(src, "%s/%s", conf_path, p.we_wordv[0]);
236 } else {
237 sway_log(L_ERROR,
238 "Unable to allocate background source");
239 }
240 free(conf);
241 } else {
242 sway_log(L_ERROR,
243 "Unable to allocate background source");
244 }
245 }
246 if (!src || access(src, F_OK) == -1) {
247 error = cmd_results_new(CMD_INVALID, "output",
248 "Background file unreadable (%s).", src);
249 wordfree(&p);
250 goto fail;
251 }
252
253 output->background = strdup(src);
254 output->background_option = strdup(mode);
255 if (src != p.we_wordv[0]) {
256 free(src);
257 }
258 wordfree(&p);
259
260 i += j;
261 }
262 } else { 266 } else {
263 error = cmd_results_new(CMD_INVALID, "output", 267 error = cmd_results_new(CMD_INVALID, "output",
264 "Invalid output subcommand: %s.", command); 268 "Invalid output subcommand: %s.", command);
269 }
270
271 if (error != NULL) {
265 goto fail; 272 goto fail;
266 } 273 }
267 } 274 }
268 275
269 i = list_seq_find(config->output_configs, output_name_cmp, name); 276 int i = list_seq_find(config->output_configs, output_name_cmp, output->name);
270 if (i >= 0) { 277 if (i >= 0) {
271 // merge existing config 278 // merge existing config
272 struct output_config *oc = config->output_configs->items[i]; 279 struct output_config *oc = config->output_configs->items[i];
diff --git a/sway/config/output.c b/sway/config/output.c
index ff3f73a3..f336c949 100644
--- a/sway/config/output.c
+++ b/sway/config/output.c
@@ -14,11 +14,16 @@ int output_name_cmp(const void *item, const void *data) {
14 return strcmp(output->name, name); 14 return strcmp(output->name, name);
15} 15}
16 16
17struct output_config *new_output_config() { 17struct output_config *new_output_config(const char *name) {
18 struct output_config *oc = calloc(1, sizeof(struct output_config)); 18 struct output_config *oc = calloc(1, sizeof(struct output_config));
19 if (oc == NULL) { 19 if (oc == NULL) {
20 return NULL; 20 return NULL;
21 } 21 }
22 oc->name = strdup(name);
23 if (oc->name == NULL) {
24 free(oc);
25 return NULL;
26 }
22 oc->enabled = -1; 27 oc->enabled = -1;
23 oc->width = oc->height = -1; 28 oc->width = oc->height = -1;
24 oc->refresh_rate = -1; 29 oc->refresh_rate = -1;
diff --git a/sway/main.c b/sway/main.c
index bd69395a..c18e2677 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -15,12 +15,12 @@
15#include <sys/capability.h> 15#include <sys/capability.h>
16#include <sys/prctl.h> 16#include <sys/prctl.h>
17#endif 17#endif
18#include <wlr/util/log.h>
18#include "sway/config.h" 19#include "sway/config.h"
19#include "sway/server.h" 20#include "sway/server.h"
20#include "sway/layout.h" 21#include "sway/layout.h"
21#include "sway/ipc-server.h" 22#include "sway/ipc-server.h"
22#include "ipc-client.h" 23#include "ipc-client.h"
23#include "log.h"
24#include "readline.h" 24#include "readline.h"
25#include "stringop.h" 25#include "stringop.h"
26#include "util.h" 26#include "util.h"
@@ -126,7 +126,7 @@ static void log_env() {
126 "SWAYSOCK" 126 "SWAYSOCK"
127 }; 127 };
128 for (size_t i = 0; i < sizeof(log_vars) / sizeof(char *); ++i) { 128 for (size_t i = 0; i < sizeof(log_vars) / sizeof(char *); ++i) {
129 sway_log(L_INFO, "%s=%s", log_vars[i], getenv(log_vars[i])); 129 wlr_log(L_INFO, "%s=%s", log_vars[i], getenv(log_vars[i]));
130 } 130 }
131} 131}
132 132
@@ -141,14 +141,14 @@ static void log_distro() {
141 for (size_t i = 0; i < sizeof(paths) / sizeof(char *); ++i) { 141 for (size_t i = 0; i < sizeof(paths) / sizeof(char *); ++i) {
142 FILE *f = fopen(paths[i], "r"); 142 FILE *f = fopen(paths[i], "r");
143 if (f) { 143 if (f) {
144 sway_log(L_INFO, "Contents of %s:", paths[i]); 144 wlr_log(L_INFO, "Contents of %s:", paths[i]);
145 while (!feof(f)) { 145 while (!feof(f)) {
146 char *line; 146 char *line;
147 if (!(line = read_line(f))) { 147 if (!(line = read_line(f))) {
148 break; 148 break;
149 } 149 }
150 if (*line) { 150 if (*line) {
151 sway_log(L_INFO, "%s", line); 151 wlr_log(L_INFO, "%s", line);
152 } 152 }
153 free(line); 153 free(line);
154 } 154 }
@@ -161,7 +161,7 @@ static void log_kernel() {
161 return; 161 return;
162 FILE *f = popen("uname -a", "r"); 162 FILE *f = popen("uname -a", "r");
163 if (!f) { 163 if (!f) {
164 sway_log(L_INFO, "Unable to determine kernel version"); 164 wlr_log(L_INFO, "Unable to determine kernel version");
165 return; 165 return;
166 } 166 }
167 while (!feof(f)) { 167 while (!feof(f)) {
@@ -170,7 +170,7 @@ static void log_kernel() {
170 break; 170 break;
171 } 171 }
172 if (*line) { 172 if (*line) {
173 sway_log(L_INFO, "%s", line); 173 wlr_log(L_INFO, "%s", line);
174 } 174 }
175 free(line); 175 free(line);
176 } 176 }
@@ -181,14 +181,14 @@ static void security_sanity_check() {
181 // TODO: Notify users visually if this has issues 181 // TODO: Notify users visually if this has issues
182 struct stat s; 182 struct stat s;
183 if (stat("/proc", &s)) { 183 if (stat("/proc", &s)) {
184 sway_log(L_ERROR, 184 wlr_log(L_ERROR,
185 "!! DANGER !! /proc is not available - sway CANNOT enforce security rules!"); 185 "!! DANGER !! /proc is not available - sway CANNOT enforce security rules!");
186 } 186 }
187#ifdef __linux__ 187#ifdef __linux__
188 cap_flag_value_t v; 188 cap_flag_value_t v;
189 cap_t cap = cap_get_proc(); 189 cap_t cap = cap_get_proc();
190 if (!cap || cap_get_flag(cap, CAP_SYS_PTRACE, CAP_PERMITTED, &v) != 0 || v != CAP_SET) { 190 if (!cap || cap_get_flag(cap, CAP_SYS_PTRACE, CAP_PERMITTED, &v) != 0 || v != CAP_SET) {
191 sway_log(L_ERROR, 191 wlr_log(L_ERROR,
192 "!! DANGER !! Sway does not have CAP_SYS_PTRACE and cannot enforce security rules for processes running as other users."); 192 "!! DANGER !! Sway does not have CAP_SYS_PTRACE and cannot enforce security rules for processes running as other users.");
193 } 193 }
194 if (cap) { 194 if (cap) {
@@ -204,13 +204,13 @@ static void executable_sanity_check() {
204 stat(exe, &sb); 204 stat(exe, &sb);
205 // We assume that cap_get_file returning NULL implies ENODATA 205 // We assume that cap_get_file returning NULL implies ENODATA
206 if (sb.st_mode & (S_ISUID|S_ISGID) && cap_get_file(exe)) { 206 if (sb.st_mode & (S_ISUID|S_ISGID) && cap_get_file(exe)) {
207 sway_log(L_ERROR, 207 wlr_log(L_ERROR,
208 "sway executable has both the s(g)uid bit AND file caps set."); 208 "sway executable has both the s(g)uid bit AND file caps set.");
209 sway_log(L_ERROR, 209 wlr_log(L_ERROR,
210 "This is strongly discouraged (and completely broken)."); 210 "This is strongly discouraged (and completely broken).");
211 sway_log(L_ERROR, 211 wlr_log(L_ERROR,
212 "Please clear one of them (either the suid bit, or the file caps)."); 212 "Please clear one of them (either the suid bit, or the file caps).");
213 sway_log(L_ERROR, 213 wlr_log(L_ERROR,
214 "If unsure, strip the file caps."); 214 "If unsure, strip the file caps.");
215 exit(EXIT_FAILURE); 215 exit(EXIT_FAILURE);
216 } 216 }
@@ -221,16 +221,16 @@ static void executable_sanity_check() {
221static void drop_permissions(bool keep_caps) { 221static void drop_permissions(bool keep_caps) {
222 if (getuid() != geteuid() || getgid() != getegid()) { 222 if (getuid() != geteuid() || getgid() != getegid()) {
223 if (setgid(getgid()) != 0) { 223 if (setgid(getgid()) != 0) {
224 sway_log(L_ERROR, "Unable to drop root"); 224 wlr_log(L_ERROR, "Unable to drop root");
225 exit(EXIT_FAILURE); 225 exit(EXIT_FAILURE);
226 } 226 }
227 if (setuid(getuid()) != 0) { 227 if (setuid(getuid()) != 0) {
228 sway_log(L_ERROR, "Unable to drop root"); 228 wlr_log(L_ERROR, "Unable to drop root");
229 exit(EXIT_FAILURE); 229 exit(EXIT_FAILURE);
230 } 230 }
231 } 231 }
232 if (setuid(0) != -1) { 232 if (setuid(0) != -1) {
233 sway_log(L_ERROR, "Root privileges can be restored."); 233 wlr_log(L_ERROR, "Root privileges can be restored.");
234 exit(EXIT_FAILURE); 234 exit(EXIT_FAILURE);
235 } 235 }
236#ifdef __linux__ 236#ifdef __linux__
@@ -238,11 +238,11 @@ static void drop_permissions(bool keep_caps) {
238 // Drop every cap except CAP_SYS_PTRACE 238 // Drop every cap except CAP_SYS_PTRACE
239 cap_t caps = cap_init(); 239 cap_t caps = cap_init();
240 cap_value_t keep = CAP_SYS_PTRACE; 240 cap_value_t keep = CAP_SYS_PTRACE;
241 sway_log(L_INFO, "Dropping extra capabilities"); 241 wlr_log(L_INFO, "Dropping extra capabilities");
242 if (cap_set_flag(caps, CAP_PERMITTED, 1, &keep, CAP_SET) || 242 if (cap_set_flag(caps, CAP_PERMITTED, 1, &keep, CAP_SET) ||
243 cap_set_flag(caps, CAP_EFFECTIVE, 1, &keep, CAP_SET) || 243 cap_set_flag(caps, CAP_EFFECTIVE, 1, &keep, CAP_SET) ||
244 cap_set_proc(caps)) { 244 cap_set_proc(caps)) {
245 sway_log(L_ERROR, "Failed to drop extra capabilities"); 245 wlr_log(L_ERROR, "Failed to drop extra capabilities");
246 exit(EXIT_FAILURE); 246 exit(EXIT_FAILURE);
247 } 247 }
248 } 248 }
@@ -330,22 +330,22 @@ int main(int argc, char **argv) {
330 330
331 // TODO: switch logging over to wlroots? 331 // TODO: switch logging over to wlroots?
332 if (debug) { 332 if (debug) {
333 init_log(L_DEBUG); 333 wlr_log_init(L_DEBUG, NULL);
334 } else if (verbose || validate) { 334 } else if (verbose || validate) {
335 init_log(L_INFO); 335 wlr_log_init(L_INFO, NULL);
336 } else { 336 } else {
337 init_log(L_ERROR); 337 wlr_log_init(L_ERROR, NULL);
338 } 338 }
339 339
340 if (optind < argc) { // Behave as IPC client 340 if (optind < argc) { // Behave as IPC client
341 if(optind != 1) { 341 if(optind != 1) {
342 sway_log(L_ERROR, "Don't use options with the IPC client"); 342 wlr_log(L_ERROR, "Don't use options with the IPC client");
343 exit(EXIT_FAILURE); 343 exit(EXIT_FAILURE);
344 } 344 }
345 drop_permissions(false); 345 drop_permissions(false);
346 char *socket_path = getenv("SWAYSOCK"); 346 char *socket_path = getenv("SWAYSOCK");
347 if (!socket_path) { 347 if (!socket_path) {
348 sway_log(L_ERROR, "Unable to retrieve socket path"); 348 wlr_log(L_ERROR, "Unable to retrieve socket path");
349 exit(EXIT_FAILURE); 349 exit(EXIT_FAILURE);
350 } 350 }
351 char *command = join_args(argv + optind, argc - optind); 351 char *command = join_args(argv + optind, argc - optind);
@@ -359,7 +359,7 @@ int main(int argc, char **argv) {
359 if (getuid() != geteuid() || getgid() != getegid()) { 359 if (getuid() != geteuid() || getgid() != getegid()) {
360 // Retain capabilities after setuid() 360 // Retain capabilities after setuid()
361 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { 361 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
362 sway_log(L_ERROR, "Cannot keep caps after setuid()"); 362 wlr_log(L_ERROR, "Cannot keep caps after setuid()");
363 exit(EXIT_FAILURE); 363 exit(EXIT_FAILURE);
364 } 364 }
365 suid = true; 365 suid = true;
@@ -380,7 +380,7 @@ int main(int argc, char **argv) {
380 // prevent ipc from crashing sway 380 // prevent ipc from crashing sway
381 signal(SIGPIPE, SIG_IGN); 381 signal(SIGPIPE, SIG_IGN);
382 382
383 sway_log(L_INFO, "Starting sway version " SWAY_VERSION "\n"); 383 wlr_log(L_INFO, "Starting sway version " SWAY_VERSION "\n");
384 384
385 init_layout(); 385 init_layout();
386 386
diff --git a/sway/server.c b/sway/server.c
index 32c8f03c..365094ef 100644
--- a/sway/server.c
+++ b/sway/server.c
@@ -10,12 +10,12 @@
10#include <wlr/types/wlr_wl_shell.h> 10#include <wlr/types/wlr_wl_shell.h>
11// TODO WLR: make Xwayland optional 11// TODO WLR: make Xwayland optional
12#include <wlr/xwayland.h> 12#include <wlr/xwayland.h>
13#include <wlr/util/log.h>
13#include "sway/server.h" 14#include "sway/server.h"
14#include "sway/input/input-manager.h" 15#include "sway/input/input-manager.h"
15#include "log.h"
16 16
17bool server_init(struct sway_server *server) { 17bool server_init(struct sway_server *server) {
18 sway_log(L_DEBUG, "Initializing Wayland server"); 18 wlr_log(L_DEBUG, "Initializing Wayland server");
19 19
20 server->wl_display = wl_display_create(); 20 server->wl_display = wl_display_create();
21 server->wl_event_loop = wl_display_get_event_loop(server->wl_display); 21 server->wl_event_loop = wl_display_get_event_loop(server->wl_display);
@@ -55,7 +55,8 @@ bool server_init(struct sway_server *server) {
55 server->wl_shell_surface.notify = handle_wl_shell_surface; 55 server->wl_shell_surface.notify = handle_wl_shell_surface;
56 56
57 server->socket = wl_display_add_socket_auto(server->wl_display); 57 server->socket = wl_display_add_socket_auto(server->wl_display);
58 if (!sway_assert(server->socket, "Unable to open wayland socket")) { 58 if (!server->socket) {
59 wlr_log(L_ERROR, "Unable to open wayland socket");
59 wlr_backend_destroy(server->backend); 60 wlr_backend_destroy(server->backend);
60 return false; 61 return false;
61 } 62 }
@@ -71,11 +72,11 @@ void server_fini(struct sway_server *server) {
71} 72}
72 73
73void server_run(struct sway_server *server) { 74void server_run(struct sway_server *server) {
74 sway_log(L_INFO, "Running compositor on wayland display '%s'", 75 wlr_log(L_INFO, "Running compositor on wayland display '%s'",
75 server->socket); 76 server->socket);
76 setenv("_WAYLAND_DISPLAY", server->socket, true); 77 setenv("_WAYLAND_DISPLAY", server->socket, true);
77 if (!sway_assert(wlr_backend_start(server->backend), 78 if (!wlr_backend_start(server->backend)) {
78 "Failed to start backend")) { 79 wlr_log(L_ERROR, "Failed to start backend");
79 wlr_backend_destroy(server->backend); 80 wlr_backend_destroy(server->backend);
80 return; 81 return;
81 } 82 }
diff --git a/swaymsg/main.c b/swaymsg/main.c
index b431872a..8a720fca 100644
--- a/swaymsg/main.c
+++ b/swaymsg/main.c
@@ -107,29 +107,42 @@ static void pretty_print_input(json_object *i) {
107} 107}
108 108
109static void pretty_print_output(json_object *o) { 109static void pretty_print_output(json_object *o) {
110 json_object *name, *rect, *focused, *active, *ws, *scale; 110 json_object *name, *rect, *focused, *active, *ws;
111 json_object_object_get_ex(o, "name", &name); 111 json_object_object_get_ex(o, "name", &name);
112 json_object_object_get_ex(o, "rect", &rect); 112 json_object_object_get_ex(o, "rect", &rect);
113 json_object_object_get_ex(o, "focused", &focused); 113 json_object_object_get_ex(o, "focused", &focused);
114 json_object_object_get_ex(o, "active", &active); 114 json_object_object_get_ex(o, "active", &active);
115 json_object_object_get_ex(o, "current_workspace", &ws); 115 json_object_object_get_ex(o, "current_workspace", &ws);
116 json_object *make, *model, *serial, *scale, *refresh, *transform;
117 json_object_object_get_ex(o, "make", &make);
118 json_object_object_get_ex(o, "model", &model);
119 json_object_object_get_ex(o, "serial", &serial);
116 json_object_object_get_ex(o, "scale", &scale); 120 json_object_object_get_ex(o, "scale", &scale);
121 json_object_object_get_ex(o, "refresh", &refresh);
122 json_object_object_get_ex(o, "transform", &transform);
117 json_object *x, *y, *width, *height; 123 json_object *x, *y, *width, *height;
118 json_object_object_get_ex(rect, "x", &x); 124 json_object_object_get_ex(rect, "x", &x);
119 json_object_object_get_ex(rect, "y", &y); 125 json_object_object_get_ex(rect, "y", &y);
120 json_object_object_get_ex(rect, "width", &width); 126 json_object_object_get_ex(rect, "width", &width);
121 json_object_object_get_ex(rect, "height", &height); 127 json_object_object_get_ex(rect, "height", &height);
122 printf( 128 printf(
123 "Output %s%s%s\n" 129 "Output %s '%s %s %s'%s%s\n"
124 " Geometry: %dx%d @ %d,%d\n" 130 " Mode: %dx%d @ %f Hz\n"
131 " Position: %d,%d\n"
125 " Scale factor: %dx\n" 132 " Scale factor: %dx\n"
133 " Transform: %s\n"
126 " Workspace: %s\n\n", 134 " Workspace: %s\n\n",
127 json_object_get_string(name), 135 json_object_get_string(name),
136 json_object_get_string(make),
137 json_object_get_string(model),
138 json_object_get_string(serial),
128 json_object_get_boolean(focused) ? " (focused)" : "", 139 json_object_get_boolean(focused) ? " (focused)" : "",
129 !json_object_get_boolean(active) ? " (inactive)" : "", 140 !json_object_get_boolean(active) ? " (inactive)" : "",
130 json_object_get_int(width), json_object_get_int(height), 141 json_object_get_int(width), json_object_get_int(height),
142 (float)json_object_get_int(refresh) / 1000,
131 json_object_get_int(x), json_object_get_int(y), 143 json_object_get_int(x), json_object_get_int(y),
132 json_object_get_int(scale), 144 json_object_get_int(scale),
145 json_object_get_string(transform),
133 json_object_get_string(ws) 146 json_object_get_string(ws)
134 ); 147 );
135} 148}