// See LICENSE file for copyright and license details. extern crate libc; extern crate x11; extern crate unix_socket; #[macro_use] extern crate nom; pub mod safe_x11; pub mod command; pub mod dotwm; pub mod event; pub mod socket; use dotwm::DotWM; use command::*; use event::{Event,select_event}; use socket::parser; use std::collections::HashMap; use x11::xlib; use x11::xlib::XEvent; use x11::keysym; use std::fs; use std::io::{Read,Write}; use unix_socket::UnixListener; const SOCKET_PATH: &'static str = "./dotwm.sock"; fn main() { println!("Creating dotwm"); let mut dotwm = DotWM::new(); let mut bindings: BindingHash = HashMap::new(); let x11_fd = safe_x11::x11_fd(dotwm.display); add_binding(&mut dotwm, &mut bindings, keysym::XK_q, xlib::Mod4Mask | xlib::ShiftMask, quit_dotwm, &[]); let listener = UnixListener::bind(SOCKET_PATH).unwrap(); exec_cmd("./autostart", &[]).unwrap(); // Main loop while !dotwm.finish { let event = unsafe { select_event(dotwm.display, x11_fd, &listener) }; match event { Event::Key(mut e, true) => { let keysym = unsafe { xlib::XLookupKeysym(&mut e, 0) as u32 }; let mask = e.state; exec_func(&mut dotwm, &mut bindings, keysym, mask, xlib::XEvent::from(e)); }, Event::Map(e) => { // If the window has override_redirect setted to true, this should not // be handled by the wm. let map_event = xlib::XMapEvent::from(e); if map_event.override_redirect == 0 { dotwm.add_window(map_event.window); } else { println!("Map event 0 :("); } } Event::Unmap(e) => { dotwm.remove_window(e.window); }, Event::Enter(e) => { if let Some(idx) = dotwm.find_window(e.window) { dotwm.change_focus_of(idx); } }, Event::Socket(stream) => { let mut s = stream.try_clone().unwrap(); let mut buf = String::new(); s.read_to_string(&mut buf).unwrap(); for line in buf.lines() { let res = parser::parse(&line); match res { Ok(pcmd) => { pcmd.handle(&mut dotwm, &mut bindings); let _ = write!(s, "+ok"); }, Err(e) => { let _ = write!(s, "-{}", e); }, } } }, _ => println!("Unknown event"), } collect_zombies(); } let _ = fs::remove_file(SOCKET_PATH); }