aboutsummaryrefslogtreecommitdiffstats
path: root/swayidle/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'swayidle/main.c')
-rw-r--r--swayidle/main.c93
1 files changed, 45 insertions, 48 deletions
diff --git a/swayidle/main.c b/swayidle/main.c
index 7666578f..678d622f 100644
--- a/swayidle/main.c
+++ b/swayidle/main.c
@@ -1,22 +1,21 @@
1#define _XOPEN_SOURCE 500 1#define _XOPEN_SOURCE 500
2#include <errno.h>
2#include <getopt.h> 3#include <getopt.h>
3#include <signal.h>
4#include <pthread.h> 4#include <pthread.h>
5#include <signal.h>
5#include <stdio.h> 6#include <stdio.h>
6#include <stdlib.h> 7#include <stdlib.h>
7#include <errno.h>
8#include <string.h> 8#include <string.h>
9#include <sys/wait.h> 9#include <sys/wait.h>
10#include <unistd.h> 10#include <unistd.h>
11#include <wayland-client-protocol.h> 11#include <wayland-client-protocol.h>
12#include <wayland-client.h> 12#include <wayland-client.h>
13#include <wayland-server.h>
13#include <wayland-util.h> 14#include <wayland-util.h>
14#include <wlr/config.h> 15#include <wlr/config.h>
15#include <wlr/util/log.h> 16#include <wlr/util/log.h>
16#include <wlr/types/wlr_output_layout.h>
17#include <wlr/types/wlr_output.h>
18#include "idle-client-protocol.h"
19#include "config.h" 17#include "config.h"
18#include "idle-client-protocol.h"
20#include "list.h" 19#include "list.h"
21#ifdef SWAY_IDLE_HAS_SYSTEMD 20#ifdef SWAY_IDLE_HAS_SYSTEMD
22#include <systemd/sd-bus.h> 21#include <systemd/sd-bus.h>
@@ -36,7 +35,6 @@ struct swayidle_state {
36 struct wl_display *display; 35 struct wl_display *display;
37 struct org_kde_kwin_idle_timeout *idle_timer; 36 struct org_kde_kwin_idle_timeout *idle_timer;
38 struct org_kde_kwin_idle_timeout *lock_timer; 37 struct org_kde_kwin_idle_timeout *lock_timer;
39 struct wlr_output_layout *layout;
40 struct wl_event_loop *event_loop; 38 struct wl_event_loop *event_loop;
41 list_t *timeout_cmds; 39 list_t *timeout_cmds;
42} state; 40} state;
@@ -59,24 +57,24 @@ static void cmd_exec(void *data) {
59 return; 57 return;
60 } 58 }
61 char *param = (char *)data; 59 char *param = (char *)data;
62 wlr_log(L_DEBUG, "Cmd exec %s", param); 60 wlr_log(WLR_DEBUG, "Cmd exec %s", param);
63 pid_t pid = fork(); 61 pid_t pid = fork();
64 if (pid == 0) { 62 if (pid == 0) {
65 pid = fork(); 63 pid = fork();
66 if (pid == 0) { 64 if (pid == 0) {
67 char *const cmd[] = { "sh", "-c", param, NULL, }; 65 char *const cmd[] = { "sh", "-c", param, NULL, };
68 execvp(cmd[0], cmd); 66 execvp(cmd[0], cmd);
69 wlr_log_errno(L_ERROR, "execve failed!"); 67 wlr_log_errno(WLR_ERROR, "execve failed!");
70 exit(1); 68 exit(1);
71 } else if (pid < 0) { 69 } else if (pid < 0) {
72 wlr_log_errno(L_ERROR, "fork failed"); 70 wlr_log_errno(WLR_ERROR, "fork failed");
73 exit(1); 71 exit(1);
74 } 72 }
75 exit(0); 73 exit(0);
76 } else if (pid < 0) { 74 } else if (pid < 0) {
77 wlr_log_errno(L_ERROR, "fork failed"); 75 wlr_log_errno(WLR_ERROR, "fork failed");
78 } else { 76 } else {
79 wlr_log(L_DEBUG, "Spawned process %s", param); 77 wlr_log(WLR_DEBUG, "Spawned process %s", param);
80 waitpid(pid, NULL, 0); 78 waitpid(pid, NULL, 0);
81 } 79 }
82} 80}
@@ -86,7 +84,7 @@ static int lock_fd = -1;
86static int ongoing_fd = -1; 84static int ongoing_fd = -1;
87 85
88static int release_lock(void *data) { 86static int release_lock(void *data) {
89 wlr_log(L_INFO, "Releasing sleep lock %d", ongoing_fd); 87 wlr_log(WLR_INFO, "Releasing sleep lock %d", ongoing_fd);
90 if (ongoing_fd >= 0) { 88 if (ongoing_fd >= 0) {
91 close(ongoing_fd); 89 close(ongoing_fd);
92 } 90 }
@@ -101,7 +99,7 @@ void acquire_sleep_lock() {
101 int ret = sd_bus_default_system(&bus); 99 int ret = sd_bus_default_system(&bus);
102 100
103 if (ret < 0) { 101 if (ret < 0) {
104 wlr_log(L_ERROR, "Failed to open D-Bus connection: %s", 102 wlr_log(WLR_ERROR, "Failed to open D-Bus connection: %s",
105 strerror(-ret)); 103 strerror(-ret));
106 return; 104 return;
107 } 105 }
@@ -112,17 +110,17 @@ void acquire_sleep_lock() {
112 &error, &msg, "ssss", "sleep", "swayidle", 110 &error, &msg, "ssss", "sleep", "swayidle",
113 "Setup Up Lock Screen", "delay"); 111 "Setup Up Lock Screen", "delay");
114 if (ret < 0) { 112 if (ret < 0) {
115 wlr_log(L_ERROR, "Failed to send Inhibit signal: %s", 113 wlr_log(WLR_ERROR, "Failed to send Inhibit signal: %s",
116 strerror(-ret)); 114 strerror(-ret));
117 } else { 115 } else {
118 ret = sd_bus_message_read(msg, "h", &lock_fd); 116 ret = sd_bus_message_read(msg, "h", &lock_fd);
119 if (ret < 0) { 117 if (ret < 0) {
120 wlr_log(L_ERROR, 118 wlr_log(WLR_ERROR,
121 "Failed to parse D-Bus response for Inhibit: %s", 119 "Failed to parse D-Bus response for Inhibit: %s",
122 strerror(-ret)); 120 strerror(-ret));
123 } 121 }
124 } 122 }
125 wlr_log(L_INFO, "Got sleep lock: %d", lock_fd); 123 wlr_log(WLR_INFO, "Got sleep lock: %d", lock_fd);
126} 124}
127 125
128static int prepare_for_sleep(sd_bus_message *msg, void *userdata, 126static int prepare_for_sleep(sd_bus_message *msg, void *userdata,
@@ -131,10 +129,10 @@ static int prepare_for_sleep(sd_bus_message *msg, void *userdata,
131 int going_down = 1; 129 int going_down = 1;
132 int ret = sd_bus_message_read(msg, "b", &going_down); 130 int ret = sd_bus_message_read(msg, "b", &going_down);
133 if (ret < 0) { 131 if (ret < 0) {
134 wlr_log(L_ERROR, "Failed to parse D-Bus response for Inhibit: %s", 132 wlr_log(WLR_ERROR, "Failed to parse D-Bus response for Inhibit: %s",
135 strerror(-ret)); 133 strerror(-ret));
136 } 134 }
137 wlr_log(L_DEBUG, "PrepareForSleep signal received %d", going_down); 135 wlr_log(WLR_DEBUG, "PrepareForSleep signal received %d", going_down);
138 if (!going_down) { 136 if (!going_down) {
139 acquire_sleep_lock(); 137 acquire_sleep_lock();
140 return 0; 138 return 0;
@@ -151,7 +149,7 @@ static int prepare_for_sleep(sd_bus_message *msg, void *userdata,
151 wl_event_loop_add_timer(state.event_loop, release_lock, NULL); 149 wl_event_loop_add_timer(state.event_loop, release_lock, NULL);
152 wl_event_source_timer_update(source, 1000); 150 wl_event_source_timer_update(source, 1000);
153 } 151 }
154 wlr_log(L_DEBUG, "Prepare for sleep done"); 152 wlr_log(WLR_DEBUG, "Prepare for sleep done");
155 return 0; 153 return 0;
156} 154}
157 155
@@ -165,10 +163,10 @@ static int dbus_event(int fd, uint32_t mask, void *data) {
165 163
166void setup_sleep_listener() { 164void setup_sleep_listener() {
167 struct sd_bus *bus; 165 struct sd_bus *bus;
168 166
169 int ret = sd_bus_default_system(&bus); 167 int ret = sd_bus_default_system(&bus);
170 if (ret < 0) { 168 if (ret < 0) {
171 wlr_log(L_ERROR, "Failed to open D-Bus connection: %s", 169 wlr_log(WLR_ERROR, "Failed to open D-Bus connection: %s",
172 strerror(-ret)); 170 strerror(-ret));
173 return; 171 return;
174 } 172 }
@@ -183,7 +181,7 @@ void setup_sleep_listener() {
183 "/org/freedesktop/login1"); 181 "/org/freedesktop/login1");
184 ret = sd_bus_add_match(bus, NULL, str, prepare_for_sleep, NULL); 182 ret = sd_bus_add_match(bus, NULL, str, prepare_for_sleep, NULL);
185 if (ret < 0) { 183 if (ret < 0) {
186 wlr_log(L_ERROR, "Failed to add D-Bus match: %s", strerror(-ret)); 184 wlr_log(WLR_ERROR, "Failed to add D-Bus match: %s", strerror(-ret));
187 return; 185 return;
188 } 186 }
189 acquire_sleep_lock(); 187 acquire_sleep_lock();
@@ -214,7 +212,7 @@ static const struct wl_registry_listener registry_listener = {
214 212
215static void handle_idle(void *data, struct org_kde_kwin_idle_timeout *timer) { 213static void handle_idle(void *data, struct org_kde_kwin_idle_timeout *timer) {
216 struct swayidle_timeout_cmd *cmd = data; 214 struct swayidle_timeout_cmd *cmd = data;
217 wlr_log(L_DEBUG, "idle state"); 215 wlr_log(WLR_DEBUG, "idle state");
218 if (cmd && cmd->idle_cmd && cmd->idle_cmd->callback) { 216 if (cmd && cmd->idle_cmd && cmd->idle_cmd->callback) {
219 cmd->idle_cmd->callback(cmd->idle_cmd->param); 217 cmd->idle_cmd->callback(cmd->idle_cmd->param);
220 } 218 }
@@ -222,7 +220,7 @@ static void handle_idle(void *data, struct org_kde_kwin_idle_timeout *timer) {
222 220
223static void handle_resume(void *data, struct org_kde_kwin_idle_timeout *timer) { 221static void handle_resume(void *data, struct org_kde_kwin_idle_timeout *timer) {
224 struct swayidle_timeout_cmd *cmd = data; 222 struct swayidle_timeout_cmd *cmd = data;
225 wlr_log(L_DEBUG, "active state"); 223 wlr_log(WLR_DEBUG, "active state");
226 if (cmd && cmd->resume_cmd && cmd->resume_cmd->callback) { 224 if (cmd && cmd->resume_cmd && cmd->resume_cmd->callback) {
227 cmd->resume_cmd->callback(cmd->resume_cmd->param); 225 cmd->resume_cmd->callback(cmd->resume_cmd->param);
228 } 226 }
@@ -235,12 +233,12 @@ static const struct org_kde_kwin_idle_timeout_listener idle_timer_listener = {
235 233
236struct swayidle_cmd *parse_command(int argc, char **argv) { 234struct swayidle_cmd *parse_command(int argc, char **argv) {
237 if (argc < 1) { 235 if (argc < 1) {
238 wlr_log(L_ERROR, "Too few parameters for command in parse_command"); 236 wlr_log(WLR_ERROR, "Too few parameters for command in parse_command");
239 return NULL; 237 return NULL;
240 } 238 }
241 239
242 struct swayidle_cmd *cmd = calloc(1, sizeof(struct swayidle_cmd)); 240 struct swayidle_cmd *cmd = calloc(1, sizeof(struct swayidle_cmd));
243 wlr_log(L_DEBUG, "Command: %s", argv[0]); 241 wlr_log(WLR_DEBUG, "Command: %s", argv[0]);
244 cmd->callback = cmd_exec; 242 cmd->callback = cmd_exec;
245 cmd->param = argv[0]; 243 cmd->param = argv[0];
246 return cmd; 244 return cmd;
@@ -248,7 +246,7 @@ struct swayidle_cmd *parse_command(int argc, char **argv) {
248 246
249int parse_timeout(int argc, char **argv) { 247int parse_timeout(int argc, char **argv) {
250 if (argc < 3) { 248 if (argc < 3) {
251 wlr_log(L_ERROR, "Too few parameters to timeout command. " 249 wlr_log(WLR_ERROR, "Too few parameters to timeout command. "
252 "Usage: timeout <seconds> <command>"); 250 "Usage: timeout <seconds> <command>");
253 exit(-1); 251 exit(-1);
254 } 252 }
@@ -256,7 +254,7 @@ int parse_timeout(int argc, char **argv) {
256 char *endptr; 254 char *endptr;
257 int seconds = strtoul(argv[1], &endptr, 10); 255 int seconds = strtoul(argv[1], &endptr, 10);
258 if (errno != 0 || *endptr != '\0') { 256 if (errno != 0 || *endptr != '\0') {
259 wlr_log(L_ERROR, "Invalid timeout parameter '%s', it should be a " 257 wlr_log(WLR_ERROR, "Invalid timeout parameter '%s', it should be a "
260 "numeric value representing seconds", optarg); 258 "numeric value representing seconds", optarg);
261 exit(-1); 259 exit(-1);
262 } 260 }
@@ -264,13 +262,13 @@ int parse_timeout(int argc, char **argv) {
264 calloc(1, sizeof(struct swayidle_timeout_cmd)); 262 calloc(1, sizeof(struct swayidle_timeout_cmd));
265 cmd->timeout = seconds * 1000; 263 cmd->timeout = seconds * 1000;
266 264
267 wlr_log(L_DEBUG, "Register idle timeout at %d ms", cmd->timeout); 265 wlr_log(WLR_DEBUG, "Register idle timeout at %d ms", cmd->timeout);
268 wlr_log(L_DEBUG, "Setup idle"); 266 wlr_log(WLR_DEBUG, "Setup idle");
269 cmd->idle_cmd = parse_command(argc - 2, &argv[2]); 267 cmd->idle_cmd = parse_command(argc - 2, &argv[2]);
270 268
271 int result = 3; 269 int result = 3;
272 if (argc >= 5 && !strcmp("resume", argv[3])) { 270 if (argc >= 5 && !strcmp("resume", argv[3])) {
273 wlr_log(L_DEBUG, "Setup resume"); 271 wlr_log(WLR_DEBUG, "Setup resume");
274 cmd->resume_cmd = parse_command(argc - 4, &argv[4]); 272 cmd->resume_cmd = parse_command(argc - 4, &argv[4]);
275 result = 5; 273 result = 5;
276 } 274 }
@@ -280,14 +278,14 @@ int parse_timeout(int argc, char **argv) {
280 278
281int parse_sleep(int argc, char **argv) { 279int parse_sleep(int argc, char **argv) {
282 if (argc < 2) { 280 if (argc < 2) {
283 wlr_log(L_ERROR, "Too few parameters to before-sleep command. " 281 wlr_log(WLR_ERROR, "Too few parameters to before-sleep command. "
284 "Usage: before-sleep <command>"); 282 "Usage: before-sleep <command>");
285 exit(-1); 283 exit(-1);
286 } 284 }
287 285
288 lock_cmd = parse_command(argc - 1, &argv[1]); 286 lock_cmd = parse_command(argc - 1, &argv[1]);
289 if (lock_cmd) { 287 if (lock_cmd) {
290 wlr_log(L_DEBUG, "Setup sleep lock: %s", lock_cmd->param); 288 wlr_log(WLR_DEBUG, "Setup sleep lock: %s", lock_cmd->param);
291 } 289 }
292 290
293 return 2; 291 return 2;
@@ -314,10 +312,10 @@ int parse_args(int argc, char *argv[]) {
314 } 312 }
315 313
316 if (debug) { 314 if (debug) {
317 wlr_log_init(L_DEBUG, NULL); 315 wlr_log_init(WLR_DEBUG, NULL);
318 wlr_log(L_DEBUG, "Loglevel debug"); 316 wlr_log(WLR_DEBUG, "Loglevel debug");
319 } else { 317 } else {
320 wlr_log_init(L_INFO, NULL); 318 wlr_log_init(WLR_INFO, NULL);
321 } 319 }
322 320
323 321
@@ -326,13 +324,13 @@ int parse_args(int argc, char *argv[]) {
326 int i = optind; 324 int i = optind;
327 while (i < argc) { 325 while (i < argc) {
328 if (!strcmp("timeout", argv[i])) { 326 if (!strcmp("timeout", argv[i])) {
329 wlr_log(L_DEBUG, "Got timeout"); 327 wlr_log(WLR_DEBUG, "Got timeout");
330 i += parse_timeout(argc - i, &argv[i]); 328 i += parse_timeout(argc - i, &argv[i]);
331 } else if (!strcmp("before-sleep", argv[i])) { 329 } else if (!strcmp("before-sleep", argv[i])) {
332 wlr_log(L_DEBUG, "Got before-sleep"); 330 wlr_log(WLR_DEBUG, "Got before-sleep");
333 i += parse_sleep(argc - i, &argv[i]); 331 i += parse_sleep(argc - i, &argv[i]);
334 } else { 332 } else {
335 wlr_log(L_ERROR, "Unsupported command '%s'", argv[i]); 333 wlr_log(WLR_ERROR, "Unsupported command '%s'", argv[i]);
336 exit(-1); 334 exit(-1);
337 } 335 }
338 } 336 }
@@ -358,16 +356,16 @@ static int display_event(int fd, uint32_t mask, void *data) {
358 sway_terminate(0); 356 sway_terminate(0);
359 } 357 }
360 if (wl_display_dispatch(state.display) < 0) { 358 if (wl_display_dispatch(state.display) < 0) {
361 wlr_log_errno(L_ERROR, "wl_display_dispatch failed, exiting"); 359 wlr_log_errno(WLR_ERROR, "wl_display_dispatch failed, exiting");
362 sway_terminate(0); 360 sway_terminate(0);
363 }; 361 }
364 return 0; 362 return 0;
365} 363}
366 364
367void register_idle_timeout(void *item) { 365void register_idle_timeout(void *item) {
368 struct swayidle_timeout_cmd *cmd = item; 366 struct swayidle_timeout_cmd *cmd = item;
369 if (cmd == NULL || !cmd->timeout) { 367 if (cmd == NULL || !cmd->timeout) {
370 wlr_log(L_ERROR, "Invalid idle cmd, will not register"); 368 wlr_log(WLR_ERROR, "Invalid idle cmd, will not register");
371 return; 369 return;
372 } 370 }
373 state.idle_timer = 371 state.idle_timer =
@@ -376,7 +374,7 @@ void register_idle_timeout(void *item) {
376 org_kde_kwin_idle_timeout_add_listener(state.idle_timer, 374 org_kde_kwin_idle_timeout_add_listener(state.idle_timer,
377 &idle_timer_listener, cmd); 375 &idle_timer_listener, cmd);
378 } else { 376 } else {
379 wlr_log(L_ERROR, "Could not create idle timer"); 377 wlr_log(WLR_ERROR, "Could not create idle timer");
380 } 378 }
381} 379}
382 380
@@ -390,22 +388,21 @@ int main(int argc, char *argv[]) {
390 388
391 state.display = wl_display_connect(NULL); 389 state.display = wl_display_connect(NULL);
392 if (state.display == NULL) { 390 if (state.display == NULL) {
393 wlr_log(L_ERROR, "Failed to create display"); 391 wlr_log(WLR_ERROR, "Failed to create display");
394 return -3; 392 return -3;
395 } 393 }
396 394
397 struct wl_registry *registry = wl_display_get_registry(state.display); 395 struct wl_registry *registry = wl_display_get_registry(state.display);
398 wl_registry_add_listener(registry, &registry_listener, NULL); 396 wl_registry_add_listener(registry, &registry_listener, NULL);
399 wl_display_roundtrip(state.display); 397 wl_display_roundtrip(state.display);
400 state.layout = wlr_output_layout_create();
401 state.event_loop = wl_event_loop_create(); 398 state.event_loop = wl_event_loop_create();
402 399
403 if (idle_manager == NULL) { 400 if (idle_manager == NULL) {
404 wlr_log(L_ERROR, "Display doesn't support idle protocol"); 401 wlr_log(WLR_ERROR, "Display doesn't support idle protocol");
405 return -4; 402 return -4;
406 } 403 }
407 if (seat == NULL) { 404 if (seat == NULL) {
408 wlr_log(L_ERROR, "Seat error"); 405 wlr_log(WLR_ERROR, "Seat error");
409 return -5; 406 return -5;
410 } 407 }
411 408
@@ -417,7 +414,7 @@ int main(int argc, char *argv[]) {
417 } 414 }
418#endif 415#endif
419 if (!should_run) { 416 if (!should_run) {
420 wlr_log(L_INFO, "No command specified! Nothing to do, will exit"); 417 wlr_log(WLR_INFO, "No command specified! Nothing to do, will exit");
421 sway_terminate(0); 418 sway_terminate(0);
422 } 419 }
423 list_foreach(state.timeout_cmds, register_idle_timeout); 420 list_foreach(state.timeout_cmds, register_idle_timeout);