1
0
Fork 0
forked from wry/wry
wry/src/main.rs
2022-03-23 15:56:15 +01:00

207 lines
6.2 KiB
Rust

#![feature(
c_variadic,
thread_local,
label_break_value,
try_blocks,
generic_associated_types,
extern_types
)]
#![allow(
clippy::len_zero,
clippy::needless_lifetimes,
clippy::enum_variant_names,
clippy::useless_format,
clippy::redundant_clone
)]
use crate::acceptor::AcceptorError;
use crate::async_engine::{AsyncError, Phase};
use crate::backends::metal;
use crate::client::Clients;
use crate::clientmem::ClientMemError;
use crate::dbus::{Dbus, FALSE};
use crate::event_loop::EventLoopError;
use crate::forker::ForkerError;
use crate::globals::Globals;
use crate::ifs::wl_compositor::WlCompositorGlobal;
use crate::ifs::wl_shm::WlShmGlobal;
use crate::ifs::wl_subcompositor::WlSubcompositorGlobal;
use crate::ifs::wl_surface::NoneSurfaceExt;
use crate::ifs::xdg_wm_base::XdgWmBaseGlobal;
use crate::ifs::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1Global;
use crate::ifs::zxdg_decoration_manager_v1::ZxdgDecorationManagerV1Global;
use crate::render::RenderError;
use crate::sighand::SighandError;
use crate::state::State;
use crate::tree::{
container_layout, container_titles, float_layout, float_titles, DisplayNode, NodeIds,
};
use crate::udev::Udev;
use crate::utils::clonecell::CloneCell;
use crate::utils::errorfmt::ErrorFmt;
use crate::utils::fdcloser::FdCloser;
use crate::utils::numcell::NumCell;
use crate::utils::queue::AsyncQueue;
use crate::utils::run_toplevel::RunToplevel;
use crate::wheel::WheelError;
use crate::wire_dbus::org;
use crate::xkbcommon::XkbContext;
use acceptor::Acceptor;
use async_engine::AsyncEngine;
use event_loop::EventLoop;
use log::LevelFilter;
use std::cell::Cell;
use std::ops::Deref;
use std::rc::Rc;
use thiserror::Error;
use wheel::Wheel;
#[macro_use]
mod macros;
#[macro_use]
mod leaks;
mod acceptor;
mod async_engine;
mod backend;
mod backends;
mod bugs;
mod client;
mod clientmem;
mod config;
mod cursor;
mod dbus;
mod drm;
mod event_loop;
mod fixed;
mod forker;
mod format;
mod globals;
mod ifs;
mod libinput;
mod logind;
mod object;
mod pixman;
mod rect;
mod render;
mod sighand;
mod state;
mod tasks;
mod text;
mod theme;
mod time;
mod tree;
mod udev;
mod utils;
mod wheel;
mod wire;
mod wire_dbus;
mod wire_xcon;
mod xcon;
mod xkbcommon;
mod xwayland;
mod pango;
fn main() {
env_logger::builder()
.format_timestamp_millis()
.filter_level(LevelFilter::Info)
.filter_level(LevelFilter::Debug)
// .filter_level(LevelFilter::Trace)
.init();
if let Err(e) = main_() {
log::error!("A fatal error occurred: {}", ErrorFmt(e));
std::process::exit(1);
}
}
#[derive(Debug, Error)]
enum MainError {
#[error("The client acceptor caused an error")]
AcceptorError(#[from] AcceptorError),
#[error("The event loop caused an error")]
EventLoopError(#[from] EventLoopError),
#[error("The signal handler caused an error")]
SighandError(#[from] SighandError),
#[error("The clientmem subsystem caused an error")]
ClientmemError(#[from] ClientMemError),
#[error("The timer subsystem caused an error")]
WheelError(#[from] WheelError),
#[error("The async subsystem caused an error")]
AsyncError(#[from] AsyncError),
#[error("The render backend caused an error")]
RenderError(#[from] RenderError),
#[error("The ol' forker caused an error")]
ForkerError(#[from] ForkerError),
}
fn main_() -> Result<(), MainError> {
let forker = Rc::new(forker::ForkerProxy::create()?);
leaks::init();
render::init()?;
clientmem::init()?;
let el = EventLoop::new()?;
sighand::install(&el)?;
let xkb_ctx = XkbContext::new().unwrap();
let xkb_keymap = xkb_ctx.keymap_from_str(include_str!("keymap.xkb")).unwrap();
let wheel = Wheel::install(&el)?;
let engine = AsyncEngine::install(&el, &wheel)?;
let (_run_toplevel_future, run_toplevel) = RunToplevel::install(&engine);
let node_ids = NodeIds::default();
let state = Rc::new(State {
xkb_ctx,
backend: Default::default(),
forker: Default::default(),
default_keymap: xkb_keymap,
eng: engine.clone(),
el: el.clone(),
render_ctx: Default::default(),
cursors: Default::default(),
wheel,
clients: Clients::new(),
next_name: NumCell::new(1),
globals: Globals::new(),
output_ids: Default::default(),
root: Rc::new(DisplayNode::new(node_ids.next())),
node_ids,
backend_events: AsyncQueue::new(),
output_handlers: Default::default(),
seat_ids: Default::default(),
outputs: Default::default(),
seat_queue: Default::default(),
slow_clients: AsyncQueue::new(),
none_surface_ext: Rc::new(NoneSurfaceExt),
tree_changed_sent: Cell::new(false),
config: Default::default(),
input_device_ids: Default::default(),
input_device_handlers: Default::default(),
theme: Default::default(),
pending_container_layout: Default::default(),
pending_container_titles: Default::default(),
pending_float_layout: Default::default(),
pending_float_titles: Default::default(),
dbus: Dbus::new(&engine, &run_toplevel),
fdcloser: FdCloser::new(),
});
forker.install(&state);
let config = config::ConfigProxy::default(&state);
state.config.set(Some(Rc::new(config)));
let _global_event_handler = engine.spawn(tasks::handle_backend_events(state.clone()));
let _slow_client_handler = engine.spawn(tasks::handle_slow_clients(state.clone()));
let _container_do_layout = engine.spawn2(Phase::Layout, container_layout(state.clone()));
let _container_render_titles =
engine.spawn2(Phase::PostLayout, container_titles(state.clone()));
let _float_do_layout = engine.spawn2(Phase::Layout, float_layout(state.clone()));
let _float_render_titles = engine.spawn2(Phase::PostLayout, float_titles(state.clone()));
let socket_path = Acceptor::install(&state)?;
forker.setenv(b"WAYLAND_DISPLAY", socket_path.as_bytes());
let _xwayland = engine.spawn(xwayland::manage(state.clone()));
let _backend = engine.spawn(tasks::start_backend(state.clone()));
el.run()?;
drop(_xwayland);
state.clients.clear();
for (_, seat) in state.globals.seats.lock().deref() {
seat.clear();
}
leaks::log_leaked();
Ok(())
}