Compare commits
6 Commits
793ed4d730
...
8693e10979
Author | SHA1 | Date | |
---|---|---|---|
8693e10979 | |||
7f22334f0e | |||
3b107f09cd | |||
08eca1a2d0 | |||
208eed348b | |||
85891abba0 |
173
Cargo.lock
generated
173
Cargo.lock
generated
|
@ -2,6 +2,15 @@
|
|||
# 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 = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
|
@ -177,6 +186,7 @@ dependencies = [
|
|||
"chrono",
|
||||
"dim_sdk",
|
||||
"lazy_static",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -204,12 +214,17 @@ dependencies = [
|
|||
name = "dim"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
"chrono",
|
||||
"clap",
|
||||
"dlopen",
|
||||
"dlopen_derive",
|
||||
"env_logger",
|
||||
"libc",
|
||||
"log",
|
||||
"serde",
|
||||
"toml",
|
||||
"x11",
|
||||
]
|
||||
|
||||
|
@ -246,6 +261,35 @@ dependencies = [
|
|||
"syn 0.15.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea"
|
||||
dependencies = [
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"env_filter",
|
||||
"humantime",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "example_rust"
|
||||
version = "0.1.0"
|
||||
|
@ -254,12 +298,24 @@ dependencies = [
|
|||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.60"
|
||||
|
@ -283,6 +339,16 @@ dependencies = [
|
|||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.0"
|
||||
|
@ -319,6 +385,12 @@ version = "0.4.21"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
|
@ -376,6 +448,64 @@ dependencies = [
|
|||
"proc-macro2 1.0.85",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
|
||||
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 = "serde"
|
||||
version = "1.0.203"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.203"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.85",
|
||||
"quote 1.0.36",
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
|
@ -410,6 +540,40 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
|
@ -586,6 +750,15 @@ version = "0.52.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11"
|
||||
version = "2.21.0"
|
||||
|
|
|
@ -7,10 +7,15 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.86"
|
||||
camino = "1.1.7"
|
||||
chrono = "0.4.38"
|
||||
clap = { version = "4.5.7", features = ["derive"] }
|
||||
dlopen = "0.1.8"
|
||||
dlopen_derive = "0.1.4"
|
||||
env_logger = "0.11.3"
|
||||
libc = "0.2.155"
|
||||
log = "0.4.21"
|
||||
serde = { version = "1.0.203", features = ["derive"] }
|
||||
toml = "0.8.14"
|
||||
x11 = { version = "2.21.0", features = ["xlib"] }
|
||||
|
|
6
config/main.template.toml
Normal file
6
config/main.template.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
seperator=" | "
|
||||
|
||||
[plugins]
|
||||
blacklist=["example_c", "example_rust"]
|
||||
as_whitelist=false
|
||||
template=["counter", "battery", "clock"]
|
6
config/main.toml
Normal file
6
config/main.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
seperator=" | "
|
||||
|
||||
[plugins]
|
||||
blacklist=["example_c", "example_rust"]
|
||||
as_whitelist=false
|
||||
template=["counter", "battery", "clock"]
|
|
@ -1,15 +1,17 @@
|
|||
# Must match package name in Cargo.toml
|
||||
PLUGIN_NAME=battery
|
||||
|
||||
# `target` or `debug`
|
||||
TYPE=target
|
||||
|
||||
build: $(PLUGIN_DIR)/$(PLUGIN_NAME).dim
|
||||
|
||||
$(PLUGIN_DIR)/$(PLUGIN_NAME).dim: $(OBJECT_DIR)/$(PLUGIN_NAME)/debug/lib$(PLUGIN_NAME).so
|
||||
cp $(OBJECT_DIR)/$(PLUGIN_NAME)/debug/lib$(PLUGIN_NAME).so $(PLUGIN_DIR)/$(PLUGIN_NAME).dim
|
||||
$(PLUGIN_DIR)/$(PLUGIN_NAME).dim: $(OBJECT_DIR)/$(PLUGIN_NAME)/$(TYPE)/lib$(PLUGIN_NAME).so
|
||||
@mkdir -p $(dir $@)
|
||||
cp $^ $@
|
||||
|
||||
$(OBJECT_DIR)/$(PLUGIN_NAME)/debug/lib$(PLUGIN_NAME).so:
|
||||
mkdir -p $(OBJECT_DIR)/$(PLUGIN_NAME)
|
||||
cargo build --target-dir $(OBJECT_DIR)/$(PLUGIN_NAME)
|
||||
$(OBJECT_DIR)/$(PLUGIN_NAME)/$(TYPE)/lib$(PLUGIN_NAME).so:
|
||||
@mkdir -p $(dir $@)
|
||||
cargo build --release --target-dir $(OBJECT_DIR)/$(PLUGIN_NAME)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
# Must match package name in Cargo.toml
|
||||
PLUGIN_NAME=clock
|
||||
|
||||
# `target` or `debug`
|
||||
TYPE=target
|
||||
|
||||
build: $(PLUGIN_DIR)/$(PLUGIN_NAME).dim
|
||||
|
||||
$(PLUGIN_DIR)/$(PLUGIN_NAME).dim: $(OBJECT_DIR)/$(PLUGIN_NAME)/debug/lib$(PLUGIN_NAME).so
|
||||
cp $(OBJECT_DIR)/$(PLUGIN_NAME)/debug/lib$(PLUGIN_NAME).so $(PLUGIN_DIR)/$(PLUGIN_NAME).dim
|
||||
$(PLUGIN_DIR)/$(PLUGIN_NAME).dim: $(OBJECT_DIR)/$(PLUGIN_NAME)/$(TYPE)/lib$(PLUGIN_NAME).so
|
||||
@mkdir -p $(dir $@)
|
||||
cp $^ $@
|
||||
|
||||
$(OBJECT_DIR)/$(PLUGIN_NAME)/debug/lib$(PLUGIN_NAME).so:
|
||||
mkdir -p $(OBJECT_DIR)/$(PLUGIN_NAME)
|
||||
cargo build --target-dir $(OBJECT_DIR)/$(PLUGIN_NAME)
|
||||
|
||||
|
||||
|
||||
$(OBJECT_DIR)/$(PLUGIN_NAME)/$(TYPE)/lib$(PLUGIN_NAME).so:
|
||||
@mkdir -p $(dir $@)
|
||||
cargo build --release --target-dir $(OBJECT_DIR)/$(PLUGIN_NAME)
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
# Must match package name in Cargo.toml
|
||||
PLUGIN_NAME=counter
|
||||
|
||||
# `target` or `debug`
|
||||
TYPE=target
|
||||
|
||||
build: $(PLUGIN_DIR)/$(PLUGIN_NAME).dim
|
||||
|
||||
$(PLUGIN_DIR)/$(PLUGIN_NAME).dim: $(OBJECT_DIR)/$(PLUGIN_NAME)/debug/lib$(PLUGIN_NAME).so
|
||||
cp $(OBJECT_DIR)/$(PLUGIN_NAME)/debug/lib$(PLUGIN_NAME).so $(PLUGIN_DIR)/$(PLUGIN_NAME).dim
|
||||
$(PLUGIN_DIR)/$(PLUGIN_NAME).dim: $(OBJECT_DIR)/$(PLUGIN_NAME)/$(TYPE)/lib$(PLUGIN_NAME).so
|
||||
@mkdir -p $(dir $@)
|
||||
cp $^ $@
|
||||
|
||||
$(OBJECT_DIR)/$(PLUGIN_NAME)/debug/lib$(PLUGIN_NAME).so:
|
||||
mkdir -p $(OBJECT_DIR)/$(PLUGIN_NAME)
|
||||
cargo build --target-dir $(OBJECT_DIR)/$(PLUGIN_NAME)
|
||||
|
||||
|
||||
|
||||
$(OBJECT_DIR)/$(PLUGIN_NAME)/$(TYPE)/lib$(PLUGIN_NAME).so:
|
||||
@mkdir -p $(dir $@)
|
||||
cargo build --release --target-dir $(OBJECT_DIR)/$(PLUGIN_NAME)
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
# Must match package name in Cargo.toml
|
||||
PLUGIN_NAME=example_rust
|
||||
|
||||
|
||||
# `target` or `debug`
|
||||
TYPE=target
|
||||
build: $(PLUGIN_DIR)/$(PLUGIN_NAME).dim
|
||||
|
||||
$(PLUGIN_DIR)/$(PLUGIN_NAME).dim: $(OBJECT_DIR)/$(PLUGIN_NAME)/debug/lib$(PLUGIN_NAME).so
|
||||
cp $(OBJECT_DIR)/$(PLUGIN_NAME)/debug/lib$(PLUGIN_NAME).so $(PLUGIN_DIR)/$(PLUGIN_NAME).dim
|
||||
$(PLUGIN_DIR)/$(PLUGIN_NAME).dim: $(OBJECT_DIR)/$(PLUGIN_NAME)/$(TYPE)/lib$(PLUGIN_NAME).so
|
||||
@mkdir -p $(dir $@)
|
||||
cp $^ $@
|
||||
|
||||
$(OBJECT_DIR)/$(PLUGIN_NAME)/debug/lib$(PLUGIN_NAME).so:
|
||||
mkdir -p $(OBJECT_DIR)/$(PLUGIN_NAME)
|
||||
cargo build --target-dir $(OBJECT_DIR)/$(PLUGIN_NAME)
|
||||
|
||||
|
||||
|
||||
$(OBJECT_DIR)/$(PLUGIN_NAME)/$(TYPE)/lib$(PLUGIN_NAME).so:
|
||||
@mkdir -p $(dir $@)
|
||||
cargo build --release --target-dir $(OBJECT_DIR)/$(PLUGIN_NAME)
|
||||
|
|
1
rust-toolchain
Normal file
1
rust-toolchain
Normal file
|
@ -0,0 +1 @@
|
|||
nightly
|
55
src/config.rs
Normal file
55
src/config.rs
Normal file
|
@ -0,0 +1,55 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||
pub struct Config {
|
||||
pub seperator: String,
|
||||
pub plugins: ConfigPlugins,
|
||||
|
||||
#[serde(skip)]
|
||||
pub config_dir: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||
pub struct ConfigPlugins {
|
||||
pub blacklist: Vec<String>,
|
||||
pub as_whitelist: bool,
|
||||
pub template: Vec<String>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new(path: &Path) -> Result<Self, ConfigError> {
|
||||
let path = path.join("main.toml");
|
||||
|
||||
if !path.exists() {
|
||||
println!("ERROR: {:?} doesnt exist", path);
|
||||
}
|
||||
|
||||
let mut cfg: Self = toml::from_str(
|
||||
&std::fs::read_to_string(&path)?
|
||||
)?;
|
||||
|
||||
cfg.config_dir = path.to_path_buf();
|
||||
Ok(cfg)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
pub enum ConfigError {
|
||||
IoError(std::io::Error),
|
||||
TomlDeserialiseError(toml::de::Error)
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for ConfigError {
|
||||
fn from(e: std::io::Error) -> Self {
|
||||
Self::IoError(e)
|
||||
}
|
||||
}
|
||||
impl From<toml::de::Error> for ConfigError {
|
||||
fn from(e: toml::de::Error) -> Self {
|
||||
Self::TomlDeserialiseError(e)
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
use std::ffi::{CString, NulError};
|
||||
use std::{collections::HashMap, ffi::{CString, NulError}};
|
||||
|
||||
use x11::xlib;
|
||||
|
||||
use crate::{config::Config, plugman::PolledText};
|
||||
|
||||
|
||||
|
||||
pub struct Display {
|
||||
|
@ -16,7 +18,7 @@ impl Display {
|
|||
let display = xlib::XOpenDisplay(std::ptr::null());
|
||||
|
||||
if display.is_null() {
|
||||
eprintln!("ERROR: Could not open x11 display");
|
||||
log::error!("Could not open x11 display");
|
||||
return Err(());
|
||||
}
|
||||
|
||||
|
@ -41,4 +43,63 @@ impl Display {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write_with_vec(&mut self, cfg: &Config, v: HashMap<String, PolledText>) -> Result<(), NulError> {
|
||||
let mut buf = Vec::new();
|
||||
|
||||
let mut v = if cfg.plugins.as_whitelist {
|
||||
let mut vv = HashMap::new();
|
||||
for (n, pt) in v {
|
||||
if cfg.plugins.blacklist.contains(&n) {
|
||||
vv.insert(n, pt);
|
||||
}
|
||||
}
|
||||
vv
|
||||
} else {
|
||||
let mut vv = HashMap::new();
|
||||
for (n, pt) in v {
|
||||
if !cfg.plugins.blacklist.contains(&n) {
|
||||
vv.insert(n, pt);
|
||||
}
|
||||
}
|
||||
vv
|
||||
};
|
||||
|
||||
let mut used_values = Vec::new();
|
||||
for tv in &cfg.plugins.template {
|
||||
let mut found = false;
|
||||
for (pname, pt) in &v {
|
||||
if *pname == *tv {
|
||||
if !pt.disabled() {
|
||||
buf.push(pt.text().clone());
|
||||
}
|
||||
|
||||
used_values.push(pname.clone());
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
log::warn!("Plugin '{}' was not found even though it was included in the template", tv);
|
||||
}
|
||||
}
|
||||
|
||||
for val in used_values {
|
||||
v.remove(&val);
|
||||
}
|
||||
|
||||
let mut kv: Vec<(&String, &PolledText)> = v.iter().collect();
|
||||
kv.sort_by(|a, b| a.0.cmp(b.0));
|
||||
|
||||
for (_, pt) in &kv {
|
||||
buf.push(pt.text().clone());
|
||||
}
|
||||
|
||||
let text = buf.join(&cfg.seperator);
|
||||
|
||||
self.write_display_name(&text)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
55
src/main.rs
55
src/main.rs
|
@ -1,40 +1,69 @@
|
|||
#![allow(internal_features)]
|
||||
#![feature(core_intrinsics)]
|
||||
use std::{path::PathBuf, process::ExitCode, time::Duration};
|
||||
|
||||
use std::{process::ExitCode, time::Duration};
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
mod display;
|
||||
mod plugman;
|
||||
mod config;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
struct CliArgs {
|
||||
#[arg(long, short, default_value="./plugins")]
|
||||
plugin_dir: camino::Utf8PathBuf,
|
||||
pub plugin_dir: camino::Utf8PathBuf,
|
||||
#[arg(long, short, default_value="./config")]
|
||||
pub config_dir: camino::Utf8PathBuf,
|
||||
#[arg(long, short)]
|
||||
pub debug: bool
|
||||
}
|
||||
|
||||
|
||||
// TODO: Clean up main function
|
||||
// TODO: Make ffi safe abstraction for logger
|
||||
// TODO: Set up ipc with unix sockets
|
||||
// TODO: Allow sending messages command -> running DIM instance -> plugin with ipc
|
||||
// TODO: Run code through clippy
|
||||
fn main() -> ExitCode {
|
||||
// let ca = CliArgs::parse();
|
||||
let ca = CliArgs::parse();
|
||||
|
||||
if ca.debug {
|
||||
env_logger::builder()
|
||||
.filter(None, log::LevelFilter::Debug)
|
||||
.init();
|
||||
} else {
|
||||
env_logger::builder()
|
||||
.filter(None, log::LevelFilter::Info)
|
||||
.init();
|
||||
}
|
||||
|
||||
let config;
|
||||
match config::Config::new(ca.config_dir.as_std_path()) {
|
||||
Ok(v) => config = v,
|
||||
Err(e) => {
|
||||
log::error!("Failed to parse config: {e:?}");
|
||||
return ExitCode::from(2);
|
||||
}
|
||||
};
|
||||
let Ok(mut disp) = display::Display::new() else {
|
||||
return ExitCode::from(1);
|
||||
};
|
||||
|
||||
|
||||
let mut pm = plugman::PlugMan::new(1024); // idk tbh
|
||||
if let Err(e) = pm.load(PathBuf::from("./plugins")
|
||||
//ca.plugin_dir.as_std_path().to_path_buf()
|
||||
){
|
||||
eprintln!("ERROR: Failed to load plugins: {e:?}");
|
||||
if let Err(e) = pm.load(ca.plugin_dir.as_std_path().to_path_buf()){
|
||||
log::error!("Failed to load plugins: {e:?}");
|
||||
return ExitCode::from(3);
|
||||
}
|
||||
|
||||
pm.init_plugins();
|
||||
|
||||
// TODO: Sort them from a config or something
|
||||
|
||||
loop {
|
||||
let vals: Vec<String> = pm.poll_plugins().into_iter().map(|f| f.1).collect();
|
||||
|
||||
|
||||
let _ = disp.write_display_name(&vals.join(" | "));
|
||||
let vals = pm.poll_plugins();
|
||||
if let Err(e) = disp.write_with_vec(&config, vals) {
|
||||
log::warn!("Failed to write too bar: {e}");
|
||||
}
|
||||
std::thread::sleep(Duration::from_millis(250));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::path::PathBuf;
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use self::plugin::Plugin;
|
||||
|
||||
|
@ -20,13 +20,15 @@ impl PlugMan {
|
|||
}
|
||||
|
||||
pub fn load(&mut self, dir: PathBuf) -> Result<(), PluginError>{
|
||||
log::debug!("Loading plugins from {:?}", dir);
|
||||
|
||||
let files = std::fs::read_dir(dir)?;
|
||||
|
||||
for file in files {
|
||||
let entry = file?;
|
||||
if entry.file_type()?.is_file() {
|
||||
let plugin = Plugin::load(entry.path().to_path_buf())?;
|
||||
println!("INFO: Loaded plugin {} {} licensed with {}",
|
||||
log::info!("Loaded plugin '{}' ({}) licensed with {}",
|
||||
plugin.name().clone(),
|
||||
plugin.version().clone().unwrap_or("None".to_string()),
|
||||
plugin.license().clone().unwrap_or("None".to_string())
|
||||
|
@ -37,7 +39,12 @@ impl PlugMan {
|
|||
self.load(entry.path().to_path_buf())?;
|
||||
}
|
||||
}
|
||||
println!("INFO: Loaded {} plugins", self.plugins.len());
|
||||
if self.plugins.len() == 0 {
|
||||
log::error!("No plugins found");
|
||||
return Err(PluginError::NoPlugins);
|
||||
}
|
||||
|
||||
log::info!("Loaded {} plugins", self.plugins.len());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -52,7 +59,7 @@ impl PlugMan {
|
|||
pub fn reload_plugins(&mut self) {
|
||||
for plugin in &mut self.plugins {
|
||||
if let Err(e) = plugin.reload() {
|
||||
eprintln!("ERROR: Failed to reload plugin {:?}: {e}", plugin.name());
|
||||
log::error!("Failed to reload plugin {:?}: {e}", plugin.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,8 +71,8 @@ impl PlugMan {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn poll_plugins(&mut self) -> Vec<(String, String)> {
|
||||
let mut answers = Vec::new();
|
||||
pub fn poll_plugins(&mut self) -> HashMap<String, PolledText> {
|
||||
let mut answers = HashMap::new();
|
||||
let len = self.len_cap / self.plugins.len();
|
||||
for plugin in &self.plugins {
|
||||
if !plugin.enabled() {
|
||||
|
@ -73,11 +80,15 @@ impl PlugMan {
|
|||
}
|
||||
match plugin.poll(len) {
|
||||
Ok(v) => {
|
||||
if !v.is_empty() {
|
||||
answers.push((plugin.name().clone(), v));
|
||||
let mut pth = (plugin.name().clone(), PolledText::new(v));
|
||||
if pth.1.text().is_empty() {
|
||||
pth.1.disable()
|
||||
}
|
||||
|
||||
|
||||
answers.insert(pth.0, pth.1);
|
||||
},
|
||||
Err(e) => eprintln!("Failed to poll plugin: {e}"),
|
||||
Err(e) => log::error!("Failed to poll plugin: {e}"),
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -85,10 +96,32 @@ impl PlugMan {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PolledText {
|
||||
text: String,
|
||||
disabled: bool
|
||||
}
|
||||
|
||||
impl PolledText {
|
||||
pub fn new(text: String) -> Self {
|
||||
Self { text, disabled: false }
|
||||
}
|
||||
pub fn text(&self) -> &String {
|
||||
&self.text
|
||||
}
|
||||
pub fn disabled(&self) -> bool {
|
||||
self.disabled
|
||||
}
|
||||
pub fn disable(&mut self) {
|
||||
self.disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PluginError {
|
||||
DlOpenError,
|
||||
IoError
|
||||
IoError,
|
||||
NoPlugins
|
||||
}
|
||||
|
||||
impl From<dlopen::Error> for PluginError {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::{alloc::Layout, ffi::{c_char, c_uint, CStr, CString}, path::PathBuf};
|
||||
use std::{alloc::Layout, ffi::{c_char, CStr}, path::PathBuf};
|
||||
|
||||
use dlopen::raw::Library;
|
||||
|
||||
|
@ -38,7 +38,7 @@ impl Plugin {
|
|||
}
|
||||
|
||||
fn reload_symbols(&mut self) -> Result<(), dlopen::Error> {
|
||||
println!("INFO: Loading {:?}", self.path);
|
||||
log::debug!("Loading {:?}", self.path);
|
||||
let lib = Library::open(&self.path)?;
|
||||
let symbols = PluginSyms {
|
||||
init: unsafe { lib.symbol("plug_init")? },
|
||||
|
@ -51,14 +51,13 @@ impl Plugin {
|
|||
};
|
||||
unsafe {
|
||||
if (symbols.get_info)().is_null() {
|
||||
eprintln!("ERROR: Info fields for plugin {:?} are null", self.path);
|
||||
log::error!("Info fields for plugin {:?} are null", self.path);
|
||||
self.disable();
|
||||
}
|
||||
}
|
||||
|
||||
self.syms = Some(symbols);
|
||||
self.lib = Some(lib);
|
||||
println!("INFO: Loading OK");
|
||||
Ok(())
|
||||
}
|
||||
pub fn syms(&self) -> PluginSyms {
|
||||
|
@ -97,7 +96,9 @@ impl Plugin {
|
|||
String::from_raw_parts(buf, len, cap)
|
||||
};
|
||||
|
||||
println!("Polled: {}", s);
|
||||
if !s.is_empty() {
|
||||
log::debug!("Polled: {}", s);
|
||||
}
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user