mod debug_log;
mod display;
mod mpd_handler;
mod signal;
#[cfg(feature = "unicode_support")]
mod unicode_support;
use clap::Parser;
use ggez::conf::{WindowMode, WindowSetup};
use ggez::event;
use ggez::{ContextBuilder, GameResult};
use std::fs::File;
use std::io::Read;
use std::net::Ipv4Addr;
use std::path::PathBuf;
#[derive(Parser, Debug, Clone)]
#[command(author, version, about, long_about = None)]
pub struct Opt {
host: Ipv4Addr,
#[arg(default_value = "6600")]
port: u16,
#[arg(short = 'p')]
password: Option<String>,
#[arg(long = "disable-show-title", help = "disable title display")]
disable_show_title: bool,
#[arg(long = "disable-show-artist", help = "disable artist display")]
disable_show_artist: bool,
#[arg(long = "disable-show-album", help = "disable album display")]
disable_show_album: bool,
#[arg(long = "disable-show-filename", help = "disable filename display")]
disable_show_filename: bool,
#[arg(long = "disable-show-percentage", help = "disable percentage display")]
disable_show_percentage: bool,
#[arg(
long = "force-text-height-scale",
help = "force-set text height relative to window height as a ratio (default 0.12)"
)]
force_text_height_scale: Option<f32>,
#[arg(long = "pprompt", help = "input password via prompt")]
enable_prompt_password: bool,
#[arg(long = "pfile", help = "read password from file")]
password_file: Option<PathBuf>,
#[arg(
long = "no-scale-fill",
help = "don't scale-fill the album art to the window"
)]
do_not_fill_scale_album_art: bool,
#[arg(short = 'l', long = "log-level", default_value = "error")]
log_level: debug_log::LogLevel,
#[arg(
short,
long,
help = "sets the opacity of the text background (0-255)",
default_value = "190"
)]
text_bg_opacity: u8,
}
fn main() -> GameResult<()> {
let mut opt = Opt::parse();
if let Some(forced_scale) = &mut opt.force_text_height_scale {
if *forced_scale < 0.01 {
*forced_scale = 0.01;
println!("WARNING: Clamped \"force-text-height-scale\" to minimum of 0.01!");
} else if *forced_scale > 0.5 {
*forced_scale = 0.5;
println!("WARNING: Clamped \"force-text-height-scale\" to maximum of 0.5!");
}
}
println!("Got host addr == {}, port == {}", opt.host, opt.port);
if let Some(psswd_file_path) = opt.password_file.as_ref() {
let mut file = File::open(psswd_file_path).expect("pfile/password_file should exist");
let mut content: String = String::new();
file.read_to_string(&mut content)
.expect("Should be able to read from pfile/password_file");
if content.ends_with("\r\n") {
content.truncate(content.len() - 2);
} else if content.ends_with('\n') {
content.truncate(content.len() - 1);
}
opt.password = Some(content);
}
#[cfg(target_family = "unix")]
{
signal::register_signal(libc::SIGHUP).unwrap();
signal::register_signal(libc::SIGINT).unwrap();
signal::register_signal(libc::SIGTERM).unwrap();
}
#[cfg(target_family = "windows")]
{}
let (mut ctx, event_loop) = ContextBuilder::new("mpd_info_screen", "Stephen Seo")
.window_setup(WindowSetup {
title: "mpd info screen".into(),
..Default::default()
})
.window_mode(WindowMode {
resizable: true,
resize_on_scale_factor_change: true,
..Default::default()
})
.build()
.expect("Failed to create ggez context");
ctx.fs.mount(&PathBuf::from("/"), true);
let display = display::MPDDisplay::new(&mut ctx, opt.clone());
event::run(ctx, event_loop, display)
}