#[cfg(all(
feature = "x11",
not(any(
target_os = "android",
target_vendor = "apple",
target_os = "redox",
target_family = "wasm",
target_os = "windows"
))
))]
mod example {
use raw_window_handle::{
DisplayHandle, RawDisplayHandle, RawWindowHandle, WindowHandle, XcbDisplayHandle,
XcbWindowHandle,
};
use std::{env, num::NonZeroU32, ptr::NonNull};
use x11rb::{
connection::Connection,
protocol::{
xproto::{self, ConnectionExt as _},
Event,
},
xcb_ffi::XCBConnection,
};
const RED: u32 = 255 << 16;
pub(crate) fn run() {
let (conn, screen) = XCBConnection::connect(None).expect("Failed to connect to X server");
let display_handle = XcbDisplayHandle::new(
if env::var_os("SOFTBUFFER_NO_DISPLAY").is_some() {
None
} else {
NonNull::new(conn.get_raw_xcb_connection() as *mut _)
},
screen as _,
);
let mut width = 640u16;
let mut height = 480u16;
let window = conn.generate_id().unwrap();
let screen = &conn.setup().roots[screen];
let (root_visual, root_parent) = (screen.root_visual, screen.root);
conn.create_window(
x11rb::COPY_FROM_PARENT as _,
window,
root_parent,
0,
0,
width,
height,
0,
xproto::WindowClass::COPY_FROM_PARENT,
root_visual,
&xproto::CreateWindowAux::new()
.background_pixel(screen.white_pixel)
.event_mask(xproto::EventMask::EXPOSURE | xproto::EventMask::STRUCTURE_NOTIFY),
)
.unwrap()
.check()
.unwrap();
let mut window_handle = XcbWindowHandle::new(NonZeroU32::new(window).unwrap());
window_handle.visual_id = NonZeroU32::new(root_visual);
let display_handle =
unsafe { DisplayHandle::borrow_raw(RawDisplayHandle::Xcb(display_handle)) };
let window_handle =
unsafe { WindowHandle::borrow_raw(RawWindowHandle::Xcb(window_handle)) };
let context = softbuffer::Context::new(display_handle).unwrap();
let mut surface = softbuffer::Surface::new(&context, window_handle).unwrap();
let wm_protocols_atom = conn
.intern_atom(false, "WM_PROTOCOLS".as_bytes())
.unwrap()
.reply()
.unwrap()
.atom;
let delete_window_atom = conn
.intern_atom(false, "WM_DELETE_WINDOW".as_bytes())
.unwrap()
.reply()
.unwrap()
.atom;
conn.change_property(
xproto::PropMode::REPLACE as _,
window,
wm_protocols_atom,
xproto::AtomEnum::ATOM,
32,
1,
&delete_window_atom.to_ne_bytes(),
)
.unwrap()
.check()
.unwrap();
conn.map_window(window).unwrap().check().unwrap();
loop {
let event = conn.wait_for_event().unwrap();
match event {
Event::Expose(_) => {
surface
.resize(
NonZeroU32::new(width.into()).unwrap(),
NonZeroU32::new(height.into()).unwrap(),
)
.unwrap();
let mut buffer = surface.buffer_mut().unwrap();
buffer.fill(RED);
buffer.present().unwrap();
}
Event::ConfigureNotify(configure_notify) => {
width = configure_notify.width;
height = configure_notify.height;
}
Event::ClientMessage(cm) => {
if cm.data.as_data32()[0] == delete_window_atom {
break;
}
}
_ => {}
}
}
drop(context);
conn.destroy_window(window).unwrap().check().unwrap();
}
}
#[cfg(all(
feature = "x11",
not(any(
target_os = "android",
target_vendor = "apple",
target_os = "redox",
target_family = "wasm",
target_os = "windows"
))
))]
fn main() {
example::run();
}
#[cfg(not(all(
feature = "x11",
not(any(
target_os = "android",
target_vendor = "apple",
target_os = "redox",
target_family = "wasm",
target_os = "windows"
))
)))]
fn main() {
eprintln!("This example requires the `x11` feature to be enabled on a supported platform.");
}