Move spawn to Rust

This commit is contained in:
Alex Kotov 2022-09-09 22:32:00 +04:00
parent 763876ac27
commit 6ff33d83fa
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
9 changed files with 162 additions and 162 deletions

View file

@ -24,7 +24,8 @@ RUST_APIS = \
src/constraints.h \ src/constraints.h \
src/geom.h \ src/geom.h \
src/helpers.h \ src/helpers.h \
src/settings.h src/settings.h \
src/spawn.h
MODULES_SRC = \ MODULES_SRC = \
src/drw.c \ src/drw.c \
@ -32,7 +33,6 @@ MODULES_SRC = \
src/geom.c \ src/geom.c \
src/layouts.c \ src/layouts.c \
src/logger.c \ src/logger.c \
src/spawn.c \
src/state.c \ src/state.c \
src/unit.c \ src/unit.c \
src/util.c \ src/util.c \
@ -83,7 +83,7 @@ polytreewm: src/main.o $(MODULES_OBJ) target/debug/libpolytreewm.a
dwm.o: $(DWM_SRC) $(DWM_HDR) dwm.o: $(DWM_SRC) $(DWM_HDR)
target/debug/libpolytreewm.a: $(RUST_SRC) target/debug/libpolytreewm.a: $(RUST_SRC)
$(CARGO) build $(CARGO) build $(CARGO_FEATURES)
######### #########
# Tasks # # Tasks #
@ -91,7 +91,7 @@ target/debug/libpolytreewm.a: $(RUST_SRC)
test: $(TEST_EXE) test: $(TEST_EXE)
@echo "$(TEST_EXE)" | awk '{ OFS="\n"; $$1=$$1 } 1' | /bin/sh @echo "$(TEST_EXE)" | awk '{ OFS="\n"; $$1=$$1 } 1' | /bin/sh
$(CARGO) test $(CARGO) test $(CARGO_FEATURES)
$(CARGO) fmt --check $(CARGO) fmt --check
$(CARGO) clippy $(CARGO) clippy

View file

@ -5,20 +5,26 @@ PKGS += xinerama
.if "$(WITH_LOCKER)" == "i3lock" .if "$(WITH_LOCKER)" == "i3lock"
CPPFLAGS += -DWITH_LOCKER -DWITH_LOCKER_I3LOCK CPPFLAGS += -DWITH_LOCKER -DWITH_LOCKER_I3LOCK
CARGO_FEATURES += --features locker-i3lock
.endif .endif
.if "$(WITH_LOCKER)" == "i3lock-color" .if "$(WITH_LOCKER)" == "i3lock-color"
CPPFLAGS += -DWITH_LOCKER -DWITH_LOCKER_I3LOCK_COLOR CPPFLAGS += -DWITH_LOCKER -DWITH_LOCKER_I3LOCK_COLOR
CARGO_FEATURES += --features locker-i3lock-color
.endif .endif
.if "$(WITH_TERMINAL)" == "alacritty" .if "$(WITH_TERMINAL)" == "alacritty"
CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_ALACRITTY CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_ALACRITTY
CARGO_FEATURES += --features term-alacritty
.endif .endif
.if "$(WITH_TERMINAL)" == "gnome" .if "$(WITH_TERMINAL)" == "gnome"
CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_GNOME CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_GNOME
CARGO_FEATURES += --features term-gnome
.endif .endif
.if "$(WITH_TERMINAL)" == "st" .if "$(WITH_TERMINAL)" == "st"
CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_ST CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_ST
CARGO_FEATURES += --features term-st
.endif .endif
.if "$(WITH_TERMINAL)" == "xterm" .if "$(WITH_TERMINAL)" == "xterm"
CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_XTERM CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_XTERM
CARGO_FEATURES += --features term-xterm
.endif .endif

View file

@ -5,20 +5,26 @@ endif
ifeq (i3lock,$(WITH_LOCKER)) ifeq (i3lock,$(WITH_LOCKER))
CPPFLAGS += -DWITH_LOCKER -DWITH_LOCKER_I3LOCK CPPFLAGS += -DWITH_LOCKER -DWITH_LOCKER_I3LOCK
CARGO_FEATURES += --features locker-i3lock
endif endif
ifeq (i3lock-color,$(WITH_LOCKER)) ifeq (i3lock-color,$(WITH_LOCKER))
CPPFLAGS += -DWITH_LOCKER -DWITH_LOCKER_I3LOCK_COLOR CPPFLAGS += -DWITH_LOCKER -DWITH_LOCKER_I3LOCK_COLOR
CARGO_FEATURES += --features locker-i3lock-color
endif endif
ifeq (alacritty,$(WITH_TERMINAL)) ifeq (alacritty,$(WITH_TERMINAL))
CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_ALACRITTY CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_ALACRITTY
CARGO_FEATURES += --features term-alacritty
endif endif
ifeq (gnome,$(WITH_TERMINAL)) ifeq (gnome,$(WITH_TERMINAL))
CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_GNOME CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_GNOME
CARGO_FEATURES += --features term-gnome
endif endif
ifeq (st,$(WITH_TERMINAL)) ifeq (st,$(WITH_TERMINAL))
CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_ST CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_ST
CARGO_FEATURES += --features term-st
endif endif
ifeq (xterm,$(WITH_TERMINAL)) ifeq (xterm,$(WITH_TERMINAL))
CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_XTERM CPPFLAGS += -DWITH_TERMINAL -DWITH_TERMINAL_XTERM
CARGO_FEATURES += --features term-xterm
endif endif

View file

@ -16,8 +16,20 @@ publish = false
name = "polytreewm" name = "polytreewm"
crate-type = ["staticlib"] 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] [dependencies]
ctor = "0.1.23" ctor = "0.1.23"
env_logger = "0.9.0" env_logger = "0.9.0"
libc = "0.2.132"
log = "0.4.17" log = "0.4.17"
x11 = "2.20.0" x11 = "2.20.0"

View file

@ -2,3 +2,4 @@ mod atoms;
mod constraints; mod constraints;
mod geom; mod geom;
mod settings; mod settings;
mod spawn;

View file

@ -0,0 +1,35 @@
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<String> =
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<CString> = 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);
}
}

View file

@ -1,6 +1,7 @@
mod api; mod api;
mod atoms; mod atoms;
mod constraints; mod constraints;
mod spawn;
pub mod geom; pub mod geom;
pub mod settings; pub mod settings;

View file

@ -0,0 +1,97 @@
pub fn command<S: AsRef<str> + 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",
],
};

View file

@ -1,158 +0,0 @@
#include "spawn.h"
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#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;
}
}