use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer}; use win_key_codes; type WinKeyCode = i32; fn win_send_key_event(keycode: WinKeyCode, down: bool, delay_ms: u64) { use winapi::um::winuser::{keybd_event, KEYEVENTF_KEYUP}; let flags = if down { 0 } else { KEYEVENTF_KEYUP }; unsafe { keybd_event(keycode as u8, 0, flags, 0) }; std::thread::sleep(std::time::Duration::from_millis(delay_ms)); } async fn index(_req: HttpRequest) -> HttpResponse { HttpResponse::Ok() .content_type("text/html") .body(include_str!("index.html")) } async fn action(req: HttpRequest) -> HttpResponse { match req.match_info().get("action") { Some(action) => { let key_code = match action { "up" => win_key_codes::VK_VOLUME_UP, "down" => win_key_codes::VK_VOLUME_DOWN, "play_pause" => win_key_codes::VK_MEDIA_PLAY_PAUSE, "prev" => win_key_codes::VK_LEFT, "next" => win_key_codes::VK_RIGHT, _ => return HttpResponse::BadRequest().body("Bad request"), }; win_send_key_event(key_code, true, 10); win_send_key_event(key_code, false, 10); HttpResponse::NoContent().body("") } None => HttpResponse::BadRequest().body("Bad request"), } } #[actix_web::main] async fn main() -> std::io::Result<()> { let port = 8030; println!("Chiudi questa finestra per terminare il programma. Collegati alla porta {} per controllare il volume.", port); let mut candidates = vec![]; if let Ok(adapters) = ipconfig::get_adapters() { for adapter in adapters { if adapter.oper_status() == ipconfig::OperStatus::IfOperStatusUp { let desc = adapter.description().to_lowercase().to_string(); if !desc.contains("virtual") && !desc.contains("loopback") { for addr in adapter.ip_addresses() { match addr { std::net::IpAddr::V4(v4addr) if v4addr.is_private() => { candidates.push(v4addr.clone()); } _ => {} } } } } } } if let Some(addr) = candidates.first() { qr2term::print_qr(format!("http://{}:{}/", addr, port)).unwrap(); } HttpServer::new(|| { App::new() .route("/", web::get().to(index)) .route("/a/{action}", web::get().to(action)) }) .bind(("0.0.0.0", port))? .run() .await }