commit 6a2b2b4c33e623c0ec408ab5545edbb2e7aa2761 Author: chayleaf Date: Wed Aug 14 06:12:40 2024 +0700 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..8665535 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,446 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "build-env" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1522ac6ee801a11bf9ef3f80403f4ede6eb41291fac3dde3de09989679305f25" + +[[package]] +name = "cc" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e8aabfac534be767c909e0690571677d49f41bd8465ae876fe043d52ba5292" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "env_filter" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "libsystemd-sys" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed080163caa59cc29b34bce2209b737149a4bac148cd9a8b04e4c12822798119" +dependencies = [ + "build-env", + "libc", + "pkg-config", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quick-xml" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f24d770aeca0eacb81ac29dfbc55ebcc09312fdd1f8bbecdc7e4a84e000e3b4" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "swayidle-rs" +version = "0.1.0" +dependencies = [ + "env_logger", + "libc", + "libsystemd-sys", + "log", + "wayland-client", + "wayland-sys", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "wayland-backend" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90e11ce2ca99c97b940ee83edbae9da2d56a08f9ea8158550fd77fa31722993" +dependencies = [ + "cc", + "downcast-rs", + "rustix", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e321577a0a165911bdcfb39cf029302479d7527b517ee58ab0f6ad09edf0943" +dependencies = [ + "bitflags", + "log", + "rustix", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7b56f89937f1cf2ee1f1259cf2936a17a1f45d8f0aa1019fae6d470d304cfa6" +dependencies = [ + "proc-macro2", + "quick-xml", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43676fe2daf68754ecf1d72026e4e6c15483198b5d24e888b74d3f22f887a148" +dependencies = [ + "dlib", + "libc", + "log", + "memoffset", + "pkg-config", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ef95fe1 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "swayidle-rs" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +env_logger = "0.11.5" +libc = "0.2.155" +libsystemd-sys = "0.9.3" +log = "0.4.22" +wayland-client = { version = "0.31.5", features = ["log"] } +wayland-sys = { version = "0.31.4", features = ["client", "server"] } diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..d443b4a --- /dev/null +++ b/shell.nix @@ -0,0 +1,7 @@ +{ pkgs ? import { } }: +pkgs.mkShell { + name = "rust-wl-shell"; + nativeBuildInputs = [ pkgs.pkg-config ]; + buildInputs = [ pkgs.wayland-protocols pkgs.wayland pkgs.systemd ]; + LD_LIBRARY_PATH = "${pkgs.wayland-scanner.out}/lib:${pkgs.systemd}/lib"; +} diff --git a/src/ext_idle_notify_v1_protocol.rs b/src/ext_idle_notify_v1_protocol.rs new file mode 100644 index 0000000..36ef58e --- /dev/null +++ b/src/ext_idle_notify_v1_protocol.rs @@ -0,0 +1,90 @@ +#![allow( + dead_code, + mutable_transmutes, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unused_assignments, + unused_mut +)] +use std::ptr; + +use wayland_client::protocol::__interfaces::wl_seat_interface; +use wayland_sys::common::{wl_interface, wl_message}; +static mut ext_idle_notify_v1_types: [*const wl_interface; 3] = unsafe { + [ + ptr::addr_of!(ext_idle_notification_v1_interface), + 0 as *const wl_interface, + ptr::addr_of!(wl_seat_interface).cast(), + ] +}; +static mut ext_idle_notifier_v1_requests: [wl_message; 2] = [ + wl_message { + name: (b"destroy\0" as *const u8).cast::(), + signature: (b"\0" as *const u8).cast::(), + types: unsafe { + ext_idle_notify_v1_types + .as_mut_ptr() + .offset(0 as libc::c_int as isize) + }, + }, + wl_message { + name: (b"get_idle_notification\0" as *const u8).cast::(), + signature: (b"nuo\0" as *const u8).cast::(), + types: unsafe { + ext_idle_notify_v1_types + .as_mut_ptr() + .offset(0 as libc::c_int as isize) + }, + }, +]; +#[no_mangle] +pub static mut ext_idle_notifier_v1_interface: wl_interface = wl_interface { + name: (b"ext_idle_notifier_v1\0" as *const u8).cast::(), + version: 1 as libc::c_int, + request_count: 2 as libc::c_int, + requests: unsafe { ext_idle_notifier_v1_requests.as_ptr() }, + event_count: 0 as libc::c_int, + events: 0 as *const wl_message, +}; + +static mut ext_idle_notification_v1_requests: [wl_message; 1] = [wl_message { + name: (b"destroy\0" as *const u8).cast::(), + signature: (b"\0" as *const u8).cast::(), + types: unsafe { + ext_idle_notify_v1_types + .as_mut_ptr() + .offset(0 as libc::c_int as isize) + }, +}]; +static mut ext_idle_notification_v1_events: [wl_message; 2] = [ + wl_message { + name: (b"idled\0" as *const u8).cast::(), + signature: (b"\0" as *const u8).cast::(), + types: unsafe { + ext_idle_notify_v1_types + .as_mut_ptr() + .offset(0 as libc::c_int as isize) + }, + }, + wl_message { + name: (b"resumed\0" as *const u8).cast::(), + signature: (b"\0" as *const u8).cast::(), + types: unsafe { + ext_idle_notify_v1_types + .as_mut_ptr() + .offset(0 as libc::c_int as isize) + }, + }, +]; +#[no_mangle] +pub static mut ext_idle_notification_v1_interface: wl_interface = unsafe { + wl_interface { + name: (b"ext_idle_notification_v1\0" as *const u8).cast::(), + version: 1 as libc::c_int, + request_count: 1 as libc::c_int, + requests: ext_idle_notification_v1_requests.as_ptr(), + event_count: 2 as libc::c_int, + events: ext_idle_notification_v1_events.as_ptr(), + } +}; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..eaf56ff --- /dev/null +++ b/src/main.rs @@ -0,0 +1,1676 @@ +#![allow( + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + clippy::missing_safety_doc +)] +use std::{borrow::Cow, ffi::CStr, mem::MaybeUninit, os::raw::c_void, ptr}; + +use ext_idle_notify_v1_protocol::{ + ext_idle_notification_v1_interface, ext_idle_notifier_v1_interface, +}; +use libc::{ + __errno_location, abort, access, calloc, close, execvp, exit, fclose, fopen, fork, free, + getenv, getline, getopt, getpid, memset, pid_t, printf, sigemptyset, signal, sigprocmask, + sigset_t, size_t, sprintf, strcmp, strdup, strlen, strncmp, strstr, strtoul, waitpid, FILE, +}; +use libsystemd_sys::bus::{ + sd_bus, sd_bus_call_method, sd_bus_default_system, sd_bus_error, sd_bus_error_free, + sd_bus_flush, sd_bus_get_fd, sd_bus_get_property, sd_bus_message, + sd_bus_message_enter_container, sd_bus_message_exit_container, sd_bus_message_handler_t, + sd_bus_message_read, sd_bus_message_read_basic, sd_bus_message_skip, sd_bus_message_unref, + sd_bus_process, sd_bus_slot, +}; +use wayland_client::protocol::__interfaces::{wl_registry_interface, wl_seat_interface}; +use wayland_sys::{ + client::{ + wl_display, wl_display_connect, wl_display_disconnect, wl_display_dispatch, + wl_display_dispatch_pending, wl_display_flush, wl_display_get_fd, wl_display_roundtrip, + wl_list_empty, wl_list_init, wl_list_insert, wl_list_remove, wl_proxy, + wl_proxy_add_listener, wl_proxy_get_version, + }, + common::{wl_interface, wl_list}, + server::{ + wl_event_loop, wl_event_loop_add_fd, wl_event_loop_add_signal, wl_event_loop_create, + wl_event_loop_destroy, wl_event_loop_dispatch, wl_event_source, wl_event_source_check, + }, +}; + +mod ext_idle_notify_v1_protocol; + +#[repr(C)] +struct wl_registry { + a: [u8; 0], +} +#[repr(C)] +struct wl_seat { + a: [u8; 0], +} +type ext_idle_notification_v1 = wl_interface; +type ext_idle_notifier_v1 = wl_interface; +#[allow( + dead_code, + mutable_transmutes, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unused_assignments, + unused_mut +)] +extern "C" { + static mut optind: libc::c_int; + static mut optarg: *mut libc::c_char; + fn wl_proxy_marshal_flags( + proxy: *mut wl_proxy, + opcode: u32, + interface: *const wl_interface, + version: u32, + flags: u32, + _: ... + ) -> *mut wl_proxy; + fn wordexp( + __words: *const libc::c_char, + __pwordexp: *mut wordexp_t, + __flags: libc::c_int, + ) -> libc::c_int; + fn wordfree(__wordexp: *mut wordexp_t); + fn sd_bus_match_signal( + bus_0: *mut sd_bus, + ret: *mut *mut sd_bus_slot, + sender: *const libc::c_char, + path: *const libc::c_char, + interface: *const libc::c_char, + member: *const libc::c_char, + callback: sd_bus_message_handler_t, + userdata: *mut libc::c_void, + ) -> libc::c_int; +} +#[derive(Copy, Clone)] +#[repr(C)] +struct wl_registry_listener { + global: Option< + unsafe extern "C" fn( + *mut libc::c_void, + *mut wl_registry, + u32, + *const libc::c_char, + u32, + ) -> (), + >, + global_remove: Option ()>, +} +#[derive(Copy, Clone)] +#[repr(C)] +struct wl_seat_listener { + capabilities: Option ()>, + name: Option ()>, +} +const WL_EVENT_ERROR: u32 = 8; +const WL_EVENT_HANGUP: u32 = 4; +const WL_EVENT_WRITABLE: u32 = 2; +const WL_EVENT_READABLE: u32 = 1; +#[derive(Copy, Clone)] +#[repr(C)] +struct wordexp_t { + we_wordc: size_t, + we_wordv: *mut *mut libc::c_char, + we_offs: size_t, +} +#[derive(Copy, Clone)] +#[repr(C)] +struct ext_idle_notification_v1_listener { + idled: Option ()>, + resumed: Option ()>, +} +type log_importance = libc::c_uint; +const LOG_DEBUG: log_importance = 3; +#[allow(dead_code)] +const LOG_INFO: log_importance = 2; +const LOG_ERROR: log_importance = 1; +const LOG_SILENT: log_importance = 0; +#[repr(C)] +struct swayidle_state { + display: *mut wl_display, + event_loop: *mut wl_event_loop, + timeout_cmds: wl_list, + seats: wl_list, + seat_name: *mut libc::c_char, + before_sleep_cmd: *mut libc::c_char, + after_resume_cmd: *mut libc::c_char, + logind_lock_cmd: *mut libc::c_char, + logind_unlock_cmd: *mut libc::c_char, + logind_idlehint: bool, + timeouts_enabled: bool, + wait: bool, +} +#[repr(C)] +struct swayidle_timeout_cmd { + link: wl_list, + timeout: libc::c_int, + registered_timeout: libc::c_int, + idle_notification: *mut ext_idle_notification_v1, + idle_cmd: *mut libc::c_char, + resume_cmd: *mut libc::c_char, + idlehint: bool, + resume_pending: bool, +} +#[repr(C)] +struct seat { + link: wl_list, + proxy: *mut wl_seat, + name: *mut libc::c_char, + capabilities: u32, +} +#[inline] +unsafe extern "C" fn wl_display_get_registry(wl_display: *mut wl_display) -> *mut wl_registry { + let registry: *mut wl_proxy = wl_proxy_marshal_flags( + wl_display.cast::(), + 1 as libc::c_int as u32, + ptr::addr_of!(wl_registry_interface), + wl_proxy_get_version(wl_display.cast::()), + 0 as libc::c_int as u32, + ptr::null_mut::(), + ); + registry.cast() +} +#[inline] +unsafe extern "C" fn wl_registry_add_listener( + wl_registry: *mut wl_registry, + listener: *mut wl_registry_listener, + data: *mut libc::c_void, +) -> libc::c_int { + wl_proxy_add_listener(wl_registry.cast::(), listener.cast(), data) +} +#[inline] +unsafe extern "C" fn wl_registry_bind( + wl_registry: *mut wl_registry, + name: u32, + interface: *const wl_interface, + version: u32, +) -> *mut libc::c_void { + let id: *mut wl_proxy = wl_proxy_marshal_flags( + wl_registry.cast::(), + 0 as libc::c_int as u32, + interface, + version, + 0 as libc::c_int as u32, + name, + (*interface).name, + version, + ptr::null_mut::(), + ); + id.cast() +} +#[inline] +unsafe extern "C" fn wl_seat_add_listener( + wl_seat: *mut wl_seat, + listener: *const wl_seat_listener, + data: *mut libc::c_void, +) -> libc::c_int { + wl_proxy_add_listener(wl_seat.cast::(), listener.cast_mut().cast(), data) +} +#[inline] +unsafe extern "C" fn ext_idle_notifier_v1_get_idle_notification( + ext_idle_notifier_v1: *mut ext_idle_notifier_v1, + timeout: u32, + seat_0: *mut wl_seat, +) -> *mut ext_idle_notification_v1 { + let id: *mut wl_proxy = wl_proxy_marshal_flags( + ext_idle_notifier_v1.cast::(), + 1 as libc::c_int as u32, + ptr::addr_of!(ext_idle_notification_v1_interface).cast(), + wl_proxy_get_version(ext_idle_notifier_v1.cast::()), + 0 as libc::c_int as u32, + ptr::null_mut::(), + timeout, + seat_0, + ); + id.cast() +} +#[inline] +unsafe extern "C" fn ext_idle_notification_v1_add_listener( + ext_idle_notification_v1: *mut ext_idle_notification_v1, + listener: *const ext_idle_notification_v1_listener, + data: *mut libc::c_void, +) -> libc::c_int { + wl_proxy_add_listener( + ext_idle_notification_v1.cast::(), + listener.cast_mut().cast(), + data, + ) +} +#[inline] +unsafe extern "C" fn ext_idle_notification_v1_destroy( + ext_idle_notification_v1: *mut ext_idle_notification_v1, +) { + wl_proxy_marshal_flags( + ext_idle_notification_v1.cast::(), + 0 as libc::c_int as u32, + ptr::null(), + wl_proxy_get_version(ext_idle_notification_v1.cast::()), + ((1 as libc::c_int) << 0 as libc::c_int) as u32, + ); +} +static mut idle_notifier: *mut ext_idle_notifier_v1 = (0 as *const ext_idle_notifier_v1).cast_mut(); +static mut seat: *mut wl_seat = (0 as *const wl_seat).cast_mut(); +#[no_mangle] +static mut state: swayidle_state = swayidle_state { + display: (0 as *const wl_display).cast_mut(), + event_loop: (0 as *const wl_event_loop).cast_mut(), + timeout_cmds: wl_list { + prev: (0 as *const wl_list).cast_mut(), + next: (0 as *const wl_list).cast_mut(), + }, + seats: wl_list { + prev: (0 as *const wl_list).cast_mut(), + next: (0 as *const wl_list).cast_mut(), + }, + seat_name: (0 as *const libc::c_char).cast_mut(), + before_sleep_cmd: (0 as *const libc::c_char).cast_mut(), + after_resume_cmd: (0 as *const libc::c_char).cast_mut(), + logind_lock_cmd: (0 as *const libc::c_char).cast_mut(), + logind_unlock_cmd: (0 as *const libc::c_char).cast_mut(), + logind_idlehint: false, + timeouts_enabled: false, + wait: false, +}; +#[no_mangle] +unsafe extern "C" fn swayidle_log_init(verbosity: log_importance) { + env_logger::builder() + .filter( + None, + match verbosity { + LOG_ERROR => log::LevelFilter::Error, + LOG_SILENT => log::LevelFilter::Off, + LOG_DEBUG => log::LevelFilter::Debug, + _ => log::LevelFilter::Info, + }, + ) + .init(); +} +unsafe extern "C" fn swayidle_init() { + memset( + ptr::addr_of_mut!(state).cast(), + 0 as libc::c_int, + ::core::mem::size_of::(), + ); + wl_list_init(&mut state.timeout_cmds); + wl_list_init(&mut state.seats); +} +unsafe extern "C" fn swayidle_finish() { + let mut cmd: *mut swayidle_timeout_cmd; + let mut tmp: *mut swayidle_timeout_cmd; + cmd = state + .timeout_cmds + .next + .cast::() + .offset(-(0 as libc::c_ulong as isize)) + .cast::(); + tmp = (*cmd) + .link + .next + .cast::() + .offset(-(0 as libc::c_ulong as isize)) + .cast::(); + while ptr::addr_of_mut!((*cmd).link) != ptr::addr_of_mut!(state.timeout_cmds) { + wl_list_remove(&mut (*cmd).link); + free((*cmd).idle_cmd.cast::()); + free((*cmd).resume_cmd.cast::()); + free(cmd.cast::()); + cmd = tmp; + tmp = (*cmd) + .link + .next + .cast::() + .offset(-(0 as libc::c_ulong as isize)) + .cast::(); + } + free(state.after_resume_cmd.cast::()); + free(state.before_sleep_cmd.cast::()); +} +#[no_mangle] +unsafe extern "C" fn sway_terminate(exit_code: libc::c_int) { + wl_display_disconnect(state.display); + wl_event_loop_destroy(state.event_loop); + swayidle_finish(); + exit(exit_code); +} +unsafe extern "C" fn cmd_exec(param: *mut libc::c_char) { + log::debug!("Cmd exec {param:?}",); + let mut pid: pid_t = fork(); + match pid { + 0 => { + if !state.wait { + pid = fork(); + } + match pid { + 0 => { + #[allow(clippy::uninit_assumed_init, invalid_value)] + let mut set = MaybeUninit::::uninit().assume_init(); + sigemptyset(ptr::addr_of_mut!(set)); + sigprocmask(2 as libc::c_int, &set, ptr::null_mut()); + signal(2 as libc::c_int, 0); + signal(15 as libc::c_int, 0); + signal(10 as libc::c_int, 0); + let cmd: [*const libc::c_char; 4] = [ + (b"sh\0" as *const u8).cast::().cast_mut(), + (b"-c\0" as *const u8).cast::().cast_mut(), + param, + ptr::null_mut(), + ]; + execvp(cmd[0 as libc::c_int as usize], cmd.as_ptr()); + log::error!("execve failed!: {:?}", strerror(*__errno_location()),); + exit(1 as libc::c_int); + } + pid if pid < 0 => { + log::error!("fork failed: {:?}", strerror(*__errno_location()),); + exit(1 as libc::c_int); + } + _ => {} + } + exit(0 as libc::c_int); + } + pid if pid < 0 => { + log::error!("fork failed: {:?}", strerror(*__errno_location()),); + } + _ => { + log::debug!("Spawned process {param:?}"); + if state.wait { + log::debug!("Blocking until process exits",); + } + let mut status: libc::c_int = 0 as libc::c_int; + waitpid(pid, &mut status, 0 as libc::c_int); + if i32::from(state.wait) != 0 && status & 0x7f as libc::c_int == 0 as libc::c_int { + log::debug!( + "Process exit status: {}", + (status & 0xff00 as libc::c_int) >> 8 as libc::c_int, + ); + } + } + }; +} +static mut sleep_lock_fd: libc::c_int = -(1 as libc::c_int); +static mut bus: *mut sd_bus = (0 as *const sd_bus).cast_mut(); +static mut session_name: *mut libc::c_char = (0 as *const libc::c_char).cast_mut(); +unsafe extern "C" fn acquire_inhibitor_lock( + type_0: *const libc::c_char, + mode: *const libc::c_char, + fd: *mut libc::c_int, +) { + let mut msg: *mut sd_bus_message = ptr::null_mut(); + let mut error: sd_bus_error = sd_bus_error { + name: ptr::null(), + message: ptr::null(), + need_free: 0, + }; + let mut why: [libc::c_char; 35] = [0; 35]; + sprintf( + why.as_mut_ptr(), + (b"Swayidle is preventing %s\0" as *const u8).cast::(), + type_0, + ); + let mut ret: libc::c_int = sd_bus_call_method( + bus, + (b"org.freedesktop.login1\0" as *const u8).cast::(), + (b"/org/freedesktop/login1\0" as *const u8).cast::(), + (b"org.freedesktop.login1.Manager\0" as *const u8).cast::(), + (b"Inhibit\0" as *const u8).cast::(), + ptr::addr_of_mut!(error), + ptr::addr_of_mut!(msg), + (b"ssss\0" as *const u8).cast::(), + type_0, + (b"swayidle\0" as *const u8).cast::(), + why.as_mut_ptr(), + mode, + ); + if ret < 0 as libc::c_int { + log::error!( + "Failed to send {:?} inhibit signal: {:?}", + type_0, + error.message, + ); + } else { + ret = sd_bus_message_read(msg, (b"h\0" as *const u8).cast::(), fd); + if ret < 0 as libc::c_int { + *__errno_location() = -ret; + log::error!( + "Failed to parse D-Bus response for {:?} inhibit: {:?}", + type_0, + strerror(*__errno_location()), + ); + } else { + *fd = libc::fcntl(*fd, 1030 as libc::c_int, 3 as libc::c_int); + if *fd >= 0 as libc::c_int { + log::debug!("Got {:?} lock: {}", type_0, *fd,); + } else { + log::error!( + "Failed to copy {:?} lock fd: {:?}", + type_0, + strerror(*__errno_location()), + ); + } + } + } + sd_bus_error_free(&mut error); + sd_bus_message_unref(msg); +} +unsafe extern "C" fn release_inhibitor_lock(fd: libc::c_int) { + if fd >= 0 as libc::c_int { + log::debug!("Releasing inhibitor lock {}", fd,); + close(fd); + } +} +unsafe extern "C" fn set_idle_hint(hint: bool) { + log::debug!("SetIdleHint {}", i32::from(hint),); + let mut msg: *mut sd_bus_message = ptr::null_mut(); + let mut error: sd_bus_error = sd_bus_error { + name: ptr::null(), + message: ptr::null(), + need_free: 0, + }; + let ret: libc::c_int = sd_bus_call_method( + bus, + (b"org.freedesktop.login1\0" as *const u8).cast::(), + session_name, + (b"org.freedesktop.login1.Session\0" as *const u8).cast::(), + (b"SetIdleHint\0" as *const u8).cast::(), + ptr::addr_of_mut!(error), + ptr::addr_of_mut!(msg), + (b"b\0" as *const u8).cast::(), + i32::from(hint), + ); + if ret < 0 as libc::c_int { + log::error!("Failed to send SetIdleHint signal: {:?}", error.message,); + } + sd_bus_error_free(&mut error); + sd_bus_message_unref(msg); +} +unsafe extern "C" fn get_logind_idle_inhibit() -> bool { + let mut locks: *const libc::c_char = ptr::null(); + let res: bool; + let mut reply: *mut sd_bus_message = ptr::null_mut(); + let mut ret: libc::c_int = sd_bus_get_property( + bus, + (b"org.freedesktop.login1\0" as *const u8).cast::(), + (b"/org/freedesktop/login1\0" as *const u8).cast::(), + (b"org.freedesktop.login1.Manager\0" as *const u8).cast::(), + (b"BlockInhibited\0" as *const u8).cast::(), + ptr::null_mut(), + &mut reply, + (b"s\0" as *const u8).cast::(), + ); + if ret >= 0 { + ret = sd_bus_message_read_basic( + reply, + 's' as i32 as libc::c_char, + ptr::addr_of_mut!(locks).cast(), + ); + if ret >= 0 { + res = !(strstr(locks, (b"idle\0" as *const u8).cast::())).is_null(); + sd_bus_message_unref(reply); + return res; + } + } + sd_bus_message_unref(reply); + *__errno_location() = -ret; + log::error!( + "Failed to parse get BlockInhibited property: {:?}", + strerror(*__errno_location()) + ); + 0 as libc::c_int != 0 +} +unsafe extern "C" fn prepare_for_sleep( + msg: *mut sd_bus_message, + _userdata: *mut libc::c_void, + _ret_error: *mut sd_bus_error, +) -> libc::c_int { + let mut going_down: libc::c_int = 1 as libc::c_int; + let ret: libc::c_int = sd_bus_message_read( + msg, + (b"b\0" as *const u8).cast::(), + ptr::addr_of_mut!(going_down), + ); + if ret < 0 as libc::c_int { + *__errno_location() = -ret; + log::error!( + "Failed to parse D-Bus response for Inhibit: {:?}", + strerror(*__errno_location()) + ); + } + log::debug!("PrepareForSleep signal received {}", going_down,); + if going_down == 0 { + acquire_inhibitor_lock( + (b"sleep\0" as *const u8).cast::(), + (b"delay\0" as *const u8).cast::(), + ptr::addr_of_mut!(sleep_lock_fd), + ); + if !(state.after_resume_cmd).is_null() { + cmd_exec(state.after_resume_cmd); + } + if state.logind_idlehint { + set_idle_hint(0 as libc::c_int != 0); + } + return 0 as libc::c_int; + } + if !(state.before_sleep_cmd).is_null() { + cmd_exec(state.before_sleep_cmd); + } + log::debug!("Prepare for sleep done"); + release_inhibitor_lock(sleep_lock_fd); + 0 as libc::c_int +} +unsafe extern "C" fn handle_lock( + _msg: *mut sd_bus_message, + _userdata: *mut libc::c_void, + _ret_error: *mut sd_bus_error, +) -> libc::c_int { + log::debug!("Lock signal received"); + if !(state.logind_lock_cmd).is_null() { + cmd_exec(state.logind_lock_cmd); + } + log::debug!("Lock command done"); + 0 as libc::c_int +} +unsafe extern "C" fn handle_unlock( + _msg: *mut sd_bus_message, + _userdata: *mut libc::c_void, + _ret_error: *mut sd_bus_error, +) -> libc::c_int { + log::debug!("Unlock signal received"); + if state.logind_idlehint { + set_idle_hint(0 as libc::c_int != 0); + } + if !(state.logind_unlock_cmd).is_null() { + cmd_exec(state.logind_unlock_cmd); + } + log::debug!("Unlock command done"); + 0 as libc::c_int +} +fn strerror(errno: i32) -> Cow<'static, str> { + let p = unsafe { libc::strerror(errno) }; + if p.is_null() { + "".into() + } else { + unsafe { CStr::from_ptr(p) }.to_string_lossy() + } +} +unsafe extern "C" fn handle_property_changed( + msg: *mut sd_bus_message, + _userdata: *mut libc::c_void, + _ret_error: *mut sd_bus_error, +) -> libc::c_int { + let current_block: u64; + let mut name: *const libc::c_char = ptr::null(); + log::debug!("PropertiesChanged signal received"); + let mut ret: libc::c_int = sd_bus_message_read_basic( + msg, + 's' as i32 as libc::c_char, + ptr::addr_of_mut!(name).cast(), + ); + if ret >= 0 { + if strcmp( + name, + (b"org.freedesktop.login1.Manager\0" as *const u8).cast::(), + ) == 0 + { + log::debug!("Got PropertyChanged: {:?}", name); + ret = sd_bus_message_enter_container( + msg, + 'a' as i32 as libc::c_char, + (b"{sv}\0" as *const u8).cast::(), + ); + if ret < 0 as libc::c_int { + current_block = 8099226602202575710; + } else { + let mut prop: *const libc::c_char = ptr::null(); + loop { + ret = sd_bus_message_enter_container( + msg, + 'e' as i32 as libc::c_char, + (b"sv\0" as *const u8).cast::(), + ); + if ret <= 0 { + current_block = 18317007320854588510; + break; + } + ret = sd_bus_message_read_basic( + msg, + 's' as i32 as libc::c_char, + ptr::addr_of_mut!(prop).cast(), + ); + if ret < 0 as libc::c_int { + current_block = 8099226602202575710; + break; + } + if strcmp( + prop, + (b"BlockInhibited\0" as *const u8).cast::(), + ) == 0 + { + if get_logind_idle_inhibit() { + log::debug!("Logind idle inhibitor found"); + disable_timeouts(); + } else { + log::debug!("Logind idle inhibitor not found",); + enable_timeouts(); + } + return 0 as libc::c_int; + } + ret = sd_bus_message_skip(msg, (b"v\0" as *const u8).cast::()); + if ret < 0 as libc::c_int { + current_block = 8099226602202575710; + break; + } + ret = sd_bus_message_exit_container(msg); + if ret < 0 as libc::c_int { + current_block = 8099226602202575710; + break; + } + } + } + } else { + current_block = 18317007320854588510; + } + match current_block { + 8099226602202575710 => {} + _ => { + if ret >= 0 { + return 0 as libc::c_int; + } + } + } + } + *__errno_location() = -ret; + log::error!( + "Failed to parse D-Bus response for PropertyChanged: {:?}", + strerror(*__errno_location()) + ); + 0 as libc::c_int +} +unsafe extern "C" fn dbus_event( + _fd: libc::c_int, + mask: u32, + data: *mut libc::c_void, +) -> libc::c_int { + let bus_0: *mut sd_bus = data.cast::(); + if mask & WL_EVENT_HANGUP as libc::c_int as libc::c_uint != 0 + || mask & WL_EVENT_ERROR as libc::c_int as libc::c_uint != 0 + { + sway_terminate(0 as libc::c_int); + } + let count: libc::c_int = if mask & WL_EVENT_READABLE as libc::c_int as libc::c_uint != 0 { + sd_bus_process(bus_0, ptr::null_mut()) + } else { + 0 + }; + if mask & WL_EVENT_WRITABLE as libc::c_int as libc::c_uint != 0 { + sd_bus_flush(bus_0); + } + if mask == 0 as libc::c_int as libc::c_uint { + sd_bus_flush(bus_0); + } + if count < 0 as libc::c_int { + log::error!( + "sd_bus_process failed, exiting: {:?}", + strerror(*__errno_location()) + ); + sway_terminate(0 as libc::c_int); + } + count +} +unsafe extern "C" fn set_session() { + let current_block: u64; + let mut msg: *mut sd_bus_message = ptr::null_mut(); + let mut error: sd_bus_error = sd_bus_error { + name: ptr::null(), + message: ptr::null(), + need_free: 0 as libc::c_int, + }; + let mut session_name_tmp: *const libc::c_char = ptr::null(); + let mut ret: libc::c_int = sd_bus_call_method( + bus, + (b"org.freedesktop.login1\0" as *const u8).cast::(), + (b"/org/freedesktop/login1\0" as *const u8).cast::(), + (b"org.freedesktop.login1.Manager\0" as *const u8).cast::(), + (b"GetSession\0" as *const u8).cast::(), + ptr::addr_of_mut!(error), + ptr::addr_of_mut!(msg), + (b"s\0" as *const u8).cast::(), + (b"auto\0" as *const u8).cast::(), + ); + if ret < 0 as libc::c_int { + log::debug!("GetSession failed: {:?}", error.message); + sd_bus_error_free(&mut error); + sd_bus_message_unref(msg); + ret = sd_bus_call_method( + bus, + (b"org.freedesktop.login1\0" as *const u8).cast::(), + (b"/org/freedesktop/login1\0" as *const u8).cast::(), + (b"org.freedesktop.login1.Manager\0" as *const u8).cast::(), + (b"GetSessionByPID\0" as *const u8).cast::(), + ptr::addr_of_mut!(error), + ptr::addr_of_mut!(msg), + (b"u\0" as *const u8).cast::(), + getpid(), + ); + if ret < 0 as libc::c_int { + log::debug!("GetSessionByPID failed: {:?}", error.message); + log::error!("Failed to find session"); + current_block = 5197767760103794011; + } else { + current_block = 6937071982253665452; + } + } else { + current_block = 6937071982253665452; + } + if current_block == 6937071982253665452 { + ret = sd_bus_message_read( + msg, + (b"o\0" as *const u8).cast::(), + ptr::addr_of_mut!(session_name_tmp), + ); + if ret < 0 as libc::c_int { + log::error!("Failed to read session name"); + } else { + session_name = strdup(session_name_tmp); + log::debug!("Using session: {session_name:?}"); + } + } + sd_bus_error_free(&mut error); + sd_bus_message_unref(msg); +} +unsafe extern "C" fn connect_to_bus() { + let ret: libc::c_int = sd_bus_default_system(ptr::addr_of_mut!(bus)); + if ret < 0 as libc::c_int { + *__errno_location() = -ret; + log::error!( + "Failed to open D-Bus connection: {:?}", + strerror(*__errno_location()), + ); + return; + } + let source: *mut wl_event_source = wl_event_loop_add_fd( + state.event_loop, + sd_bus_get_fd(bus), + WL_EVENT_READABLE as libc::c_int as u32, + dbus_event as unsafe extern "C" fn(libc::c_int, u32, *mut libc::c_void) -> libc::c_int, + bus.cast::(), + ); + wl_event_source_check(source); + set_session(); +} +unsafe extern "C" fn setup_sleep_listener() { + let ret: libc::c_int = sd_bus_match_signal( + bus, + ptr::null_mut(), + (b"org.freedesktop.login1\0" as *const u8).cast::(), + (b"/org/freedesktop/login1\0" as *const u8).cast::(), + (b"org.freedesktop.login1.Manager\0" as *const u8).cast::(), + (b"PrepareForSleep\0" as *const u8).cast::(), + Some( + prepare_for_sleep + as unsafe extern "C" fn( + *mut sd_bus_message, + *mut libc::c_void, + *mut sd_bus_error, + ) -> libc::c_int, + ), + ptr::null_mut(), + ); + if ret < 0 as libc::c_int { + *__errno_location() = -ret; + log::error!( + "Failed to add D-Bus signal match : sleep: {:?}", + strerror(*__errno_location()) + ); + return; + } + acquire_inhibitor_lock( + (b"sleep\0" as *const u8).cast::(), + (b"delay\0" as *const u8).cast::(), + ptr::addr_of_mut!(sleep_lock_fd), + ); +} +unsafe extern "C" fn setup_lock_listener() { + let ret: libc::c_int = sd_bus_match_signal( + bus, + ptr::null_mut(), + (b"org.freedesktop.login1\0" as *const u8).cast::(), + session_name, + (b"org.freedesktop.login1.Session\0" as *const u8).cast::(), + (b"Lock\0" as *const u8).cast::(), + Some( + handle_lock + as unsafe extern "C" fn( + *mut sd_bus_message, + *mut libc::c_void, + *mut sd_bus_error, + ) -> libc::c_int, + ), + ptr::null_mut(), + ); + if ret < 0 as libc::c_int { + *__errno_location() = -ret; + log::error!( + "Failed to add D-Bus signal match : lock: {:?}", + strerror(*__errno_location()) + ); + } +} +unsafe extern "C" fn setup_unlock_listener() { + let ret: libc::c_int = sd_bus_match_signal( + bus, + ptr::null_mut(), + (b"org.freedesktop.login1\0" as *const u8).cast::(), + session_name, + (b"org.freedesktop.login1.Session\0" as *const u8).cast::(), + (b"Unlock\0" as *const u8).cast::(), + Some( + handle_unlock + as unsafe extern "C" fn( + *mut sd_bus_message, + *mut libc::c_void, + *mut sd_bus_error, + ) -> libc::c_int, + ), + ptr::null_mut(), + ); + if ret < 0 as libc::c_int { + *__errno_location() = -ret; + log::error!( + "Failed to add D-Bus signal match : unlock: {:?}", + strerror(*__errno_location()) + ); + } +} +unsafe extern "C" fn setup_property_changed_listener() { + let ret: libc::c_int = sd_bus_match_signal( + bus, + ptr::null_mut(), + ptr::null(), + (b"/org/freedesktop/login1\0" as *const u8).cast::(), + (b"org.freedesktop.DBus.Properties\0" as *const u8).cast::(), + (b"PropertiesChanged\0" as *const u8).cast::(), + Some( + handle_property_changed + as unsafe extern "C" fn( + *mut sd_bus_message, + *mut libc::c_void, + *mut sd_bus_error, + ) -> libc::c_int, + ), + ptr::null_mut(), + ); + if ret < 0 as libc::c_int { + *__errno_location() = -ret; + log::error!( + "Failed to add D-Bus signal match : property changed: {:?}", + strerror(*__errno_location()) + ); + } +} +unsafe extern "C" fn seat_handle_capabilities( + data: *mut libc::c_void, + _seat_0: *mut wl_seat, + capabilities: u32, +) { + let self_0: *mut seat = data.cast::(); + (*self_0).capabilities = capabilities; +} +unsafe extern "C" fn seat_handle_name( + data: *mut libc::c_void, + _seat_0: *mut wl_seat, + name: *const libc::c_char, +) { + let self_0: *mut seat = data.cast::(); + (*self_0).name = strdup(name); +} +static mut wl_seat_listener: wl_seat_listener = wl_seat_listener { + capabilities: Some( + seat_handle_capabilities + as unsafe extern "C" fn(*mut libc::c_void, *mut wl_seat, u32) -> (), + ), + name: Some( + seat_handle_name + as unsafe extern "C" fn(*mut libc::c_void, *mut wl_seat, *const libc::c_char) -> (), + ), +}; +unsafe extern "C" fn handle_global( + _data: *mut libc::c_void, + registry: *mut wl_registry, + name: u32, + interface: *const libc::c_char, + _version: u32, +) { + if strcmp(interface, ext_idle_notifier_v1_interface.name) == 0 as libc::c_int { + idle_notifier = wl_registry_bind( + registry, + name, + ptr::addr_of!(ext_idle_notifier_v1_interface).cast(), + 1 as libc::c_int as u32, + ) + .cast::(); + } else if strcmp(interface, wl_seat_interface.name) == 0 as libc::c_int { + let s: *mut seat = calloc(1, ::core::mem::size_of::()).cast::(); + (*s).proxy = wl_registry_bind(registry, name, &wl_seat_interface, 2 as libc::c_int as u32) + .cast::(); + wl_seat_add_listener((*s).proxy, ptr::addr_of!(wl_seat_listener), s.cast()); + wl_list_insert(&mut state.seats, &mut (*s).link); + } +} +unsafe extern "C" fn handle_global_remove( + _data: *mut libc::c_void, + _registry: *mut wl_registry, + _name: u32, +) { +} +static mut registry_listener: wl_registry_listener = wl_registry_listener { + global: Some( + handle_global + as unsafe extern "C" fn( + *mut libc::c_void, + *mut wl_registry, + u32, + *const libc::c_char, + u32, + ) -> (), + ), + global_remove: Some( + handle_global_remove + as unsafe extern "C" fn(*mut libc::c_void, *mut wl_registry, u32) -> (), + ), +}; +unsafe extern "C" fn destroy_cmd_timer(cmd: *mut swayidle_timeout_cmd) { + if !((*cmd).idle_notification).is_null() { + ext_idle_notification_v1_destroy((*cmd).idle_notification); + (*cmd).idle_notification = ptr::null_mut(); + } +} +unsafe extern "C" fn register_timeout(cmd: *mut swayidle_timeout_cmd, timeout: libc::c_int) { + destroy_cmd_timer(cmd); + if timeout < 0 as libc::c_int { + log::debug!("Not registering idle timeout"); + return; + } + log::debug!("Register with timeout: {timeout:?}"); + (*cmd).idle_notification = + ext_idle_notifier_v1_get_idle_notification(idle_notifier, timeout as u32, seat); + ext_idle_notification_v1_add_listener( + (*cmd).idle_notification, + ptr::addr_of!(idle_notification_listener), + cmd.cast(), + ); + (*cmd).registered_timeout = timeout; +} +unsafe extern "C" fn enable_timeouts() { + if state.timeouts_enabled { + return; + } + if get_logind_idle_inhibit() { + log::info!("Not enabling timeouts: idle inhibitor found"); + return; + } + log::debug!("Enable idle timeouts"); + state.timeouts_enabled = 1 as libc::c_int != 0; + let mut cmd: *mut swayidle_timeout_cmd; + cmd = state + .timeout_cmds + .next + .cast::() + .offset(-(0 as libc::c_ulong as isize)) + .cast::(); + while ptr::addr_of_mut!((*cmd).link) != ptr::addr_of_mut!(state.timeout_cmds) { + register_timeout(cmd, (*cmd).timeout); + cmd = (*cmd) + .link + .next + .cast::() + .offset(-(0 as libc::c_ulong as isize)) + .cast::(); + } +} +unsafe extern "C" fn disable_timeouts() { + if !state.timeouts_enabled { + return; + } + log::debug!("Disable idle timeouts"); + state.timeouts_enabled = 0 as libc::c_int != 0; + let mut cmd: *mut swayidle_timeout_cmd; + cmd = state + .timeout_cmds + .next + .cast::() + .offset(-(0 as libc::c_ulong as isize)) + .cast::(); + while ptr::addr_of_mut!((*cmd).link) != ptr::addr_of_mut!(state.timeout_cmds) { + destroy_cmd_timer(cmd); + cmd = (*cmd) + .link + .next + .cast::() + .offset(-(0 as libc::c_ulong as isize)) + .cast::(); + } + if state.logind_idlehint { + set_idle_hint(0 as libc::c_int != 0); + } +} +unsafe extern "C" fn handle_idled(data: *mut libc::c_void, _notif: *mut ext_idle_notification_v1) { + let cmd: *mut swayidle_timeout_cmd = data.cast::(); + (*cmd).resume_pending = 1 as libc::c_int != 0; + log::debug!("idle state"); + if (*cmd).idlehint { + set_idle_hint(1 as libc::c_int != 0); + } else if !((*cmd).idle_cmd).is_null() { + cmd_exec((*cmd).idle_cmd); + } +} +unsafe extern "C" fn handle_resumed( + data: *mut libc::c_void, + _notif: *mut ext_idle_notification_v1, +) { + let cmd: *mut swayidle_timeout_cmd = data.cast::(); + (*cmd).resume_pending = 0 as libc::c_int != 0; + log::debug!("active state"); + if (*cmd).registered_timeout != (*cmd).timeout { + register_timeout(cmd, (*cmd).timeout); + } + if (*cmd).idlehint { + set_idle_hint(0 as libc::c_int != 0); + } else if !((*cmd).resume_cmd).is_null() { + cmd_exec((*cmd).resume_cmd); + } +} +static mut idle_notification_listener: ext_idle_notification_v1_listener = + ext_idle_notification_v1_listener { + idled: Some( + handle_idled + as unsafe extern "C" fn(*mut libc::c_void, *mut ext_idle_notification_v1) -> (), + ), + resumed: Some( + handle_resumed + as unsafe extern "C" fn(*mut libc::c_void, *mut ext_idle_notification_v1) -> (), + ), + }; +unsafe extern "C" fn parse_command( + argc: libc::c_int, + argv: *mut *mut libc::c_char, +) -> *mut libc::c_char { + if argc < 1 as libc::c_int { + log::error!("Missing command"); + return ptr::null_mut(); + } + log::debug!("Command: {:?}", *argv.offset(0 as libc::c_int as isize)); + strdup(*argv.offset(0 as libc::c_int as isize)) +} +unsafe extern "C" fn build_timeout_cmd( + _argc: libc::c_int, + argv: *mut *mut libc::c_char, +) -> *mut swayidle_timeout_cmd { + *__errno_location() = 0 as libc::c_int; + let mut endptr: *mut libc::c_char = ptr::null_mut(); + let seconds: libc::c_int = strtoul( + *argv.offset(1 as libc::c_int as isize), + &mut endptr, + 10 as libc::c_int, + ) as libc::c_int; + if *__errno_location() != 0 as libc::c_int || i32::from(*endptr) != '\0' as i32 { + log::error!( + "Invalid {:?} parameter '{:?}', it should be a numeric value representing seconds", + *argv.offset(0 as libc::c_int as isize), + *argv.offset(1 as libc::c_int as isize), + ); + exit(-(1 as libc::c_int)); + } + let cmd: *mut swayidle_timeout_cmd = + calloc(1, ::core::mem::size_of::()).cast::(); + (*cmd).idlehint = 0 as libc::c_int != 0; + (*cmd).resume_pending = 0 as libc::c_int != 0; + if seconds > 0 as libc::c_int { + (*cmd).timeout = seconds * 1000 as libc::c_int; + } else { + (*cmd).timeout = -(1 as libc::c_int); + } + cmd +} +unsafe extern "C" fn parse_timeout(argc: libc::c_int, argv: *mut *mut libc::c_char) -> libc::c_int { + if argc < 3 as libc::c_int { + log::error!("Too few parameters to timeout command. Usage: timeout "); + exit(-(1 as libc::c_int)); + } + let cmd: *mut swayidle_timeout_cmd = build_timeout_cmd(argc, argv); + log::debug!("Register idle timeout at {} ms", (*cmd).timeout,); + log::debug!("Setup idle"); + (*cmd).idle_cmd = parse_command( + argc - 2 as libc::c_int, + &mut *argv.offset(2 as libc::c_int as isize), + ); + let result: libc::c_int = if argc >= 5 as libc::c_int + && strcmp( + (b"resume\0" as *const u8).cast::(), + *argv.offset(3 as libc::c_int as isize), + ) == 0 + { + log::debug!("Setup resume"); + (*cmd).resume_cmd = parse_command( + argc - 4 as libc::c_int, + &mut *argv.offset(4 as libc::c_int as isize), + ); + 5 + } else { + 3 + }; + wl_list_insert(&mut state.timeout_cmds, &mut (*cmd).link); + result +} +unsafe extern "C" fn parse_sleep(argc: libc::c_int, argv: *mut *mut libc::c_char) -> libc::c_int { + if argc < 2 as libc::c_int { + log::error!("Too few parameters to before-sleep command. Usage: before-sleep "); + exit(-(1 as libc::c_int)); + } + state.before_sleep_cmd = parse_command( + argc - 1 as libc::c_int, + &mut *argv.offset(1 as libc::c_int as isize), + ); + if !(state.before_sleep_cmd).is_null() { + log::debug!("Setup sleep lock: {:?}", state.before_sleep_cmd); + } + 2 as libc::c_int +} +unsafe extern "C" fn parse_resume(argc: libc::c_int, argv: *mut *mut libc::c_char) -> libc::c_int { + if argc < 2 as libc::c_int { + log::error!("Too few parameters to after-resume command. Usage: after-resume "); + exit(-(1 as libc::c_int)); + } + state.after_resume_cmd = parse_command( + argc - 1 as libc::c_int, + &mut *argv.offset(1 as libc::c_int as isize), + ); + if !(state.after_resume_cmd).is_null() { + log::debug!("Setup resume hook: {:?}", state.after_resume_cmd,); + } + 2 as libc::c_int +} +unsafe extern "C" fn parse_lock(argc: libc::c_int, argv: *mut *mut libc::c_char) -> libc::c_int { + if argc < 2 as libc::c_int { + log::error!("Too few parameters to lock command. Usage: lock "); + exit(-(1 as libc::c_int)); + } + state.logind_lock_cmd = parse_command( + argc - 1 as libc::c_int, + &mut *argv.offset(1 as libc::c_int as isize), + ); + if !(state.logind_lock_cmd).is_null() { + log::debug!("Setup lock hook: {:?}", state.logind_lock_cmd,); + } + 2 as libc::c_int +} +unsafe extern "C" fn parse_unlock(argc: libc::c_int, argv: *mut *mut libc::c_char) -> libc::c_int { + if argc < 2 as libc::c_int { + log::error!("Too few parameters to unlock command. Usage: unlock "); + exit(-(1 as libc::c_int)); + } + state.logind_unlock_cmd = parse_command( + argc - 1 as libc::c_int, + &mut *argv.offset(1 as libc::c_int as isize), + ); + if !(state.logind_unlock_cmd).is_null() { + log::debug!("Setup unlock hook: {:?}", state.logind_unlock_cmd,); + } + 2 as libc::c_int +} +unsafe extern "C" fn parse_idlehint( + argc: libc::c_int, + argv: *mut *mut libc::c_char, +) -> libc::c_int { + if state.logind_idlehint { + log::error!("Cannot add multiple idlehint events"); + exit(-(1 as libc::c_int)); + } + if argc < 2 as libc::c_int { + log::error!("Too few parameters to idlehint command. Usage: idlehint "); + exit(-(1 as libc::c_int)); + } + let cmd: *mut swayidle_timeout_cmd = build_timeout_cmd(argc, argv); + (*cmd).idlehint = 1 as libc::c_int != 0; + log::debug!("Register idlehint timeout at {} ms", (*cmd).timeout,); + wl_list_insert(&mut state.timeout_cmds, &mut (*cmd).link); + state.logind_idlehint = 1 as libc::c_int != 0; + 2 as libc::c_int +} +unsafe extern "C" fn parse_args( + argc: libc::c_int, + argv: *mut *mut libc::c_char, + config_path: *mut *mut libc::c_char, +) -> libc::c_int { + let mut c: libc::c_int; + loop { + c = getopt( + argc, + argv.cast_const(), + (b"C:hdwS:\0" as *const u8).cast::(), + ); + if c == -1 { + break; + } + match c { + 67 => { + free((*config_path).cast::()); + *config_path = strdup(optarg); + } + 100 => { + swayidle_log_init(LOG_DEBUG); + } + 119 => { + state.wait = 1 as libc::c_int != 0; + } + 83 => { + state.seat_name = strdup(optarg); + } + 104 | 63 => { + printf( + (b"Usage: %s [OPTIONS]\n\0" as *const u8).cast::(), + *argv.offset(0 as libc::c_int as isize), + ); + printf((b" -h\tthis help menu\n\0" as *const u8).cast::()); + printf((b" -C\tpath to config file\n\0" as *const u8).cast::()); + printf((b" -d\tdebug\n\0" as *const u8).cast::()); + printf( + (b" -w\twait for command to finish\n\0" as *const u8).cast::(), + ); + printf( + (b" -S\tpick the seat to work with\n\0" as *const u8).cast::(), + ); + return 1 as libc::c_int; + } + _ => return 1 as libc::c_int, + } + } + let mut i: libc::c_int = optind; + while i < argc { + if strcmp( + (b"timeout\0" as *const u8).cast::(), + *argv.offset(i as isize), + ) == 0 + { + log::debug!("Got timeout"); + i += parse_timeout(argc - i, &mut *argv.offset(i as isize)); + } else if strcmp( + (b"before-sleep\0" as *const u8).cast::(), + *argv.offset(i as isize), + ) == 0 + { + log::debug!("Got before-sleep"); + i += parse_sleep(argc - i, &mut *argv.offset(i as isize)); + } else if strcmp( + (b"after-resume\0" as *const u8).cast::(), + *argv.offset(i as isize), + ) == 0 + { + log::debug!("Got after-resume"); + i += parse_resume(argc - i, &mut *argv.offset(i as isize)); + } else if strcmp( + (b"lock\0" as *const u8).cast::(), + *argv.offset(i as isize), + ) == 0 + { + log::debug!("Got lock"); + i += parse_lock(argc - i, &mut *argv.offset(i as isize)); + } else if strcmp( + (b"unlock\0" as *const u8).cast::(), + *argv.offset(i as isize), + ) == 0 + { + log::debug!("Got unlock"); + i += parse_unlock(argc - i, &mut *argv.offset(i as isize)); + } else if strcmp( + (b"idlehint\0" as *const u8).cast::(), + *argv.offset(i as isize), + ) == 0 + { + log::debug!("Got idlehint"); + i += parse_idlehint(argc - i, &mut *argv.offset(i as isize)); + } else { + log::error!("Unsupported command '{:?}'", *argv.offset(i as isize),); + return 1 as libc::c_int; + } + } + 0 as libc::c_int +} +unsafe extern "C" fn handle_signal(sig: libc::c_int, _data: *mut libc::c_void) -> libc::c_int { + let mut cmd: *mut swayidle_timeout_cmd; + match sig { + 2 | 15 => { + log::debug!("Got SIGTERM"); + cmd = state + .timeout_cmds + .next + .cast::() + .offset(-(0 as libc::c_ulong as isize)) + .cast::(); + while ptr::addr_of_mut!((*cmd).link) != ptr::addr_of_mut!(state.timeout_cmds) { + if (*cmd).resume_pending { + handle_resumed(cmd.cast::(), ptr::null_mut()); + } + cmd = (*cmd) + .link + .next + .cast::() + .offset(-(0 as libc::c_ulong as isize)) + .cast::(); + } + sway_terminate(0 as libc::c_int); + return 0 as libc::c_int; + } + 10 => { + log::debug!("Got SIGUSR1"); + cmd = state + .timeout_cmds + .next + .cast::() + .offset(-(0 as libc::c_ulong as isize)) + .cast::(); + while ptr::addr_of_mut!((*cmd).link) != ptr::addr_of_mut!(state.timeout_cmds) { + register_timeout(cmd, 0 as libc::c_int); + cmd = (*cmd) + .link + .next + .cast::() + .offset(-(0 as libc::c_ulong as isize)) + .cast::(); + } + return 1 as libc::c_int; + } + _ => {} + } + abort(); +} +unsafe extern "C" fn display_event( + _fd: libc::c_int, + mask: u32, + _data: *mut libc::c_void, +) -> libc::c_int { + if mask & WL_EVENT_HANGUP as libc::c_int as libc::c_uint != 0 + || mask & WL_EVENT_ERROR as libc::c_int as libc::c_uint != 0 + { + sway_terminate(0 as libc::c_int); + } + let mut count: libc::c_int = if mask & WL_EVENT_READABLE as libc::c_int as libc::c_uint != 0 { + wl_display_dispatch(state.display) + } else { + 0 + }; + if mask & WL_EVENT_WRITABLE as libc::c_int as libc::c_uint != 0 { + wl_display_flush(state.display); + } + if mask == 0 as libc::c_int as libc::c_uint { + count = wl_display_dispatch_pending(state.display); + wl_display_flush(state.display); + } + if count < 0 as libc::c_int { + log::error!( + "wl_display_dispatch failed, exiting: {:?}", + strerror(*__errno_location()), + ); + sway_terminate(0 as libc::c_int); + } + count +} +unsafe extern "C" fn get_config_path() -> *mut libc::c_char { + static mut config_paths: [*mut libc::c_char; 3] = [ + (b"$XDG_CONFIG_HOME/swayidle/config\0" as *const u8) + .cast::() + .cast_mut(), + (b"$HOME/.swayidle/config\0" as *const u8) + .cast::() + .cast_mut(), + (b"/usr/local/etc/swayidle/config\0" as *const u8) + .cast::() + .cast_mut(), + ]; + let config_home: *mut libc::c_char = + getenv((b"XDG_CONFIG_HOME\0" as *const u8).cast::()); + if config_home.is_null() + || i32::from(*config_home.offset(0 as libc::c_int as isize)) == '\n' as i32 + { + config_paths[0 as libc::c_int as usize] = (b"$HOME/.config/swayidle/config\0" as *const u8) + .cast::() + .cast_mut(); + } + let mut p: wordexp_t = wordexp_t { + we_wordc: 0, + we_wordv: ptr::null_mut(), + we_offs: 0, + }; + let mut path: *mut libc::c_char; + let mut i: size_t = 0 as libc::c_int as size_t; + while i + < (::core::mem::size_of::<[*mut libc::c_char; 3]>()) + .wrapping_div(::core::mem::size_of::<*mut libc::c_char>()) + { + if wordexp(config_paths[i as usize], &mut p, 0 as libc::c_int) == 0 as libc::c_int { + path = strdup(*(p.we_wordv).offset(0 as libc::c_int as isize)); + wordfree(&mut p); + if !path.is_null() && access(path, 4 as libc::c_int) == 0 as libc::c_int { + return path; + } + free(path.cast::()); + } + i = i.wrapping_add(1); + } + ptr::null_mut() +} +unsafe extern "C" fn load_config(config_path: *const libc::c_char) -> libc::c_int { + let f: *mut FILE = fopen(config_path, (b"r\0" as *const u8).cast::()); + if f.is_null() { + return -(2 as libc::c_int); + } + let mut lineno: size_t = 0 as libc::c_int as size_t; + let mut line: *mut libc::c_char = ptr::null_mut(); + let mut n: usize = 0; + let mut nread: isize; + loop { + nread = getline(&mut line, &mut n, f); + if nread == -1 { + break; + } + lineno = lineno.wrapping_add(1); + if i32::from(*line.offset(nread - 1)) == '\n' as i32 { + *line.offset(nread - 1) = '\0' as i32 as libc::c_char; + } + if strlen(line) == 0 || i32::from(*line.offset(0 as libc::c_int as isize)) == '#' as i32 { + continue; + } + let mut i: usize = 0; + while i32::from(*line.add(i)) != '\0' as i32 && i32::from(*line.add(i)) != ' ' as i32 { + i = i.wrapping_add(1); + } + let mut p: wordexp_t = wordexp_t { + we_wordc: 0, + we_wordv: ptr::null_mut(), + we_offs: 0, + }; + wordexp(line, &mut p, 0 as libc::c_int); + if strncmp((b"timeout\0" as *const u8).cast::(), line, i) == 0 as libc::c_int + { + parse_timeout(p.we_wordc as libc::c_int, p.we_wordv); + } else if strncmp( + (b"before-sleep\0" as *const u8).cast::(), + line, + i, + ) == 0 as libc::c_int + { + parse_sleep(p.we_wordc as libc::c_int, p.we_wordv); + } else if strncmp( + (b"after-resume\0" as *const u8).cast::(), + line, + i, + ) == 0 as libc::c_int + { + parse_resume(p.we_wordc as libc::c_int, p.we_wordv); + } else if strncmp((b"lock\0" as *const u8).cast::(), line, i) + == 0 as libc::c_int + { + parse_lock(p.we_wordc as libc::c_int, p.we_wordv); + } else if strncmp((b"unlock\0" as *const u8).cast::(), line, i) + == 0 as libc::c_int + { + parse_unlock(p.we_wordc as libc::c_int, p.we_wordv); + } else if strncmp((b"idlehint\0" as *const u8).cast::(), line, i) + == 0 as libc::c_int + { + parse_idlehint(p.we_wordc as libc::c_int, p.we_wordv); + } else { + *line.add(i) = 0 as libc::c_int as libc::c_char; + log::error!("Unexpected keyword {line:?} in line {lineno}"); + free(line.cast::()); + return -(22 as libc::c_int); + } + wordfree(&mut p); + } + free(line.cast::()); + fclose(f); + 0 +} +unsafe fn main_0(argc: libc::c_int, argv: *mut *mut libc::c_char) -> libc::c_int { + swayidle_init(); + let mut config_path: *mut libc::c_char = ptr::null_mut(); + if parse_args(argc, argv, &mut config_path) != 0 as libc::c_int { + swayidle_finish(); + free(config_path.cast::()); + return -(1 as libc::c_int); + } + if config_path.is_null() { + config_path = get_config_path(); + } + let config_load: libc::c_int = if config_path.is_null() { + -2 + } else { + load_config(config_path) + }; + if config_load == -(2 as libc::c_int) { + log::debug!("No config file found."); + } else if config_load == -(22 as libc::c_int) { + log::error!("Config file {config_path:?} has errors, exiting."); + exit(-(1 as libc::c_int)); + } else { + log::debug!("Loaded config at {config_path:?}",); + } + free(config_path.cast::()); + state.event_loop = wl_event_loop_create(); + wl_event_loop_add_signal( + state.event_loop, + 2 as libc::c_int, + handle_signal as unsafe extern "C" fn(libc::c_int, *mut libc::c_void) -> libc::c_int, + ptr::null_mut(), + ); + wl_event_loop_add_signal( + state.event_loop, + 15 as libc::c_int, + handle_signal as unsafe extern "C" fn(libc::c_int, *mut libc::c_void) -> libc::c_int, + ptr::null_mut(), + ); + wl_event_loop_add_signal( + state.event_loop, + 10 as libc::c_int, + handle_signal as unsafe extern "C" fn(libc::c_int, *mut libc::c_void) -> libc::c_int, + ptr::null_mut(), + ); + state.display = wl_display_connect(ptr::null()); + if (state.display).is_null() { + log::error!("Unable to connect to the compositor. If your compositor is running, check or set the WAYLAND_DISPLAY environment variable."); + swayidle_finish(); + return -(3 as libc::c_int); + } + let registry: *mut wl_registry = wl_display_get_registry(state.display); + wl_registry_add_listener( + registry, + ptr::addr_of_mut!(registry_listener), + ptr::null_mut(), + ); + wl_display_roundtrip(state.display); + wl_display_roundtrip(state.display); + let mut seat_i: *mut seat; + seat_i = state + .seats + .next + .cast::() + .offset(-(0 as libc::c_ulong as isize)) + .cast::(); + while ptr::addr_of_mut!((*seat_i).link) != ptr::addr_of_mut!(state.seats) { + if (state.seat_name).is_null() + || strcmp((*seat_i).name, state.seat_name) == 0 as libc::c_int + { + seat = (*seat_i).proxy; + } + seat_i = (*seat_i) + .link + .next + .cast::() + .offset(-(0 as libc::c_ulong as isize)) + .cast::(); + } + if idle_notifier.is_null() { + log::error!("Compositor doesn't support idle protocol"); + swayidle_finish(); + return -(4 as libc::c_int); + } + if seat.is_null() { + if state.seat_name.is_null() { + log::error!("No seat found"); + } else { + log::error!("Seat {:?} not found", state.seat_name,); + } + swayidle_finish(); + return -(5 as libc::c_int); + } + let mut should_run: bool = wl_list_empty(&state.timeout_cmds) == 0; + connect_to_bus(); + setup_property_changed_listener(); + if !(state.before_sleep_cmd).is_null() || !(state.after_resume_cmd).is_null() { + should_run = 1 as libc::c_int != 0; + setup_sleep_listener(); + } + if !(state.logind_lock_cmd).is_null() { + should_run = 1 as libc::c_int != 0; + setup_lock_listener(); + } + if !(state.logind_unlock_cmd).is_null() { + should_run = 1 as libc::c_int != 0; + setup_unlock_listener(); + } + if state.logind_idlehint { + set_idle_hint(0 as libc::c_int != 0); + } + if !should_run { + log::info!("No command specified! Nothing to do, will exit"); + sway_terminate(0 as libc::c_int); + } + enable_timeouts(); + wl_display_roundtrip(state.display); + let source: *mut wl_event_source = wl_event_loop_add_fd( + state.event_loop, + wl_display_get_fd(state.display), + WL_EVENT_READABLE as libc::c_int as u32, + display_event as unsafe extern "C" fn(libc::c_int, u32, *mut libc::c_void) -> libc::c_int, + ptr::null_mut(), + ); + wl_event_source_check(source); + while wl_event_loop_dispatch(state.event_loop, -(1 as libc::c_int)) != 1 as libc::c_int {} + sway_terminate(0 as libc::c_int); + 0 +} +fn main() { + let mut args: Vec<*mut libc::c_char> = Vec::new(); + for arg in ::std::env::args() { + args.push( + (::std::ffi::CString::new(arg)) + .expect("Failed to convert argument into CString.") + .into_raw(), + ); + } + args.push(::core::ptr::null_mut()); + unsafe { + ::std::process::exit(main_0((args.len() - 1) as libc::c_int, args.as_mut_ptr()) as i32) + } +}