aboutsummaryrefslogtreecommitdiff
path: root/src/winit.rs
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2023-08-07 19:44:40 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2023-08-10 14:49:38 +0400
commitad3c3f8cefd38d2bf26b466d8e34eccde3bca443 (patch)
tree5783df13fa895bb6a8244556fb31b6504312b82b /src/winit.rs
downloadniri-ad3c3f8cefd38d2bf26b466d8e34eccde3bca443.tar.gz
niri-ad3c3f8cefd38d2bf26b466d8e34eccde3bca443.tar.bz2
niri-ad3c3f8cefd38d2bf26b466d8e34eccde3bca443.zip
Init from smallvil
Diffstat (limited to 'src/winit.rs')
-rw-r--r--src/winit.rs139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/winit.rs b/src/winit.rs
new file mode 100644
index 00000000..6b1b04ae
--- /dev/null
+++ b/src/winit.rs
@@ -0,0 +1,139 @@
+use std::time::Duration;
+
+use smithay::{
+ backend::{
+ renderer::{
+ damage::OutputDamageTracker, element::surface::WaylandSurfaceRenderElement, gles::GlesRenderer,
+ },
+ winit::{self, WinitError, WinitEvent, WinitEventLoop, WinitGraphicsBackend},
+ },
+ output::{Mode, Output, PhysicalProperties, Subpixel},
+ reexports::calloop::{
+ timer::{TimeoutAction, Timer},
+ EventLoop,
+ },
+ utils::{Rectangle, Transform},
+};
+
+use crate::{CalloopData, Smallvil};
+
+pub fn init_winit(
+ event_loop: &mut EventLoop<CalloopData>,
+ data: &mut CalloopData,
+) -> Result<(), Box<dyn std::error::Error>> {
+ let display = &mut data.display;
+ let state = &mut data.state;
+
+ let (mut backend, mut winit) = winit::init()?;
+
+ let mode = Mode {
+ size: backend.window_size().physical_size,
+ refresh: 60_000,
+ };
+
+ let output = Output::new(
+ "winit".to_string(),
+ PhysicalProperties {
+ size: (0, 0).into(),
+ subpixel: Subpixel::Unknown,
+ make: "Smithay".into(),
+ model: "Winit".into(),
+ },
+ );
+ let _global = output.create_global::<Smallvil>(&display.handle());
+ output.change_current_state(Some(mode), Some(Transform::Flipped180), None, Some((0, 0).into()));
+ output.set_preferred(mode);
+
+ state.space.map_output(&output, (0, 0));
+
+ let mut damage_tracker = OutputDamageTracker::from_output(&output);
+
+ std::env::set_var("WAYLAND_DISPLAY", &state.socket_name);
+
+ let mut full_redraw = 0u8;
+
+ let timer = Timer::immediate();
+ event_loop.handle().insert_source(timer, move |_, _, data| {
+ winit_dispatch(
+ &mut backend,
+ &mut winit,
+ data,
+ &output,
+ &mut damage_tracker,
+ &mut full_redraw,
+ )
+ .unwrap();
+ TimeoutAction::ToDuration(Duration::from_millis(16))
+ })?;
+
+ Ok(())
+}
+
+pub fn winit_dispatch(
+ backend: &mut WinitGraphicsBackend<GlesRenderer>,
+ winit: &mut WinitEventLoop,
+ data: &mut CalloopData,
+ output: &Output,
+ damage_tracker: &mut OutputDamageTracker,
+ full_redraw: &mut u8,
+) -> Result<(), Box<dyn std::error::Error>> {
+ let display = &mut data.display;
+ let state = &mut data.state;
+
+ let res = winit.dispatch_new_events(|event| match event {
+ WinitEvent::Resized { size, .. } => {
+ output.change_current_state(
+ Some(Mode {
+ size,
+ refresh: 60_000,
+ }),
+ None,
+ None,
+ None,
+ );
+ }
+ WinitEvent::Input(event) => state.process_input_event(event),
+ _ => (),
+ });
+
+ if let Err(WinitError::WindowClosed) = res {
+ // Stop the loop
+ state.loop_signal.stop();
+
+ return Ok(());
+ } else {
+ res?;
+ }
+
+ *full_redraw = full_redraw.saturating_sub(1);
+
+ let size = backend.window_size().physical_size;
+ let damage = Rectangle::from_loc_and_size((0, 0), size);
+
+ backend.bind()?;
+ smithay::desktop::space::render_output::<_, WaylandSurfaceRenderElement<GlesRenderer>, _, _>(
+ output,
+ backend.renderer(),
+ 1.0,
+ 0,
+ [&state.space],
+ &[],
+ damage_tracker,
+ [0.1, 0.1, 0.1, 1.0],
+ )?;
+ backend.submit(Some(&[damage]))?;
+
+ state.space.elements().for_each(|window| {
+ window.send_frame(
+ output,
+ state.start_time.elapsed(),
+ Some(Duration::ZERO),
+ |_, _| Some(output.clone()),
+ )
+ });
+
+ state.space.refresh();
+ display.flush_clients()?;
+
+ Ok(())
+}