diff --git a/Makefile b/Makefile index ce6aa3e..bba31e4 100644 --- a/Makefile +++ b/Makefile @@ -24,8 +24,7 @@ RUST_APIS = \ src/constraints.h \ src/geom.h \ src/helpers.h \ - src/settings.h \ - src/spawn.h + src/settings.h MODULES_SRC = \ src/drw.c \ @@ -33,6 +32,7 @@ MODULES_SRC = \ src/geom.c \ src/layouts.c \ src/logger.c \ + src/spawn.c \ src/state.c \ src/unit.c \ src/util.c \ @@ -83,7 +83,7 @@ polytreewm: src/main.o $(MODULES_OBJ) target/debug/libpolytreewm.a dwm.o: $(DWM_SRC) $(DWM_HDR) target/debug/libpolytreewm.a: $(RUST_SRC) - $(CARGO) build $(CARGO_FEATURES) + $(CARGO) build ######### # Tasks # @@ -91,7 +91,7 @@ target/debug/libpolytreewm.a: $(RUST_SRC) test: $(TEST_EXE) @echo "$(TEST_EXE)" | awk '{ OFS="\n"; $$1=$$1 } 1' | /bin/sh - $(CARGO) test $(CARGO_FEATURES) + $(CARGO) test $(CARGO) fmt --check $(CARGO) clippy diff --git a/config/2-conditionals-bsd.mk b/config/2-conditionals-bsd.mk index b33262c..ab9d5b1 100644 --- a/config/2-conditionals-bsd.mk +++ b/config/2-conditionals-bsd.mk @@ -5,26 +5,20 @@ PKGS += xinerama .if "$(WITH_LOCKER)" == "i3lock" CPPFLAGS += -DWITH_LOCKER -DWITH_LOCKER_I3LOCK -CARGO_FEATURES += --features locker-i3lock .endif .if "$(WITH_LOCKER)" == "i3lock-color" CPPFLAGS += -DWITH_LOCKER -DWITH_LOCKER_I3LOCK_COLOR -CARGO_FEATURES += --features locker-i3lock-color .endif .if "$(WITH_TERMINAL)" == "alacritty" CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_ALACRITTY -CARGO_FEATURES += --features term-alacritty .endif .if "$(WITH_TERMINAL)" == "gnome" CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_GNOME -CARGO_FEATURES += --features term-gnome .endif .if "$(WITH_TERMINAL)" == "st" CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_ST -CARGO_FEATURES += --features term-st .endif .if "$(WITH_TERMINAL)" == "xterm" CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_XTERM -CARGO_FEATURES += --features term-xterm .endif diff --git a/config/2-conditionals-gnu.mk b/config/2-conditionals-gnu.mk index a8fc25e..e8d9aa8 100644 --- a/config/2-conditionals-gnu.mk +++ b/config/2-conditionals-gnu.mk @@ -5,26 +5,20 @@ endif ifeq (i3lock,$(WITH_LOCKER)) CPPFLAGS += -DWITH_LOCKER -DWITH_LOCKER_I3LOCK -CARGO_FEATURES += --features locker-i3lock endif ifeq (i3lock-color,$(WITH_LOCKER)) CPPFLAGS += -DWITH_LOCKER -DWITH_LOCKER_I3LOCK_COLOR -CARGO_FEATURES += --features locker-i3lock-color endif ifeq (alacritty,$(WITH_TERMINAL)) CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_ALACRITTY -CARGO_FEATURES += --features term-alacritty endif ifeq (gnome,$(WITH_TERMINAL)) CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_GNOME -CARGO_FEATURES += --features term-gnome endif ifeq (st,$(WITH_TERMINAL)) CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_ST -CARGO_FEATURES += --features term-st endif ifeq (xterm,$(WITH_TERMINAL)) CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_XTERM -CARGO_FEATURES += --features term-xterm endif diff --git a/rust-polytreewm/Cargo.toml b/rust-polytreewm/Cargo.toml index de27270..8c1406c 100644 --- a/rust-polytreewm/Cargo.toml +++ b/rust-polytreewm/Cargo.toml @@ -16,20 +16,8 @@ publish = false name = "polytreewm" crate-type = ["staticlib"] -[features] -default = [] -locker = [] -locker-i3lock = ["locker"] -locker-i3lock-color = ["locker"] -term = [] -term-alacritty = ["term"] -term-gnome = ["term"] -term-st = ["term"] -term-xterm = ["term"] - [dependencies] ctor = "0.1.23" env_logger = "0.9.0" -libc = "0.2.132" log = "0.4.17" x11 = "2.20.0" diff --git a/rust-polytreewm/src/api/mod.rs b/rust-polytreewm/src/api/mod.rs index e97efed..204bb83 100644 --- a/rust-polytreewm/src/api/mod.rs +++ b/rust-polytreewm/src/api/mod.rs @@ -2,4 +2,3 @@ mod atoms; mod constraints; mod geom; mod settings; -mod spawn; diff --git a/rust-polytreewm/src/api/spawn.rs b/rust-polytreewm/src/api/spawn.rs deleted file mode 100644 index 3cb19d6..0000000 --- a/rust-polytreewm/src/api/spawn.rs +++ /dev/null @@ -1,35 +0,0 @@ -use crate::*; - -use std::ffi::{CStr, CString}; -use std::os::raw::*; - -#[no_mangle] -unsafe extern "C" fn spawn_command( - name: *const c_char, - callback: unsafe extern "C" fn(), - monitor: c_int, -) { - if name.is_null() || !(0..=9).contains(&monitor) { - return; - } - let name = CStr::from_ptr(name).to_str().unwrap(); - let command = spawn::command(name); - let mut args: Vec = - command.args.iter().map(|arg| arg.to_string()).collect(); - if command.monitor_arg_index != 0 { - args[command.monitor_arg_index] = format!("{}", monitor); - } - let arg_cstrs: Vec = args - .iter() - .map(|arg| CString::new(arg.as_str()).unwrap()) - .collect(); - let arg_ptrs: Vec<*const c_char> = - arg_cstrs.iter().map(|arg| arg.as_ptr()).collect(); - - if libc::fork() != 0 { - callback(); - libc::setsid(); - libc::execvp(arg_ptrs[0], arg_ptrs.as_ptr()); - libc::exit(libc::EXIT_SUCCESS); - } -} diff --git a/rust-polytreewm/src/lib.rs b/rust-polytreewm/src/lib.rs index 01e49fa..39948a3 100644 --- a/rust-polytreewm/src/lib.rs +++ b/rust-polytreewm/src/lib.rs @@ -1,7 +1,6 @@ mod api; mod atoms; mod constraints; -mod spawn; pub mod geom; pub mod settings; diff --git a/rust-polytreewm/src/spawn.rs b/rust-polytreewm/src/spawn.rs deleted file mode 100644 index e0d5fd0..0000000 --- a/rust-polytreewm/src/spawn.rs +++ /dev/null @@ -1,97 +0,0 @@ -pub fn command + std::fmt::Debug>(name: S) -> &'static Command { - let name = name.as_ref(); - for command in COMMANDS { - if command.name == name { - return command; - } - } - panic!("unknown command: {:?}", name); -} - -pub struct Command { - pub name: &'static str, - pub monitor_arg_index: usize, - pub args: &'static [&'static str], -} - -static COMMANDS: &[&Command] = &[ - &MENU_COMMAND, - &FIREFOX_COMMAND, - #[cfg(feature = "term")] - &TERM_COMMAND, - #[cfg(feature = "locker")] - &LOCK_COMMAND, -]; - -static MENU_COMMAND: Command = Command { - name: "menu", - monitor_arg_index: 6, - args: &[ - "rofi", - "-modi", - "drun", - "-show", - "drun", - "-monitor", - "-1", // monitor arg - "-show-icons", - ], -}; - -static FIREFOX_COMMAND: Command = Command { - name: "firefox", - monitor_arg_index: 0, - args: &["firefox"], -}; - -#[cfg(feature = "term")] -static TERM_COMMAND: Command = Command { - name: "term", - monitor_arg_index: 0, - #[cfg(feature = "term-alacritty")] - args: &["alacritty"], - #[cfg(feature = "term-gnome")] - args: &["gnome-terminal", "--wait"], - #[cfg(feature = "term-st")] - args: &["st"], - #[cfg(feature = "term-xterm")] - args: &["xterm"], -}; - -#[cfg(feature = "locker")] -static LOCK_COMMAND: Command = Command { - name: "lock", - monitor_arg_index: 0, - #[cfg(feature = "locker-i3lock")] - args: &["i3lock"], - #[cfg(feature = "locker-i3lock-color")] - args: &[ - "i3lock", - "--insidever-color=#ffffff22", - "--ringver-color=#bb00bbbb", - // - "--insidewrong-color=#ffffff22", - "--ringwrong-color=#880000bb", - // - "--inside-color=#00000000", - "--ring-color=#ff00ffcc", - "--line-color=#00000000", - "--separator-color=#ff00ffcc", - // - "--verif-color=#ee00eeee", - "--wrong-color=#ee00eeee", - "--time-color=#ee00eeee", - "--date-color=#ee00eeee", - "--layout-color=#ee00eeee", - "--keyhl-color=#880000bb", - "--bshl-color=#880000bb", - // - "--screen=1", - "--blur=5", - "--clock", - "--indicator", - "--time-str=%H:%M:%S", - "--date-str=%a, %e %b %Y", - "--keylayout=1", - ], -}; diff --git a/src/spawn.c b/src/spawn.c new file mode 100644 index 0000000..d8d776d --- /dev/null +++ b/src/spawn.c @@ -0,0 +1,158 @@ +#include "spawn.h" + +#include +#include +#include +#include +#include + +#define MAX_ARGS_COUNT 25 +#define ARGS_SIZE (MAX_ARGS_COUNT + 1) +#define MON_ARG_SIZE 2 + +#ifdef WITH_LOCKER_I3LOCK_COLOR +#define COLOR_BLANK "#00000000" +#define COLOR_CLEAR "#ffffff22" +#define COLOR_DEFAULT "#ff00ffcc" +#define COLOR_TEXT "#ee00eeee" +#define COLOR_WRONG "#880000bb" +#define COLOR_VERIFYING "#bb00bbbb" +#endif // WITH_LOCKER_I3LOCK_COLOR + +struct Command { + const char *name; + size_t monitor_arg_index; + const char *args[ARGS_SIZE]; +}; + +static struct Command commands[] = { +#ifdef WITH_LOCKER + { + .name = "lock", + .monitor_arg_index = 0, +#ifdef WITH_LOCKER_I3LOCK + .args = { "i3lock", NULL }, +#endif // WITH_LOCKER_I3LOCK +#ifdef WITH_LOCKER_I3LOCK_COLOR + .args = { + "i3lock", + "--insidever-color="COLOR_CLEAR, + "--ringver-color="COLOR_VERIFYING, + + "--insidewrong-color="COLOR_CLEAR, + "--ringwrong-color="COLOR_WRONG, + + "--inside-color="COLOR_BLANK, + "--ring-color="COLOR_DEFAULT, + "--line-color="COLOR_BLANK, + "--separator-color="COLOR_DEFAULT, + + "--verif-color="COLOR_TEXT, + "--wrong-color="COLOR_TEXT, + "--time-color="COLOR_TEXT, + "--date-color="COLOR_TEXT, + "--layout-color="COLOR_TEXT, + "--keyhl-color="COLOR_WRONG, + "--bshl-color="COLOR_WRONG, + + "--screen=1", + "--blur=5", + "--clock", + "--indicator", + "--time-str=%H:%M:%S", + "--date-str=%a, %e %b %Y", + "--keylayout=1", + NULL, + }, +#endif // WITH_LOCKER_I3LOCK_COLOR + }, +#endif // WITH_LOCKER + { + .name = "menu", + .monitor_arg_index = 6, + .args = { + "rofi", + "-modi", + "drun", + "-show", + "drun", + "-monitor", + "-1", + "-show-icons", + NULL, + }, + }, +#ifdef WITH_TERMINAL + { + .name = "term", + .monitor_arg_index = 0, +#ifdef WITH_TERMINAL_ALACRITTY + .args = { "alacritty", NULL }, +#endif // WITH_TERMINAL_ALACRITTY +#ifdef WITH_TERMINAL_GNOME + .args = { "gnome-terminal", "--wait", NULL }, +#endif // WITH_TERMINAL_GNOME +#ifdef WITH_TERMINAL_ST + .args = { "st", NULL }, +#endif // WITH_TERMINAL_ST +#ifdef WITH_TERMINAL_XTERM + .args = { "xterm", NULL }, +#endif // WITH_TERMINAL_XTERM + }, +#endif // WITH_TERMINAL + { + .name = "firefox", + .monitor_arg_index = 0, + .args = { "firefox", NULL }, + }, +}; + +void spawn_command( + const char *const name, + void (*const callback)(), + const int monitor +) { + // TODO: maybe we should assert here + if (name == NULL || monitor < 0 || monitor > 9) return; + + for ( + size_t command_index = 0; + command_index < sizeof(commands) / sizeof(struct Command); + ++command_index + ) { + const struct Command *const command = &commands[command_index]; + if (strcmp(name, command->name) != 0) continue; + + // We discard const modifier + // because we will only change newly allocated version. + char **args = (char**)command->args; + char monitor_buffer[2] = { '0' + monitor, '\0' }; + + if (command->monitor_arg_index != 0) { + args = malloc(sizeof(char*) * ARGS_SIZE); + if (args == NULL) return; + + for (size_t arg_index = 0;; ++arg_index) { + // We discard const modifier + // because we will only change newly allocated version. + args[arg_index] = (char*)command->args[arg_index]; + if (args[arg_index] == NULL) break; + } + + args[command->monitor_arg_index] = monitor_buffer; + } + + if (fork() == 0) { + callback(); + setsid(); + execvp(args[0], args); + fprintf(stderr, "polytreewm: execvp %s", args[0]); + perror(" failed"); + exit(EXIT_SUCCESS); + } + + if (command->monitor_arg_index != 0) free(args); + + return; + } +}