diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2023-08-07 19:44:40 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2023-08-10 14:49:38 +0400 |
| commit | ad3c3f8cefd38d2bf26b466d8e34eccde3bca443 (patch) | |
| tree | 5783df13fa895bb6a8244556fb31b6504312b82b /src/winit.rs | |
| download | niri-ad3c3f8cefd38d2bf26b466d8e34eccde3bca443.tar.gz niri-ad3c3f8cefd38d2bf26b466d8e34eccde3bca443.tar.bz2 niri-ad3c3f8cefd38d2bf26b466d8e34eccde3bca443.zip | |
Init from smallvil
Diffstat (limited to 'src/winit.rs')
| -rw-r--r-- | src/winit.rs | 139 |
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(()) +} |
