From 847bcd44d9a7002effcebadbc591e8063ae7a71f Mon Sep 17 00:00:00 2001 From: chayleaf Date: Wed, 14 Aug 2024 11:00:40 +0700 Subject: [PATCH] changes --- src/ext_idle_notify_v1_protocol.rs | 88 +- src/main.rs | 1693 ++++++++++++---------------- 2 files changed, 760 insertions(+), 1021 deletions(-) diff --git a/src/ext_idle_notify_v1_protocol.rs b/src/ext_idle_notify_v1_protocol.rs index 36ef58e..89ad59e 100644 --- a/src/ext_idle_notify_v1_protocol.rs +++ b/src/ext_idle_notify_v1_protocol.rs @@ -11,80 +11,56 @@ 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_notify_v1_types: [*const wl_interface; 3] = [ + ptr::addr_of!(ext_idle_notification_v1_interface), + ptr::null(), + 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) - }, + name: b"destroy\0".as_ptr().cast(), + signature: b"\0".as_ptr().cast(), + types: unsafe { ext_idle_notify_v1_types.as_mut_ptr() }, }, 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) - }, + name: b"get_idle_notification\0".as_ptr().cast(), + signature: b"nuo\0".as_ptr().cast(), + types: unsafe { ext_idle_notify_v1_types.as_mut_ptr() }, }, ]; #[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, + name: b"ext_idle_notifier_v1\0".as_ptr().cast(), + version: 1, + request_count: 2, requests: unsafe { ext_idle_notifier_v1_requests.as_ptr() }, - event_count: 0 as libc::c_int, - events: 0 as *const wl_message, + event_count: 0, + events: ptr::null(), }; 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) - }, + name: b"destroy\0".as_ptr().cast(), + signature: b"\0".as_ptr().cast(), + types: unsafe { ext_idle_notify_v1_types.as_mut_ptr() }, }]; 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) - }, + name: b"idled\0".as_ptr().cast(), + signature: b"\0".as_ptr().cast(), + types: unsafe { ext_idle_notify_v1_types.as_mut_ptr() }, }, 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) - }, + name: b"resumed\0".as_ptr().cast(), + signature: b"\0".as_ptr().cast(), + types: unsafe { ext_idle_notify_v1_types.as_mut_ptr() }, }, ]; #[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(), - } +pub static ext_idle_notification_v1_interface: wl_interface = wl_interface { + name: b"ext_idle_notification_v1\0".as_ptr().cast(), + version: 1, + request_count: 1, + requests: unsafe { ext_idle_notification_v1_requests.as_ptr() }, + event_count: 2, + events: unsafe { ext_idle_notification_v1_events.as_ptr() }, }; diff --git a/src/main.rs b/src/main.rs index 23b7c23..f9a8c1d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,15 +4,15 @@ non_upper_case_globals, clippy::missing_safety_doc )] -use std::{borrow::Cow, ffi::CStr, mem::MaybeUninit, os::raw::c_void, ptr}; +use std::{borrow::Cow, env, ffi::CStr, mem, mem::MaybeUninit, os::raw::c_void, process, 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, + getenv, getline, getopt, getpid, memset, printf, sigemptyset, signal, sigprocmask, sigset_t, + size_t, sprintf, strcmp, strdup, strlen, strncmp, strstr, strtoul, waitpid, }; use libsystemd_sys::bus::{ sd_bus, sd_bus_call_method, sd_bus_default_system, sd_bus_error, sd_bus_error_free, @@ -32,7 +32,7 @@ use wayland_sys::{ 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, + wl_event_loop_destroy, wl_event_loop_dispatch, wl_event_source_check, }, }; @@ -163,15 +163,15 @@ struct seat { } #[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, + wl_proxy_marshal_flags( + wl_display.cast(), + 1, ptr::addr_of!(wl_registry_interface), - wl_proxy_get_version(wl_display.cast::()), - 0 as libc::c_int as u32, + wl_proxy_get_version(wl_display.cast()), + 0, ptr::null_mut::(), - ); - registry.cast() + ) + .cast() } #[inline] unsafe extern "C" fn wl_registry_add_listener( @@ -179,7 +179,7 @@ unsafe extern "C" fn wl_registry_add_listener( listener: *mut wl_registry_listener, data: *mut libc::c_void, ) -> libc::c_int { - wl_proxy_add_listener(wl_registry.cast::(), listener.cast(), data) + wl_proxy_add_listener(wl_registry.cast(), listener.cast(), data) } #[inline] unsafe extern "C" fn wl_registry_bind( @@ -188,18 +188,18 @@ unsafe extern "C" fn wl_registry_bind( 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, + wl_proxy_marshal_flags( + wl_registry.cast(), + 0, interface, version, - 0 as libc::c_int as u32, + 0, name, (*interface).name, version, ptr::null_mut::(), - ); - id.cast() + ) + .cast() } #[inline] unsafe extern "C" fn wl_seat_add_listener( @@ -207,7 +207,7 @@ unsafe extern "C" fn wl_seat_add_listener( 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) + wl_proxy_add_listener(wl_seat.cast(), listener.cast_mut().cast(), data) } #[inline] unsafe extern "C" fn ext_idle_notifier_v1_get_idle_notification( @@ -215,17 +215,17 @@ unsafe extern "C" fn ext_idle_notifier_v1_get_idle_notification( 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, + wl_proxy_marshal_flags( + ext_idle_notifier_v1.cast(), + 1, 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, + wl_proxy_get_version(ext_idle_notifier_v1.cast()), + 0, ptr::null_mut::(), timeout, seat_0, - ); - id.cast() + ) + .cast() } #[inline] unsafe extern "C" fn ext_idle_notification_v1_add_listener( @@ -234,7 +234,7 @@ unsafe extern "C" fn ext_idle_notification_v1_add_listener( data: *mut libc::c_void, ) -> libc::c_int { wl_proxy_add_listener( - ext_idle_notification_v1.cast::(), + ext_idle_notification_v1.cast(), listener.cast_mut().cast(), data, ) @@ -244,32 +244,32 @@ 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, + ext_idle_notification_v1.cast(), + 0, ptr::null(), - wl_proxy_get_version(ext_idle_notification_v1.cast::()), - ((1 as libc::c_int) << 0 as libc::c_int) as u32, + wl_proxy_get_version(ext_idle_notification_v1.cast()), + 1, ); } -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(); +static mut idle_notifier: *mut ext_idle_notifier_v1 = ptr::null_mut(); +static mut seat: *mut wl_seat = ptr::null_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(), + display: ptr::null_mut(), + event_loop: ptr::null_mut(), timeout_cmds: wl_list { - prev: (0 as *const wl_list).cast_mut(), - next: (0 as *const wl_list).cast_mut(), + prev: ptr::null_mut(), + next: ptr::null_mut(), }, seats: wl_list { - prev: (0 as *const wl_list).cast_mut(), - next: (0 as *const wl_list).cast_mut(), + prev: ptr::null_mut(), + next: ptr::null_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(), + seat_name: ptr::null_mut(), + before_sleep_cmd: ptr::null_mut(), + after_resume_cmd: ptr::null_mut(), + logind_lock_cmd: ptr::null_mut(), + logind_unlock_cmd: ptr::null_mut(), logind_idlehint: false, timeouts_enabled: false, wait: false, @@ -288,52 +288,469 @@ unsafe extern "C" fn swayidle_log_init(verbosity: log_importance) { ) .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::(); +impl swayidle_state { + unsafe fn init(&mut self) { + memset(ptr::addr_of_mut!(*self).cast(), 0, mem::size_of::()); + wl_list_init(&mut self.timeout_cmds); + wl_list_init(&mut self.seats); + } + unsafe fn finish(&mut self) { + let mut cmd: *mut swayidle_timeout_cmd = self.timeout_cmds.next.cast(); + let mut tmp: *mut swayidle_timeout_cmd = (*cmd).link.next.cast(); + while ptr::addr_of_mut!((*cmd).link) != ptr::addr_of_mut!(self.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(); + } + free(self.after_resume_cmd.cast()); + free(self.before_sleep_cmd.cast()); + } + unsafe fn sway_terminate(&self, exit_code: libc::c_int) -> ! { + wl_display_disconnect(self.display); + wl_event_loop_destroy(self.event_loop); + exit(exit_code); + } + unsafe fn cmd_exec(&self, param: *mut libc::c_char) { + log::debug!("Cmd exec {}", read_str(param)); + let mut pid = fork(); + match pid { + 0 => { + if !self.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, &set, ptr::null_mut()); + signal(2, 0); + signal(15, 0); + signal(10, 0); + let cmd: [*const libc::c_char; 4] = [ + b"sh\0".as_ptr().cast(), + b"-c\0".as_ptr().cast(), + param, + ptr::null(), + ]; + execvp(cmd[0], cmd.as_ptr()); + log::error!("execve failed!: {}", strerror(*__errno_location()),); + exit(1); + } + pid if pid < 0 => { + log::error!("fork failed: {}", strerror(*__errno_location()),); + exit(1); + } + _ => {} + } + exit(0); + } + pid if pid < 0 => { + log::error!("fork failed: {}", strerror(*__errno_location()),); + } + _ => { + log::debug!("Spawned process {}", read_str(param)); + if self.wait { + log::debug!("Blocking until process exits"); + } + let mut status = 0; + waitpid(pid, &mut status, 0); + if i32::from(self.wait) != 0 && status & 0x7f == 0 { + log::debug!("Process exit status: {}", (status & 0xff00) >> 8,); + } + } + }; + } + unsafe extern "C" fn connect_to_bus(&self) { + let ret = sd_bus_default_system(ptr::addr_of_mut!(bus)); + if ret < 0 { + *__errno_location() = -ret; + log::error!( + "Failed to open D-Bus connection: {}", + strerror(*__errno_location()), + ); + return; + } + let source = wl_event_loop_add_fd( + self.event_loop, + sd_bus_get_fd(bus), + WL_EVENT_READABLE, + dbus_event, + bus.cast(), + ); + wl_event_source_check(source); + set_session(); + } + unsafe fn display_event(&self, mask: u32) -> libc::c_int { + if mask & WL_EVENT_HANGUP != 0 || mask & WL_EVENT_ERROR != 0 { + self.sway_terminate(0); + } + let mut count = if mask & WL_EVENT_READABLE != 0 { + wl_display_dispatch(self.display) + } else { + 0 + }; + if mask & WL_EVENT_WRITABLE != 0 { + wl_display_flush(self.display); + } + if mask == 0 { + count = wl_display_dispatch_pending(self.display); + wl_display_flush(self.display); + } + if count < 0 { + log::error!( + "wl_display_dispatch failed, exiting: {}", + strerror(*__errno_location()), + ); + self.sway_terminate(0); + } + count + } + unsafe fn handle_signal(&self, sig: libc::c_int) -> libc::c_int { + let mut cmd: *mut swayidle_timeout_cmd; + match sig { + 2 | 15 => { + log::debug!("Got SIGTERM"); + cmd = self.timeout_cmds.next.cast(); + while ptr::addr_of!((*cmd).link) != ptr::addr_of!(self.timeout_cmds) { + if (*cmd).resume_pending { + handle_resumed(cmd.cast(), ptr::null_mut()); + } + cmd = (*cmd).link.next.cast(); + } + self.sway_terminate(0); + } + 10 => { + log::debug!("Got SIGUSR1"); + cmd = self.timeout_cmds.next.cast(); + while ptr::addr_of!((*cmd).link) != ptr::addr_of!(self.timeout_cmds) { + register_timeout(cmd, 0); + cmd = (*cmd).link.next.cast(); + } + return 1; + } + _ => {} + } + abort(); + } + unsafe fn parse_args( + &mut self, + argc: usize, + 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 as i32, argv.cast_const(), b"C:hdwS:\0".as_ptr().cast()); + if c == -1 { + break; + } + match c { + 67 => { + free((*config_path).cast()); + *config_path = strdup(optarg); + } + 100 => { + swayidle_log_init(LOG_DEBUG); + } + 119 => { + self.wait = 1 != 0; + } + 83 => { + self.seat_name = strdup(optarg); + } + 104 | 63 => { + printf(b"Usage: %s [OPTIONS]\n\0".as_ptr().cast(), *argv); + printf(b" -h\tthis help menu\n\0".as_ptr().cast()); + printf(b" -C\tpath to config file\n\0".as_ptr().cast()); + printf(b" -d\tdebug\n\0".as_ptr().cast()); + printf(b" -w\twait for command to finish\n\0".as_ptr().cast()); + printf(b" -S\tpick the seat to work with\n\0".as_ptr().cast()); + return 1; + } + _ => return 1, + } + } + let mut i = optind as usize; + while i < argc { + if strcmp(b"timeout\0".as_ptr().cast(), *argv.add(i)) == 0 { + log::debug!("Got timeout"); + i += self.parse_timeout(argc - i, &mut *argv.add(i)); + } else if strcmp(b"before-sleep\0".as_ptr().cast(), *argv.add(i)) == 0 { + log::debug!("Got before-sleep"); + i += self.parse_sleep(argc - i, &mut *argv.add(i)); + } else if strcmp(b"after-resume\0".as_ptr().cast(), *argv.add(i)) == 0 { + log::debug!("Got after-resume"); + i += self.parse_resume(argc - i, &mut *argv.add(i)); + } else if strcmp(b"lock\0".as_ptr().cast(), *argv.add(i)) == 0 { + log::debug!("Got lock"); + i += self.parse_lock(argc - i, &mut *argv.add(i)); + } else if strcmp(b"unlock\0".as_ptr().cast(), *argv.add(i)) == 0 { + log::debug!("Got unlock"); + i += self.parse_unlock(argc - i, &mut *argv.add(i)); + } else if strcmp(b"idlehint\0".as_ptr().cast(), *argv.add(i)) == 0 { + log::debug!("Got idlehint"); + i += self.parse_idlehint(argc - i, &mut *argv.add(i)); + } else { + log::error!("Unsupported command '{}'", read_str(*argv.add(i))); + return 1; + } + } + 0 + } + unsafe fn prepare_for_sleep(&self, msg: *mut sd_bus_message) -> libc::c_int { + let mut going_down = 1; + let ret = sd_bus_message_read(msg, b"b\0".as_ptr().cast(), ptr::addr_of_mut!(going_down)); + if ret < 0 { + *__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_ptr().cast(), + b"delay\0".as_ptr().cast(), + ptr::addr_of_mut!(sleep_lock_fd), + ); + if !self.after_resume_cmd.is_null() { + self.cmd_exec(self.after_resume_cmd); + } + if self.logind_idlehint { + set_idle_hint(false); + } + return 0; + } + if !self.before_sleep_cmd.is_null() { + self.cmd_exec(self.before_sleep_cmd); + } + log::debug!("Prepare for sleep done"); + release_inhibitor_lock(sleep_lock_fd); + 0 + } + unsafe fn handle_lock(&self) -> libc::c_int { + log::debug!("Lock signal received"); + if !self.logind_lock_cmd.is_null() { + self.cmd_exec(self.logind_lock_cmd); + } + log::debug!("Lock command done"); + 0 + } + unsafe fn handle_unlock(&self) -> libc::c_int { + log::debug!("Unlock signal received"); + if self.logind_idlehint { + set_idle_hint(false); + } + if !self.logind_unlock_cmd.is_null() { + self.cmd_exec(self.logind_unlock_cmd); + } + log::debug!("Unlock command done"); + 0 + } + unsafe fn handle_global( + &mut self, + registry: *mut wl_registry, + name: u32, + interface: *const libc::c_char, + ) { + if strcmp(interface, ext_idle_notifier_v1_interface.name) == 0 { + idle_notifier = wl_registry_bind( + registry, + name, + ptr::addr_of!(ext_idle_notifier_v1_interface).cast(), + 1, + ) + .cast(); + } else if strcmp(interface, wl_seat_interface.name) == 0 { + let s: *mut seat = calloc(1, mem::size_of::()).cast(); + (*s).proxy = wl_registry_bind(registry, name, &wl_seat_interface, 2).cast(); + wl_seat_add_listener((*s).proxy, ptr::addr_of!(wl_seat_listener), s.cast()); + wl_list_insert(&mut self.seats, &mut (*s).link); + } + } + unsafe fn enable_timeouts(&mut self) { + if self.timeouts_enabled { + return; + } + if get_logind_idle_inhibit() { + log::info!("Not enabling timeouts: idle inhibitor found"); + return; + } + log::debug!("Enable idle timeouts"); + self.timeouts_enabled = true; + let mut cmd: *mut swayidle_timeout_cmd; + cmd = self.timeout_cmds.next.cast(); + while ptr::addr_of_mut!((*cmd).link) != ptr::addr_of_mut!(self.timeout_cmds) { + register_timeout(cmd, (*cmd).timeout); + cmd = (*cmd).link.next.cast(); + } + } + unsafe extern "C" fn disable_timeouts(&mut self) { + if !self.timeouts_enabled { + return; + } + log::debug!("Disable idle timeouts"); + self.timeouts_enabled = false; + let mut cmd: *mut swayidle_timeout_cmd; + cmd = self.timeout_cmds.next.cast(); + while ptr::addr_of_mut!((*cmd).link) != ptr::addr_of_mut!(self.timeout_cmds) { + destroy_cmd_timer(cmd); + cmd = (*cmd).link.next.cast(); + } + if self.logind_idlehint { + set_idle_hint(false); + } + } + unsafe fn parse_timeout(&mut self, argc: usize, argv: *mut *mut libc::c_char) -> usize { + if argc < 3 { + log::error!( + "Too few parameters to timeout command. Usage: timeout " + ); + exit(-1); + } + let cmd = build_timeout_cmd(argv); + log::debug!("Register idle timeout at {} ms", (*cmd).timeout,); + log::debug!("Setup idle"); + (*cmd).idle_cmd = parse_command(argc - 2, &mut *argv.offset(2)); + let result = if argc >= 5 && strcmp(b"resume\0".as_ptr().cast(), *argv.offset(3)) == 0 { + log::debug!("Setup resume"); + (*cmd).resume_cmd = parse_command(argc - 4, &mut *argv.offset(4)); + 5 + } else { + 3 + }; + wl_list_insert(&mut self.timeout_cmds, &mut (*cmd).link); + result + } + unsafe fn parse_sleep(&mut self, argc: usize, argv: *mut *mut libc::c_char) -> usize { + if argc < 2 { + log::error!( + "Too few parameters to before-sleep command. Usage: before-sleep " + ); + exit(-1); + } + self.before_sleep_cmd = parse_command(argc - 1, &mut *argv.offset(1)); + if !self.before_sleep_cmd.is_null() { + log::debug!("Setup sleep lock: {}", read_str(self.before_sleep_cmd)); + } + 2 + } + unsafe fn parse_resume(&mut self, argc: usize, argv: *mut *mut libc::c_char) -> usize { + if argc < 2 { + log::error!( + "Too few parameters to after-resume command. Usage: after-resume " + ); + exit(-1); + } + self.after_resume_cmd = parse_command(argc - 1, &mut *argv.offset(1)); + if !self.after_resume_cmd.is_null() { + log::debug!("Setup resume hook: {}", read_str(self.after_resume_cmd)); + } + 2 + } + unsafe fn parse_lock(&mut self, argc: usize, argv: *mut *mut libc::c_char) -> usize { + if argc < 2 { + log::error!("Too few parameters to lock command. Usage: lock "); + exit(-1); + } + self.logind_lock_cmd = parse_command(argc - 1, &mut *argv.offset(1)); + if !self.logind_lock_cmd.is_null() { + log::debug!("Setup lock hook: {}", read_str(self.logind_lock_cmd)); + } + 2 + } + unsafe fn parse_unlock(&mut self, argc: usize, argv: *mut *mut libc::c_char) -> usize { + if argc < 2 { + log::error!("Too few parameters to unlock command. Usage: unlock "); + exit(-1); + } + self.logind_unlock_cmd = parse_command(argc - 1, &mut *argv.offset(1)); + if !self.logind_unlock_cmd.is_null() { + log::debug!("Setup unlock hook: {}", read_str(self.logind_unlock_cmd)); + } + 2 + } + unsafe fn parse_idlehint(&mut self, argc: usize, argv: *mut *mut libc::c_char) -> usize { + if self.logind_idlehint { + log::error!("Cannot add multiple idlehint events"); + exit(-1); + } + if argc < 2 { + log::error!("Too few parameters to idlehint command. Usage: idlehint "); + exit(-1); + } + let cmd: *mut swayidle_timeout_cmd = build_timeout_cmd(argv); + (*cmd).idlehint = true; + log::debug!("Register idlehint timeout at {} ms", (*cmd).timeout,); + wl_list_insert(&mut self.timeout_cmds, &mut (*cmd).link); + self.logind_idlehint = true; + 2 + } + unsafe extern "C" fn load_config(&mut self, config_path: *const libc::c_char) -> i32 { + let f = fopen(config_path, b"r\0".as_ptr().cast()); + if f.is_null() { + return -2; + } + let mut lineno: size_t = 0; + let mut line = ptr::null_mut(); + let mut n = 0; + let mut nread; + loop { + nread = getline(&mut line, &mut n, f); + if nread == -1 { + break; + } + lineno = lineno.wrapping_add(1); + if *line.offset(nread - 1) as u8 == b'\n' { + *line.offset(nread - 1) = 0; + } + if strlen(line) == 0 || *line as u8 == b'#' { + continue; + } + let mut i = 0; + while *line.add(i) as u8 != b'\0' && *line.add(i) as u8 != b' ' { + i = i.wrapping_add(1); + } + let mut p = wordexp_t { + we_wordc: 0, + we_wordv: ptr::null_mut(), + we_offs: 0, + }; + wordexp(line, &mut p, 0); + if strncmp(b"timeout\0".as_ptr().cast(), line, i) == 0 { + self.parse_timeout(p.we_wordc, p.we_wordv); + } else if strncmp(b"before-sleep\0".as_ptr().cast(), line, i) == 0 { + self.parse_sleep(p.we_wordc, p.we_wordv); + } else if strncmp(b"after-resume\0".as_ptr().cast(), line, i) == 0 { + self.parse_resume(p.we_wordc, p.we_wordv); + } else if strncmp(b"lock\0".as_ptr().cast(), line, i) == 0 { + self.parse_lock(p.we_wordc, p.we_wordv); + } else if strncmp(b"unlock\0".as_ptr().cast(), line, i) == 0 { + self.parse_unlock(p.we_wordc, p.we_wordv); + } else if strncmp(b"idlehint\0".as_ptr().cast(), line, i) == 0 { + self.parse_idlehint(p.we_wordc, p.we_wordv); + } else { + *line.add(i) = 0; + log::error!("Unexpected keyword {} in line {lineno}", read_str(line)); + free(line.cast::()); + return -22; + } + wordfree(&mut p); + } + free(line.cast()); + fclose(f); + 0 } - 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); +impl Drop for swayidle_state { + fn drop(&mut self) { + unsafe { self.finish() } + } } unsafe fn read_str(ptr: *const libc::c_char) -> Cow<'static, str> { if ptr.is_null() { @@ -342,103 +759,49 @@ unsafe fn read_str(ptr: *const libc::c_char) -> Cow<'static, str> { CStr::from_ptr(ptr).to_string_lossy() } } -unsafe extern "C" fn cmd_exec(param: *mut libc::c_char) { - log::debug!("Cmd exec {}", read_str(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 {}", read_str(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(); +static mut sleep_lock_fd: libc::c_int = -1; +static mut bus: *mut sd_bus = ptr::null_mut(); +static mut session_name: *mut libc::c_char = ptr::null_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 { + let mut msg = ptr::null_mut(); + let mut error = sd_bus_error { name: ptr::null(), message: ptr::null(), need_free: 0, }; - let mut why: [libc::c_char; 35] = [0; 35]; + let mut why = [0; 35]; sprintf( why.as_mut_ptr(), - (b"Swayidle is preventing %s\0" as *const u8).cast::(), + b"Swayidle is preventing %s\0".as_ptr().cast(), type_0, ); - let mut ret: libc::c_int = sd_bus_call_method( + let mut 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"Inhibit\0" as *const u8).cast::(), + b"org.freedesktop.login1\0".as_ptr().cast(), + b"/org/freedesktop/login1\0".as_ptr().cast(), + b"org.freedesktop.login1.Manager\0".as_ptr().cast(), + b"Inhibit\0".as_ptr().cast(), ptr::addr_of_mut!(error), ptr::addr_of_mut!(msg), - (b"ssss\0" as *const u8).cast::(), + b"ssss\0".as_ptr().cast(), type_0, - (b"swayidle\0" as *const u8).cast::(), + b"swayidle\0".as_ptr().cast::(), why.as_mut_ptr(), mode, ); - if ret < 0 as libc::c_int { + if ret < 0 { log::error!( "Failed to send {} inhibit signal: {}", read_str(type_0), read_str(error.message), ); } else { - ret = sd_bus_message_read(msg, (b"h\0" as *const u8).cast::(), fd); - if ret < 0 as libc::c_int { + ret = sd_bus_message_read(msg, b"h\0".as_ptr().cast(), fd); + if ret < 0 { *__errno_location() = -ret; log::error!( "Failed to parse D-Bus response for {} inhibit: {}", @@ -446,8 +809,8 @@ unsafe extern "C" fn acquire_inhibitor_lock( 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 { + *fd = libc::fcntl(*fd, 1030, 3); + if *fd >= 0 { log::debug!("Got {} lock: {}", read_str(type_0), *fd,); } else { log::error!( @@ -462,31 +825,31 @@ unsafe extern "C" fn acquire_inhibitor_lock( sd_bus_message_unref(msg); } unsafe extern "C" fn release_inhibitor_lock(fd: libc::c_int) { - if fd >= 0 as libc::c_int { + if fd >= 0 { 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 { + let mut msg = ptr::null_mut(); + let mut error = sd_bus_error { name: ptr::null(), message: ptr::null(), need_free: 0, }; - let ret: libc::c_int = sd_bus_call_method( + let ret = sd_bus_call_method( bus, - (b"org.freedesktop.login1\0" as *const u8).cast::(), + b"org.freedesktop.login1\0".as_ptr().cast(), session_name, - (b"org.freedesktop.login1.Session\0" as *const u8).cast::(), - (b"SetIdleHint\0" as *const u8).cast::(), + b"org.freedesktop.login1.Session\0".as_ptr().cast(), + b"SetIdleHint\0".as_ptr().cast(), ptr::addr_of_mut!(error), ptr::addr_of_mut!(msg), - (b"b\0" as *const u8).cast::(), + b"b\0".as_ptr().cast(), i32::from(hint), ); - if ret < 0 as libc::c_int { + if ret < 0 { log::error!( "Failed to send SetIdleHint signal: {}", read_str(error.message) @@ -498,25 +861,22 @@ unsafe extern "C" fn set_idle_hint(hint: bool) { 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( + let mut reply = ptr::null_mut(); + let mut ret = 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::(), + b"org.freedesktop.login1\0".as_ptr().cast(), + b"/org/freedesktop/login1\0".as_ptr().cast(), + b"org.freedesktop.login1.Manager\0".as_ptr().cast(), + b"BlockInhibited\0".as_ptr().cast(), ptr::null_mut(), &mut reply, - (b"s\0" as *const u8).cast::(), + b"s\0".as_ptr().cast(), ); if ret >= 0 { - ret = sd_bus_message_read_basic( - reply, - 's' as i32 as libc::c_char, - ptr::addr_of_mut!(locks).cast(), - ); + ret = + sd_bus_message_read_basic(reply, b's' 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(); + res = !strstr(locks, b"idle\0".as_ptr().cast()).is_null(); sd_bus_message_unref(reply); return res; } @@ -527,74 +887,28 @@ unsafe extern "C" fn get_logind_idle_inhibit() -> bool { "Failed to parse get BlockInhibited property: {}", strerror(*__errno_location()) ); - 0 as libc::c_int != 0 + false } 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 + state.prepare_for_sleep(msg) } 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 + state.handle_lock() } 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 + state.handle_unlock() } fn strerror(errno: i32) -> Cow<'static, str> { let p = unsafe { libc::strerror(errno) }; @@ -609,69 +923,58 @@ unsafe extern "C" fn handle_property_changed( _userdata: *mut libc::c_void, _ret_error: *mut sd_bus_error, ) -> libc::c_int { - let mut is_error: bool = false; + let mut is_error = false; 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(), - ); + let mut ret = + sd_bus_message_read_basic(msg, b's' 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 - { + if strcmp(name, b"org.freedesktop.login1.Manager\0".as_ptr().cast()) == 0 { log::debug!("Got PropertyChanged: {}", read_str(name)); ret = sd_bus_message_enter_container( msg, - 'a' as i32 as libc::c_char, - (b"{sv}\0" as *const u8).cast::(), + b'a' as libc::c_char, + b"{sv}\0".as_ptr().cast(), ); - if ret < 0 as libc::c_int { + if ret < 0 { is_error = true; } 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::(), + b'e' as libc::c_char, + b"sv\0".as_ptr().cast(), ); if ret <= 0 { break; } ret = sd_bus_message_read_basic( msg, - 's' as i32 as libc::c_char, + b's' as libc::c_char, ptr::addr_of_mut!(prop).cast(), ); - if ret < 0 as libc::c_int { + if ret < 0 { is_error = true; break; } - if strcmp( - prop, - (b"BlockInhibited\0" as *const u8).cast::(), - ) == 0 - { + if strcmp(prop, b"BlockInhibited\0".as_ptr().cast()) == 0 { if get_logind_idle_inhibit() { log::debug!("Logind idle inhibitor found"); - disable_timeouts(); + state.disable_timeouts(); } else { log::debug!("Logind idle inhibitor not found"); - enable_timeouts(); + state.enable_timeouts(); } - return 0 as libc::c_int; + return 0; } - ret = sd_bus_message_skip(msg, (b"v\0" as *const u8).cast::()); - if ret < 0 as libc::c_int { + ret = sd_bus_message_skip(msg, b"v\0".as_ptr().cast()); + if ret < 0 { is_error = true; break; } ret = sd_bus_message_exit_container(msg); - if ret < 0 as libc::c_int { + if ret < 0 { is_error = true; break; } @@ -679,7 +982,7 @@ unsafe extern "C" fn handle_property_changed( } } if !is_error && ret >= 0 { - return 0 as libc::c_int; + return 0; } } *__errno_location() = -ret; @@ -687,75 +990,73 @@ unsafe extern "C" fn handle_property_changed( "Failed to parse D-Bus response for PropertyChanged: {}", strerror(*__errno_location()) ); - 0 as libc::c_int + 0 } 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 bus_0 = data.cast(); + if mask & WL_EVENT_HANGUP != 0 || mask & WL_EVENT_ERROR != 0 { + state.sway_terminate(0); } - let count: libc::c_int = if mask & WL_EVENT_READABLE as libc::c_int as libc::c_uint != 0 { + let count = if mask & WL_EVENT_READABLE != 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 { + if mask & WL_EVENT_WRITABLE != 0 { sd_bus_flush(bus_0); } - if mask == 0 as libc::c_int as libc::c_uint { + if mask == 0 { sd_bus_flush(bus_0); } - if count < 0 as libc::c_int { + if count < 0 { log::error!( "sd_bus_process failed, exiting: {}", strerror(*__errno_location()) ); - sway_terminate(0 as libc::c_int); + state.sway_terminate(0); } count } unsafe extern "C" fn set_session() { - let mut is_error: bool = false; - let mut msg: *mut sd_bus_message = ptr::null_mut(); - let mut error: sd_bus_error = sd_bus_error { + let mut is_error = false; + let mut msg = ptr::null_mut(); + let mut error = sd_bus_error { name: ptr::null(), message: ptr::null(), - need_free: 0 as libc::c_int, + need_free: 0, }; - let mut session_name_tmp: *const libc::c_char = ptr::null(); - let mut ret: libc::c_int = sd_bus_call_method( + let mut session_name_tmp = ptr::null(); + let mut 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"GetSession\0" as *const u8).cast::(), + b"org.freedesktop.login1\0".as_ptr().cast(), + b"/org/freedesktop/login1\0".as_ptr().cast(), + b"org.freedesktop.login1.Manager\0".as_ptr().cast(), + b"GetSession\0".as_ptr().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::(), + b"s\0".as_ptr().cast(), + b"auto\0".as_ptr().cast::(), ); - if ret < 0 as libc::c_int { + if ret < 0 { log::debug!("GetSession failed: {}", read_str(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::(), + b"org.freedesktop.login1\0".as_ptr().cast(), + b"/org/freedesktop/login1\0".as_ptr().cast(), + b"org.freedesktop.login1.Manager\0".as_ptr().cast(), + b"GetSessionByPID\0".as_ptr().cast(), ptr::addr_of_mut!(error), ptr::addr_of_mut!(msg), - (b"u\0" as *const u8).cast::(), + b"u\0".as_ptr().cast(), getpid(), ); - if ret < 0 as libc::c_int { + if ret < 0 { log::debug!("GetSessionByPID failed: {}", read_str(error.message)); log::error!("Failed to find session"); is_error = true; @@ -764,10 +1065,10 @@ unsafe extern "C" fn set_session() { if !is_error { ret = sd_bus_message_read( msg, - (b"o\0" as *const u8).cast::(), + b"o\0".as_ptr().cast(), ptr::addr_of_mut!(session_name_tmp), ); - if ret < 0 as libc::c_int { + if ret < 0 { log::error!("Failed to read session name"); } else { session_name = strdup(session_name_tmp); @@ -777,45 +1078,18 @@ unsafe extern "C" fn set_session() { 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( + let ret = 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, - ), + b"org.freedesktop.login1\0".as_ptr().cast(), + b"/org/freedesktop/login1\0".as_ptr().cast(), + b"org.freedesktop.login1.Manager\0".as_ptr().cast(), + b"PrepareForSleep\0".as_ptr().cast(), + Some(prepare_for_sleep), ptr::null_mut(), ); - if ret < 0 as libc::c_int { + if ret < 0 { *__errno_location() = -ret; log::error!( "Failed to add D-Bus signal match : sleep: {}", @@ -824,30 +1098,23 @@ unsafe extern "C" fn setup_sleep_listener() { return; } acquire_inhibitor_lock( - (b"sleep\0" as *const u8).cast::(), - (b"delay\0" as *const u8).cast::(), + b"sleep\0".as_ptr().cast(), + b"delay\0".as_ptr().cast(), ptr::addr_of_mut!(sleep_lock_fd), ); } unsafe extern "C" fn setup_lock_listener() { - let ret: libc::c_int = sd_bus_match_signal( + let ret = sd_bus_match_signal( bus, ptr::null_mut(), - (b"org.freedesktop.login1\0" as *const u8).cast::(), + b"org.freedesktop.login1\0".as_ptr().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, - ), + b"org.freedesktop.login1.Session\0".as_ptr().cast(), + b"Lock\0".as_ptr().cast(), + Some(handle_lock), ptr::null_mut(), ); - if ret < 0 as libc::c_int { + if ret < 0 { *__errno_location() = -ret; log::error!( "Failed to add D-Bus signal match : lock: {}", @@ -856,24 +1123,17 @@ unsafe extern "C" fn setup_lock_listener() { } } unsafe extern "C" fn setup_unlock_listener() { - let ret: libc::c_int = sd_bus_match_signal( + let ret = sd_bus_match_signal( bus, ptr::null_mut(), - (b"org.freedesktop.login1\0" as *const u8).cast::(), + b"org.freedesktop.login1\0".as_ptr().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, - ), + b"org.freedesktop.login1.Session\0".as_ptr().cast(), + b"Unlock\0".as_ptr().cast(), + Some(handle_unlock), ptr::null_mut(), ); - if ret < 0 as libc::c_int { + if ret < 0 { *__errno_location() = -ret; log::error!( "Failed to add D-Bus signal match : unlock: {}", @@ -882,24 +1142,17 @@ unsafe extern "C" fn setup_unlock_listener() { } } unsafe extern "C" fn setup_property_changed_listener() { - let ret: libc::c_int = sd_bus_match_signal( + let ret = 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, - ), + b"/org/freedesktop/login1\0".as_ptr().cast(), + b"org.freedesktop.DBus.Properties\0".as_ptr().cast(), + b"PropertiesChanged\0".as_ptr().cast(), + Some(handle_property_changed), ptr::null_mut(), ); - if ret < 0 as libc::c_int { + if ret < 0 { *__errno_location() = -ret; log::error!( "Failed to add D-Bus signal match : property changed: {}", @@ -912,7 +1165,7 @@ unsafe extern "C" fn seat_handle_capabilities( _seat_0: *mut wl_seat, capabilities: u32, ) { - let self_0: *mut seat = data.cast::(); + let self_0: *mut seat = data.cast(); (*self_0).capabilities = capabilities; } unsafe extern "C" fn seat_handle_name( @@ -920,18 +1173,12 @@ unsafe extern "C" fn seat_handle_name( _seat_0: *mut wl_seat, name: *const libc::c_char, ) { - let self_0: *mut seat = data.cast::(); + 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) -> (), - ), + capabilities: Some(seat_handle_capabilities), + name: Some(seat_handle_name), }; unsafe extern "C" fn handle_global( _data: *mut libc::c_void, @@ -940,21 +1187,7 @@ unsafe extern "C" fn handle_global( 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); - } + state.handle_global(registry, name, interface); } unsafe extern "C" fn handle_global_remove( _data: *mut libc::c_void, @@ -963,30 +1196,18 @@ unsafe extern "C" fn handle_global_remove( ) { } 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) -> (), - ), + global: Some(handle_global), + global_remove: Some(handle_global_remove), }; unsafe extern "C" fn destroy_cmd_timer(cmd: *mut swayidle_timeout_cmd) { - if !((*cmd).idle_notification).is_null() { + 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 { + if timeout < 0 { log::debug!("Not registering idle timeout"); return; } @@ -1000,592 +1221,150 @@ unsafe extern "C" fn register_timeout(cmd: *mut swayidle_timeout_cmd, timeout: l ); (*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; + let cmd: *mut swayidle_timeout_cmd = data.cast(); + (*cmd).resume_pending = true; 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); + set_idle_hint(true); + } else if !(*cmd).idle_cmd.is_null() { + state.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; + let cmd: *mut swayidle_timeout_cmd = data.cast(); + (*cmd).resume_pending = false; 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); + set_idle_hint(false); + } else if !(*cmd).resume_cmd.is_null() { + state.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) -> (), - ), + idled: Some(handle_idled), + resumed: Some(handle_resumed), }; -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 { +unsafe extern "C" fn parse_command(argc: usize, argv: *mut *mut libc::c_char) -> *mut libc::c_char { + if argc < 1 { log::error!("Missing command"); return ptr::null_mut(); } - log::debug!( - "Command: {}", - read_str(*argv.offset(0 as libc::c_int as isize)) - ); - strdup(*argv.offset(0 as libc::c_int as isize)) + log::debug!("Command: {}", read_str(*argv)); + strdup(*argv) } -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 { +unsafe extern "C" fn build_timeout_cmd(argv: *mut *mut libc::c_char) -> *mut swayidle_timeout_cmd { + *__errno_location() = 0; + let mut endptr = ptr::null_mut(); + let seconds = strtoul(*argv.offset(1), &mut endptr, 10) as libc::c_int; + if *__errno_location() != 0 || *endptr as u8 != b'\0' { log::error!( "Invalid {} parameter '{}', it should be a numeric value representing seconds", - read_str(*argv.offset(0 as libc::c_int as isize)), - read_str(*argv.offset(1 as libc::c_int as isize)), + read_str(*argv), + read_str(*argv.offset(1)), ); - exit(-(1 as libc::c_int)); + exit(-1); } - 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; + let cmd: *mut swayidle_timeout_cmd = calloc(1, mem::size_of::()).cast(); + (*cmd).idlehint = false; + (*cmd).resume_pending = false; + if seconds > 0 { + (*cmd).timeout = seconds * 1000; } else { - (*cmd).timeout = -(1 as libc::c_int); + (*cmd).timeout = -1; } 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: {}", read_str(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: {}", read_str(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: {}", read_str(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: {}", read_str(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 '{}'", - read_str(*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); - } - 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(); + state.handle_signal(sig) } 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 + state.display_event(mask) } 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(), + static mut config_paths: [*const libc::c_char; 3] = [ + b"$XDG_CONFIG_HOME/swayidle/config\0" + .as_ptr() + .cast::(), + b"$HOME/.swayidle/config\0".as_ptr().cast::(), + b"/usr/local/etc/swayidle/config\0" + .as_ptr() + .cast::(), ]; - 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 config_home = getenv(b"XDG_CONFIG_HOME\0".as_ptr().cast::()); + if config_home.is_null() || *config_home as u8 == b'\n' { + config_paths[0] = b"$HOME/.config/swayidle/config\0" + .as_ptr() + .cast::(); } - let mut p: wordexp_t = wordexp_t { + let mut p = 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; + let mut path; + let mut i = 0; while i - < (::core::mem::size_of::<[*mut libc::c_char; 3]>()) - .wrapping_div(::core::mem::size_of::<*mut libc::c_char>()) + < (mem::size_of::<[*mut libc::c_char; 3]>()) + .wrapping_div(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)); + if wordexp(config_paths[i], &mut p, 0) == 0 { + path = strdup(*p.we_wordv); wordfree(&mut p); - if !path.is_null() && access(path, 4 as libc::c_int) == 0 as libc::c_int { + if !path.is_null() && access(path, 4) == 0 { return path; } - free(path.cast::()); + 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 {} in line {lineno}", read_str(line)); - 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); +unsafe fn main_0(argc: usize, argv: *mut *mut libc::c_char) -> libc::c_int { + state.init(); + let mut config_path = ptr::null_mut(); + if state.parse_args(argc, argv, &mut config_path) != 0 { + free(config_path.cast()); + return -1; } if config_path.is_null() { config_path = get_config_path(); } - let config_load: libc::c_int = if config_path.is_null() { + let config_load = if config_path.is_null() { -2 } else { - load_config(config_path) + state.load_config(config_path) }; - if config_load == -(2 as libc::c_int) { + if config_load == -2 { log::debug!("No config file found."); - } else if config_load == -(22 as libc::c_int) { + } else if config_load == -22 { log::error!("Config file {} has errors, exiting.", read_str(config_path)); - exit(-(1 as libc::c_int)); + exit(-1); } else { log::debug!("Loaded config at {}", read_str(config_path)); } - free(config_path.cast::()); + 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(), - ); + wl_event_loop_add_signal(state.event_loop, 2, handle_signal, ptr::null_mut()); + wl_event_loop_add_signal(state.event_loop, 15, handle_signal, ptr::null_mut()); + wl_event_loop_add_signal(state.event_loop, 10, handle_signal, 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); + return -3; } - let registry: *mut wl_registry = wl_display_get_registry(state.display); + let registry = wl_display_get_registry(state.display); wl_registry_add_listener( registry, ptr::addr_of_mut!(registry_listener), @@ -1594,29 +1373,16 @@ unsafe fn main_0(argc: libc::c_int, argv: *mut *mut libc::c_char) -> libc::c_int 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::(); + seat_i = state.seats.next.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 - { + if (state.seat_name).is_null() || strcmp((*seat_i).name, state.seat_name) == 0 { seat = (*seat_i).proxy; } - seat_i = (*seat_i) - .link - .next - .cast::() - .offset(-(0 as libc::c_ulong as isize)) - .cast::(); + seat_i = (*seat_i).link.next.cast(); } if idle_notifier.is_null() { log::error!("Compositor doesn't support idle protocol"); - swayidle_finish(); - return -(4 as libc::c_int); + return -4; } if seat.is_null() { if state.seat_name.is_null() { @@ -1624,55 +1390,52 @@ unsafe fn main_0(argc: libc::c_int, argv: *mut *mut libc::c_char) -> libc::c_int } else { log::error!("Seat {} not found", read_str(state.seat_name)); } - swayidle_finish(); - return -(5 as libc::c_int); + return -5; } - let mut should_run: bool = wl_list_empty(&state.timeout_cmds) == 0; - connect_to_bus(); + let mut should_run = wl_list_empty(&state.timeout_cmds) == 0; + state.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; + if !state.before_sleep_cmd.is_null() || !state.after_resume_cmd.is_null() { + should_run = true; setup_sleep_listener(); } - if !(state.logind_lock_cmd).is_null() { - should_run = 1 as libc::c_int != 0; + if !state.logind_lock_cmd.is_null() { + should_run = true; setup_lock_listener(); } - if !(state.logind_unlock_cmd).is_null() { - should_run = 1 as libc::c_int != 0; + if !state.logind_unlock_cmd.is_null() { + should_run = true; setup_unlock_listener(); } if state.logind_idlehint { - set_idle_hint(0 as libc::c_int != 0); + set_idle_hint(false); } if !should_run { log::info!("No command specified! Nothing to do, will exit"); - sway_terminate(0 as libc::c_int); + state.sway_terminate(0); } - enable_timeouts(); + state.enable_timeouts(); wl_display_roundtrip(state.display); - let source: *mut wl_event_source = wl_event_loop_add_fd( + let 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, + WL_EVENT_READABLE, + display_event, 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); + while wl_event_loop_dispatch(state.event_loop, -1) != 1 {} + state.sway_terminate(0); } fn main() { - let mut args: Vec<*mut libc::c_char> = Vec::new(); - for arg in ::std::env::args() { + let mut args = Vec::new(); + for arg in 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) - } + args.push(ptr::null_mut()); + unsafe { process::exit(main_0(args.len() - 1, args.as_mut_ptr())) } }