iced-yoda/wgpu/src/window/wayland.rs
2026-01-23 11:16:56 -05:00

115 lines
3.1 KiB
Rust

use crate::graphics::compositor::Window;
use cctk::sctk::{
dmabuf::{DmabufFeedback, DmabufHandler, DmabufState},
registry::{ProvidesRegistryState, RegistryState},
registry_handlers,
};
use raw_window_handle::{RawDisplayHandle, WaylandDisplayHandle};
use wayland_client::{
backend::Backend, globals::registry_queue_init, protocol::wl_buffer,
Connection, QueueHandle,
};
use wayland_protocols::wp::linux_dmabuf::zv1::client::{
zwp_linux_buffer_params_v1, zwp_linux_dmabuf_feedback_v1,
};
struct AppData {
registry_state: RegistryState,
dmabuf_state: DmabufState,
feedback: Option<DmabufFeedback>,
}
impl DmabufHandler for AppData {
fn dmabuf_state(&mut self) -> &mut DmabufState {
&mut self.dmabuf_state
}
fn dmabuf_feedback(
&mut self,
_conn: &Connection,
_qh: &QueueHandle<Self>,
_proxy: &zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1,
feedback: DmabufFeedback,
) {
self.feedback = Some(feedback);
}
fn created(
&mut self,
_conn: &Connection,
_qh: &QueueHandle<Self>,
_params: &zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1,
_buffer: wl_buffer::WlBuffer,
) {
}
fn failed(
&mut self,
_conn: &Connection,
_qh: &QueueHandle<Self>,
_params: &zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1,
) {
}
fn released(
&mut self,
_conn: &Connection,
_qh: &QueueHandle<Self>,
_buffer: &wl_buffer::WlBuffer,
) {
}
}
impl ProvidesRegistryState for AppData {
fn registry(&mut self) -> &mut RegistryState {
&mut self.registry_state
}
registry_handlers![,];
}
pub fn get_wayland_device_ids<W: Window>(window: &W) -> Option<(u16, u16)> {
if !wayland_sys::client::is_lib_available() {
return None;
}
let conn = match window.display_handle().map(|handle| handle.as_raw()) {
#[allow(unsafe_code)]
Ok(RawDisplayHandle::Wayland(WaylandDisplayHandle {
display, ..
})) => Connection::from_backend(unsafe {
Backend::from_foreign_display(display.as_ptr() as *mut _)
}),
_ => {
return None;
}
};
let (globals, mut event_queue) = registry_queue_init(&conn).unwrap();
let qh = event_queue.handle();
let mut app_data = AppData {
registry_state: RegistryState::new(&globals),
dmabuf_state: DmabufState::new(&globals, &qh),
feedback: None,
};
match app_data.dmabuf_state.version() {
Some(4..) => {
let _ = app_data.dmabuf_state.get_default_feedback(&qh).unwrap();
let feedback = loop {
let _ = event_queue.blocking_dispatch(&mut app_data).ok()?;
if let Some(feedback) = app_data.feedback.as_ref() {
break feedback;
}
};
let dev = feedback.main_device();
super::ids_from_dev(dev)
}
_ => None,
}
}
cctk::sctk::delegate_dmabuf!(AppData);
cctk::sctk::delegate_registry!(AppData);