1
0
Fork 0
forked from wry/wry

Merge pull request #302 from mahkoh/jorth/edition-2024

warn on unsafe-op-in-unsafe-fn
This commit is contained in:
mahkoh 2024-10-20 18:41:50 +02:00 committed by GitHub
commit 5b7ad4b060
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 457 additions and 355 deletions

View file

@ -155,11 +155,13 @@ fn write_egl_procs<W: Write>(f: &mut W) -> anyhow::Result<()> {
writeln!(f, " if self.{}.is_null() {{", name)?; writeln!(f, " if self.{}.is_null() {{", name)?;
writeln!(f, " panic!(\"Could not load `{}`\");", name)?; writeln!(f, " panic!(\"Could not load `{}`\");", name)?;
writeln!(f, " }}")?; writeln!(f, " }}")?;
writeln!(f, " unsafe {{")?;
writeln!( writeln!(
f, f,
" ptr::read(&self.{} as *const *mut u8 as *const unsafe extern fn({}) -> {})({})", " ptr::read(&self.{} as *const *mut u8 as *const unsafe extern fn({}) -> {})({})",
name, args_tys, ret, args_names name, args_tys, ret, args_names
)?; )?;
writeln!(f, " }}")?;
writeln!(f, " }}")?; writeln!(f, " }}")?;
} }
writeln!(f, "}}")?; writeln!(f, "}}")?;

View file

@ -164,7 +164,7 @@ unsafe fn with_client<T, F: FnOnce(&Client) -> T>(data: *const u8, f: F) -> T {
self.cell.set(self.val); self.cell.set(self.val);
} }
} }
CLIENT.with(|cell| { CLIENT.with(|cell| unsafe {
let client = data as *const Client; let client = data as *const Client;
Rc::increment_strong_count(client); Rc::increment_strong_count(client);
let client = Rc::from_raw(client); let client = Rc::from_raw(client);
@ -190,14 +190,16 @@ impl<T: Config> ConfigEntryGen<T> {
size: usize, size: usize,
) -> *const u8 { ) -> *const u8 {
logging::init(); logging::init();
init( unsafe {
srv_data, init(
srv_unref, srv_data,
srv_handler, srv_unref,
init_data, srv_handler,
size, init_data,
T::configure, size,
) T::configure,
)
}
} }
} }
@ -239,21 +241,25 @@ pub unsafe extern "C" fn init(
pressed_keysym: Cell::new(None), pressed_keysym: Cell::new(None),
feat_mod_mask: Cell::new(false), feat_mod_mask: Cell::new(false),
}); });
let init = slice::from_raw_parts(init, size); let init = unsafe { slice::from_raw_parts(init, size) };
client.handle_init_msg(init); client.handle_init_msg(init);
Rc::into_raw(client) as *const u8 Rc::into_raw(client) as *const u8
} }
pub unsafe extern "C" fn unref(data: *const u8) { pub unsafe extern "C" fn unref(data: *const u8) {
let client = data as *const Client; let client = data as *const Client;
drop(Rc::from_raw(client)); unsafe {
drop(Rc::from_raw(client));
}
} }
pub unsafe extern "C" fn handle_msg(data: *const u8, msg: *const u8, size: usize) { pub unsafe extern "C" fn handle_msg(data: *const u8, msg: *const u8, size: usize) {
with_client(data, |client| { unsafe {
let msg = slice::from_raw_parts(msg, size); with_client(data, |client| {
client.handle_msg(msg); let msg = slice::from_raw_parts(msg, size);
}); client.handle_msg(msg);
});
}
} }
macro_rules! get_response { macro_rules! get_response {

View file

@ -41,6 +41,7 @@
clippy::single_char_add_str, clippy::single_char_add_str,
clippy::single_match clippy::single_match
)] )]
#![warn(unsafe_op_in_unsafe_fn)]
use { use {
crate::{_private::ipc::WorkspaceSource, keyboard::ModifiedKeySym, video::Connector}, crate::{_private::ipc::WorkspaceSource, keyboard::ModifiedKeySym, video::Connector},

View file

@ -49,27 +49,31 @@ impl<T: 'static, F: Future<Output = T>> SpawnedFutureVTableProxy<T, F> {
}; };
unsafe fn poll(data: *mut u8, ctx: &mut Context<'_>) -> Poll<T> { unsafe fn poll(data: *mut u8, ctx: &mut Context<'_>) -> Poll<T> {
let task = (data as *const Task<T, F>).deref(); unsafe {
if &task.state & COMPLETED == 0 { let task = (data as *const Task<T, F>).deref();
task.waker.set(Some(ctx.waker().clone())); if &task.state & COMPLETED == 0 {
Poll::Pending task.waker.set(Some(ctx.waker().clone()));
} else if &task.state & EMPTIED == 0 { Poll::Pending
task.state.or_assign(EMPTIED); } else if &task.state & EMPTIED == 0 {
Poll::Ready(ptr::read(&*task.data.get().deref().result)) task.state.or_assign(EMPTIED);
} else { Poll::Ready(ptr::read(&*task.data.get().deref().result))
panic!("Future polled after it has already been emptied"); } else {
panic!("Future polled after it has already been emptied");
}
} }
} }
unsafe fn drop(data: *mut u8) { unsafe fn drop(data: *mut u8) {
{ unsafe {
let task = (data as *const Task<T, F>).deref(); {
task.state.or_assign(CANCELLED); let task = (data as *const Task<T, F>).deref();
if &task.state & RUNNING == 0 { task.state.or_assign(CANCELLED);
task.drop_data(); if &task.state & RUNNING == 0 {
task.drop_data();
}
} }
Task::<T, F>::dec_ref_count(data as _);
} }
Task::<T, F>::dec_ref_count(data as _);
} }
} }
@ -160,27 +164,33 @@ impl<T, F: Future<Output = T>> Task<T, F> {
); );
unsafe fn run_proxy(data: *const u8, run: bool) { unsafe fn run_proxy(data: *const u8, run: bool) {
let task = data as *const Self; unsafe {
if run { let task = data as *const Self;
task.deref().run(); if run {
} else { task.deref().run();
Self::task_runnable_dropped(task); } else {
Self::task_runnable_dropped(task);
}
Self::dec_ref_count(task);
} }
Self::dec_ref_count(task);
} }
#[cold] #[cold]
unsafe fn task_runnable_dropped(task: *const Self) { unsafe fn task_runnable_dropped(task: *const Self) {
let task = task.deref(); unsafe {
task.state.and_assign(!RUNNING); let task = task.deref();
if task.state.get() & CANCELLED != 0 { task.state.and_assign(!RUNNING);
task.drop_data(); if task.state.get() & CANCELLED != 0 {
task.drop_data();
}
} }
} }
unsafe fn dec_ref_count(slf: *const Self) { unsafe fn dec_ref_count(slf: *const Self) {
if slf.deref().ref_count.fetch_sub(1) == 1 { unsafe {
drop(Box::from_raw(slf as *mut Self)); if slf.deref().ref_count.fetch_sub(1) == 1 {
drop(Box::from_raw(slf as *mut Self));
}
} }
} }
@ -189,80 +199,92 @@ impl<T, F: Future<Output = T>> Task<T, F> {
} }
unsafe fn waker_clone(data: *const ()) -> RawWaker { unsafe fn waker_clone(data: *const ()) -> RawWaker {
let task = &mut *(data as *mut Self); unsafe {
task.inc_ref_count(); let task = &mut *(data as *mut Self);
RawWaker::new(data, Self::VTABLE) task.inc_ref_count();
RawWaker::new(data, Self::VTABLE)
}
} }
unsafe fn waker_wake(data: *const ()) { unsafe fn waker_wake(data: *const ()) {
Self::waker_wake_by_ref(data); unsafe {
Self::waker_drop(data); Self::waker_wake_by_ref(data);
Self::waker_drop(data);
}
} }
unsafe fn waker_wake_by_ref(data: *const ()) { unsafe fn waker_wake_by_ref(data: *const ()) {
(data as *const Self).deref().schedule_run(); unsafe {
(data as *const Self).deref().schedule_run();
}
} }
unsafe fn waker_drop(data: *const ()) { unsafe fn waker_drop(data: *const ()) {
Self::dec_ref_count(data as _) unsafe { Self::dec_ref_count(data as _) }
} }
unsafe fn schedule_run(&self) { unsafe fn schedule_run(&self) {
if &self.state & (COMPLETED | CANCELLED) == 0 { unsafe {
if &self.state & RUNNING == 0 { if &self.state & (COMPLETED | CANCELLED) == 0 {
self.state.or_assign(RUNNING); if &self.state & RUNNING == 0 {
self.inc_ref_count(); self.state.or_assign(RUNNING);
let data = self as *const _ as _; self.inc_ref_count();
self.queue.push( let data = self as *const _ as _;
Runnable { self.queue.push(
data, Runnable {
run: Self::run_proxy, data,
}, run: Self::run_proxy,
self.phase, },
); self.phase,
} else { );
self.state.or_assign(RUN_AGAIN); } else {
self.state.or_assign(RUN_AGAIN);
}
} }
} }
} }
unsafe fn run(&self) { unsafe fn run(&self) {
if &self.state & CANCELLED == 0 { unsafe {
let data = self.data.get().deref_mut(); if &self.state & CANCELLED == 0 {
self.inc_ref_count(); let data = self.data.get().deref_mut();
let raw_waker = RawWaker::new(self as *const _ as _, Self::VTABLE); self.inc_ref_count();
let waker = Waker::from_raw(raw_waker); let raw_waker = RawWaker::new(self as *const _ as _, Self::VTABLE);
let waker = Waker::from_raw(raw_waker);
let mut ctx = Context::from_waker(&waker); let mut ctx = Context::from_waker(&waker);
let poll = { let poll = {
dynamic_zone!(self.zone); dynamic_zone!(self.zone);
Pin::new_unchecked(&mut *data.future).poll(&mut ctx) Pin::new_unchecked(&mut *data.future).poll(&mut ctx)
}; };
if let Poll::Ready(d) = poll { if let Poll::Ready(d) = poll {
ManuallyDrop::drop(&mut data.future); ManuallyDrop::drop(&mut data.future);
ptr::write(&mut data.result, ManuallyDrop::new(d)); ptr::write(&mut data.result, ManuallyDrop::new(d));
self.state.or_assign(COMPLETED); self.state.or_assign(COMPLETED);
if let Some(waker) = self.waker.take() { if let Some(waker) = self.waker.take() {
waker.wake(); waker.wake();
}
} }
} }
}
self.state.and_assign(!RUNNING); self.state.and_assign(!RUNNING);
if &self.state & CANCELLED != 0 { if &self.state & CANCELLED != 0 {
self.drop_data(); self.drop_data();
} else if &self.state & RUN_AGAIN != 0 { } else if &self.state & RUN_AGAIN != 0 {
self.state.and_assign(!RUN_AGAIN); self.state.and_assign(!RUN_AGAIN);
self.schedule_run() self.schedule_run()
}
} }
} }
unsafe fn drop_data(&self) { unsafe fn drop_data(&self) {
if &self.state & COMPLETED == 0 { unsafe {
ManuallyDrop::drop(&mut self.data.get().deref_mut().future); if &self.state & COMPLETED == 0 {
} else if &self.state & EMPTIED == 0 { ManuallyDrop::drop(&mut self.data.get().deref_mut().future);
ManuallyDrop::drop(&mut self.data.get().deref_mut().result); } else if &self.state & EMPTIED == 0 {
ManuallyDrop::drop(&mut self.data.get().deref_mut().result);
}
} }
} }
} }

View file

@ -194,39 +194,43 @@ thread_local! {
} }
unsafe fn kill() -> ! { unsafe fn kill() -> ! {
c::signal(c::SIGBUS, c::SIG_DFL); unsafe {
raise(c::SIGBUS); c::signal(c::SIGBUS, c::SIG_DFL);
raise(c::SIGBUS);
}
unreachable!(); unreachable!();
} }
unsafe extern "C" fn sigbus(sig: i32, info: &c::siginfo_t, _ucontext: *mut c::c_void) { unsafe extern "C" fn sigbus(sig: i32, info: &c::siginfo_t, _ucontext: *mut c::c_void) {
assert_eq!(sig, c::SIGBUS); unsafe {
let mut memr_ptr = MEM.get(); assert_eq!(sig, c::SIGBUS);
while !memr_ptr.is_null() { let mut memr_ptr = MEM.get();
let memr = &*memr_ptr; while !memr_ptr.is_null() {
let mem = &*memr.mem; let memr = &*memr_ptr;
let lo = mem.data as *mut u8 as usize; let mem = &*memr.mem;
let hi = lo + mem.len(); let lo = mem.data as *mut u8 as usize;
let fault_addr = info.si_addr() as usize; let hi = lo + mem.len();
if fault_addr < lo || fault_addr >= hi { let fault_addr = info.si_addr() as usize;
memr_ptr = memr.outer; if fault_addr < lo || fault_addr >= hi {
continue; memr_ptr = memr.outer;
continue;
}
let res = c::mmap64(
lo as _,
hi - lo,
c::PROT_WRITE | c::PROT_READ,
c::MAP_ANONYMOUS | c::MAP_PRIVATE | c::MAP_FIXED,
-1,
0,
);
if res == c::MAP_FAILED {
kill();
}
mem.failed.set(true);
return;
} }
let res = c::mmap64( kill();
lo as _,
hi - lo,
c::PROT_WRITE | c::PROT_READ,
c::MAP_ANONYMOUS | c::MAP_PRIVATE | c::MAP_FIXED,
-1,
0,
);
if res == c::MAP_FAILED {
kill();
}
mem.failed.set(true);
return;
} }
kill();
} }
pub fn init() -> Result<(), ClientMemError> { pub fn init() -> Result<(), ClientMemError> {

View file

@ -170,7 +170,9 @@ unsafe extern "C" fn default_client_init(
extern "C" fn configure() { extern "C" fn configure() {
jay_toml_config::configure(); jay_toml_config::configure();
} }
jay_config::_private::client::init(srv_data, srv_unref, srv_handler, msg, size, configure) unsafe {
jay_config::_private::client::init(srv_data, srv_unref, srv_handler, msg, size, configure)
}
} }
impl ConfigProxy { impl ConfigProxy {
@ -279,11 +281,11 @@ impl ConfigProxy {
return Err(ConfigError::CopyConfigFile(e)); return Err(ConfigError::CopyConfigFile(e));
} }
let unlink = UnlinkOnDrop(&copy); let unlink = UnlinkOnDrop(&copy);
let lib = match Library::new(&copy) { let lib = match unsafe { Library::new(&copy) } {
Ok(l) => l, Ok(l) => l,
Err(e) => return Err(ConfigError::CouldNotLoadLibrary(e)), Err(e) => return Err(ConfigError::CouldNotLoadLibrary(e)),
}; };
let entry = lib.get::<&'static ConfigEntry>(b"JAY_CONFIG_ENTRY_V1\0"); let entry = unsafe { lib.get::<&'static ConfigEntry>(b"JAY_CONFIG_ENTRY_V1\0") };
let entry = match entry { let entry = match entry {
Ok(e) => *e, Ok(e) => *e,
Err(e) => return Err(ConfigError::LibraryDoesNotContainEntry(e)), Err(e) => return Err(ConfigError::LibraryDoesNotContainEntry(e)),
@ -295,18 +297,22 @@ impl ConfigProxy {
unsafe extern "C" fn unref(data: *const u8) { unsafe extern "C" fn unref(data: *const u8) {
let server = data as *const ConfigProxyHandler; let server = data as *const ConfigProxyHandler;
drop(Rc::from_raw(server)); unsafe {
drop(Rc::from_raw(server));
}
} }
unsafe extern "C" fn handle_msg(data: *const u8, msg: *const u8, size: usize) { unsafe extern "C" fn handle_msg(data: *const u8, msg: *const u8, size: usize) {
let server = (data as *const ConfigProxyHandler).deref(); unsafe {
if server.dropped.get() { let server = (data as *const ConfigProxyHandler).deref();
return; if server.dropped.get() {
return;
}
let rc = Rc::from_raw(server);
let msg = std::slice::from_raw_parts(msg, size);
rc.handle_request(msg);
mem::forget(rc);
} }
let rc = Rc::from_raw(server);
let msg = std::slice::from_raw_parts(msg, size);
rc.handle_request(msg);
mem::forget(rc);
} }
pub struct InvokedShortcut { pub struct InvokedShortcut {

View file

@ -83,12 +83,12 @@ unsafe extern "C" fn egl_log(
_ => Level::Warn, _ => Level::Warn,
}; };
let command = if !command.is_null() { let command = if !command.is_null() {
CStr::from_ptr(command).to_bytes() unsafe { CStr::from_ptr(command).to_bytes() }
} else { } else {
b"none" b"none"
}; };
let message = if !message.is_null() { let message = if !message.is_null() {
CStr::from_ptr(message).to_bytes() unsafe { CStr::from_ptr(message).to_bytes() }
} else { } else {
b"none" b"none"
}; };

View file

@ -76,24 +76,30 @@ impl EglContext {
&self, &self,
f: F, f: F,
) -> Result<T, RenderError> { ) -> Result<T, RenderError> {
if (self.dpy.egl.eglMakeCurrent)( unsafe {
self.dpy.dpy, if (self.dpy.egl.eglMakeCurrent)(
EGLSurface::none(), self.dpy.dpy,
EGLSurface::none(), EGLSurface::none(),
self.ctx, EGLSurface::none(),
) == EGL_FALSE self.ctx,
{ ) == EGL_FALSE
return Err(RenderError::MakeCurrent); {
return Err(RenderError::MakeCurrent);
}
let prev = CURRENT.get();
CURRENT.set(self.ctx);
let res = f();
if (self.dpy.egl.eglMakeCurrent)(
self.dpy.dpy,
EGLSurface::none(),
EGLSurface::none(),
prev,
) == EGL_FALSE
{
panic!("Could not restore EGLContext");
}
CURRENT.set(prev);
res
} }
let prev = CURRENT.get();
CURRENT.set(self.ctx);
let res = f();
if (self.dpy.egl.eglMakeCurrent)(self.dpy.dpy, EGLSurface::none(), EGLSurface::none(), prev)
== EGL_FALSE
{
panic!("Could not restore EGLContext");
}
CURRENT.set(prev);
res
} }
} }

View file

@ -312,21 +312,23 @@ unsafe fn query_formats(
) -> Result<AHashMap<u32, EglFormat>, RenderError> { ) -> Result<AHashMap<u32, EglFormat>, RenderError> {
let mut vec = vec![]; let mut vec = vec![];
let mut num = 0; let mut num = 0;
let res = procs.eglQueryDmaBufFormatsEXT(dpy, num, ptr::null_mut(), &mut num); let res = unsafe { procs.eglQueryDmaBufFormatsEXT(dpy, num, ptr::null_mut(), &mut num) };
if res != EGL_TRUE { if res != EGL_TRUE {
return Err(RenderError::QueryDmaBufFormats); return Err(RenderError::QueryDmaBufFormats);
} }
vec.reserve_exact(num as usize); vec.reserve_exact(num as usize);
let res = procs.eglQueryDmaBufFormatsEXT(dpy, num, vec.as_mut_ptr(), &mut num); let res = unsafe { procs.eglQueryDmaBufFormatsEXT(dpy, num, vec.as_mut_ptr(), &mut num) };
if res != EGL_TRUE { if res != EGL_TRUE {
return Err(RenderError::QueryDmaBufFormats); return Err(RenderError::QueryDmaBufFormats);
} }
vec.set_len(num as usize); unsafe {
vec.set_len(num as usize);
}
let mut res = AHashMap::new(); let mut res = AHashMap::new();
let formats = formats(); let formats = formats();
for fmt in vec { for fmt in vec {
if let Some(format) = formats.get(&(fmt as u32)) { if let Some(format) = formats.get(&(fmt as u32)) {
let (modifiers, external_only) = query_modifiers(procs, dpy, fmt, format)?; let (modifiers, external_only) = unsafe { query_modifiers(procs, dpy, fmt, format)? };
res.insert( res.insert(
format.drm, format.drm,
EglFormat { EglFormat {
@ -349,32 +351,38 @@ unsafe fn query_modifiers(
let mut mods = vec![]; let mut mods = vec![];
let mut ext_only = vec![]; let mut ext_only = vec![];
let mut num = 0; let mut num = 0;
let res = procs.eglQueryDmaBufModifiersEXT( let res = unsafe {
dpy, procs.eglQueryDmaBufModifiersEXT(
gl_format, dpy,
num, gl_format,
ptr::null_mut(), num,
ptr::null_mut(), ptr::null_mut(),
&mut num, ptr::null_mut(),
); &mut num,
)
};
if res != EGL_TRUE { if res != EGL_TRUE {
return Err(RenderError::QueryDmaBufModifiers); return Err(RenderError::QueryDmaBufModifiers);
} }
mods.reserve_exact(num as usize); mods.reserve_exact(num as usize);
ext_only.reserve_exact(num as usize); ext_only.reserve_exact(num as usize);
let res = procs.eglQueryDmaBufModifiersEXT( let res = unsafe {
dpy, procs.eglQueryDmaBufModifiersEXT(
gl_format, dpy,
num, gl_format,
mods.as_mut_ptr(), num,
ext_only.as_mut_ptr(), mods.as_mut_ptr(),
&mut num, ext_only.as_mut_ptr(),
); &mut num,
)
};
if res != EGL_TRUE { if res != EGL_TRUE {
return Err(RenderError::QueryDmaBufModifiers); return Err(RenderError::QueryDmaBufModifiers);
} }
mods.set_len(num as usize); unsafe {
ext_only.set_len(num as usize); mods.set_len(num as usize);
ext_only.set_len(num as usize);
}
let mut res = IndexMap::new(); let mut res = IndexMap::new();
for (modifier, ext_only) in mods.iter().copied().zip(ext_only.iter().copied()) { for (modifier, ext_only) in mods.iter().copied().zip(ext_only.iter().copied()) {
res.insert( res.insert(

View file

@ -19,7 +19,7 @@ unsafe fn get_extensions(ext: *const c::c_char) -> Option<AHashSet<String>> {
return None; return None;
} }
let mut res = AHashSet::new(); let mut res = AHashSet::new();
let ext = CStr::from_ptr(ext).to_bytes(); let ext = unsafe { CStr::from_ptr(ext).to_bytes() };
for part in ext.split_str(" ") { for part in ext.split_str(" ") {
let name = part.trim(); let name = part.trim();
if name.len() > 0 { if name.len() > 0 {
@ -32,8 +32,10 @@ unsafe fn get_extensions(ext: *const c::c_char) -> Option<AHashSet<String>> {
} }
unsafe fn get_dpy_extensions(dpy: EGLDisplay) -> Option<AHashSet<String>> { unsafe fn get_dpy_extensions(dpy: EGLDisplay) -> Option<AHashSet<String>> {
let ext = (EGL.as_ref()?.eglQueryString)(dpy, EGL_EXTENSIONS); unsafe {
get_extensions(ext) let ext = (EGL.as_ref()?.eglQueryString)(dpy, EGL_EXTENSIONS);
get_extensions(ext)
}
} }
fn get_typed_ext<T>(exts: &AHashSet<String>, mut base: T, map: &[(&str, T)]) -> T fn get_typed_ext<T>(exts: &AHashSet<String>, mut base: T, map: &[(&str, T)]) -> T
@ -103,7 +105,7 @@ pub(crate) unsafe fn get_display_ext(dpy: EGLDisplay) -> DisplayExt {
("EGL_KHR_wait_sync", KHR_WAIT_SYNC), ("EGL_KHR_wait_sync", KHR_WAIT_SYNC),
("EGL_ANDROID_native_fence_sync", ANDROID_NATIVE_FENCE_SYNC), ("EGL_ANDROID_native_fence_sync", ANDROID_NATIVE_FENCE_SYNC),
]; ];
match get_dpy_extensions(dpy) { match unsafe { get_dpy_extensions(dpy) } {
Some(exts) => get_typed_ext(&exts, DisplayExt::none(), &map), Some(exts) => get_typed_ext(&exts, DisplayExt::none(), &map),
_ => DisplayExt::none(), _ => DisplayExt::none(),
} }

View file

@ -21,41 +21,45 @@ impl GlProgram {
vert: &str, vert: &str,
frag: &str, frag: &str,
) -> Result<Self, RenderError> { ) -> Result<Self, RenderError> {
let vert = GlShader::compile(ctx, GL_VERTEX_SHADER, vert)?; unsafe {
let frag = GlShader::compile(ctx, GL_FRAGMENT_SHADER, frag)?; let vert = GlShader::compile(ctx, GL_VERTEX_SHADER, vert)?;
Self::link(&vert, &frag) let frag = GlShader::compile(ctx, GL_FRAGMENT_SHADER, frag)?;
Self::link(&vert, &frag)
}
} }
pub(in crate::gfx_apis::gl) unsafe fn link( pub(in crate::gfx_apis::gl) unsafe fn link(
vert: &GlShader, vert: &GlShader,
frag: &GlShader, frag: &GlShader,
) -> Result<Self, RenderError> { ) -> Result<Self, RenderError> {
let gles = vert.ctx.dpy.gles; unsafe {
let res = GlProgram { let gles = vert.ctx.dpy.gles;
ctx: vert.ctx.clone(), let res = GlProgram {
prog: (gles.glCreateProgram)(), ctx: vert.ctx.clone(),
}; prog: (gles.glCreateProgram)(),
(gles.glAttachShader)(res.prog, vert.shader); };
(gles.glAttachShader)(res.prog, frag.shader); (gles.glAttachShader)(res.prog, vert.shader);
(gles.glLinkProgram)(res.prog); (gles.glAttachShader)(res.prog, frag.shader);
(gles.glDetachShader)(res.prog, vert.shader); (gles.glLinkProgram)(res.prog);
(gles.glDetachShader)(res.prog, frag.shader); (gles.glDetachShader)(res.prog, vert.shader);
(gles.glDetachShader)(res.prog, frag.shader);
let mut ok = 0; let mut ok = 0;
(gles.glGetProgramiv)(res.prog, GL_LINK_STATUS, &mut ok); (gles.glGetProgramiv)(res.prog, GL_LINK_STATUS, &mut ok);
if ok == GL_FALSE as GLint { if ok == GL_FALSE as GLint {
return Err(RenderError::ProgramLink); return Err(RenderError::ProgramLink);
}
Ok(res)
} }
Ok(res)
} }
pub unsafe fn get_uniform_location(&self, name: &CStr) -> GLint { pub unsafe fn get_uniform_location(&self, name: &CStr) -> GLint {
(self.ctx.dpy.gles.glGetUniformLocation)(self.prog, name.as_ptr() as _) unsafe { (self.ctx.dpy.gles.glGetUniformLocation)(self.prog, name.as_ptr() as _) }
} }
pub unsafe fn get_attrib_location(&self, name: &CStr) -> GLint { pub unsafe fn get_attrib_location(&self, name: &CStr) -> GLint {
(self.ctx.dpy.gles.glGetAttribLocation)(self.prog, name.as_ptr() as _) unsafe { (self.ctx.dpy.gles.glGetAttribLocation)(self.prog, name.as_ptr() as _) }
} }
} }

View file

@ -39,10 +39,17 @@ impl GlRenderBuffer {
}; };
let gles = &ctx.dpy.gles; let gles = &ctx.dpy.gles;
let mut rbo = 0; let mut rbo = 0;
(gles.glGenRenderbuffers)(1, &mut rbo); unsafe {
(gles.glBindRenderbuffer)(GL_RENDERBUFFER, rbo); (gles.glGenRenderbuffers)(1, &mut rbo);
(gles.glRenderbufferStorage)(GL_RENDERBUFFER, shm_info.gl_internal_format, width, height); (gles.glBindRenderbuffer)(GL_RENDERBUFFER, rbo);
(gles.glBindRenderbuffer)(GL_RENDERBUFFER, 0); (gles.glRenderbufferStorage)(
GL_RENDERBUFFER,
shm_info.gl_internal_format,
width,
height,
);
(gles.glBindRenderbuffer)(GL_RENDERBUFFER, 0);
}
Ok(Rc::new(GlRenderBuffer { Ok(Rc::new(GlRenderBuffer {
_img: None, _img: None,
ctx: ctx.clone(), ctx: ctx.clone(),
@ -63,12 +70,14 @@ impl GlRenderBuffer {
} }
let gles = ctx.dpy.gles; let gles = ctx.dpy.gles;
let mut rbo = 0; let mut rbo = 0;
(gles.glGenRenderbuffers)(1, &mut rbo); unsafe {
(gles.glBindRenderbuffer)(GL_RENDERBUFFER, rbo); (gles.glGenRenderbuffers)(1, &mut rbo);
ctx.dpy (gles.glBindRenderbuffer)(GL_RENDERBUFFER, rbo);
.procs ctx.dpy
.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, GLeglImageOES(img.img.0)); .procs
(gles.glBindRenderbuffer)(GL_RENDERBUFFER, 0); .glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, GLeglImageOES(img.img.0));
(gles.glBindRenderbuffer)(GL_RENDERBUFFER, 0);
}
Ok(Rc::new(GlRenderBuffer { Ok(Rc::new(GlRenderBuffer {
_img: Some(img.clone()), _img: Some(img.clone()),
ctx: ctx.clone(), ctx: ctx.clone(),
@ -85,28 +94,30 @@ impl GlRenderBuffer {
) -> Result<GlFrameBuffer, RenderError> { ) -> Result<GlFrameBuffer, RenderError> {
let gles = self.ctx.dpy.gles; let gles = self.ctx.dpy.gles;
let mut fbo = 0; let mut fbo = 0;
(gles.glGenFramebuffers)(1, &mut fbo); unsafe {
(gles.glBindFramebuffer)(GL_FRAMEBUFFER, fbo); (gles.glGenFramebuffers)(1, &mut fbo);
(gles.glFramebufferRenderbuffer)( (gles.glBindFramebuffer)(GL_FRAMEBUFFER, fbo);
GL_FRAMEBUFFER, (gles.glFramebufferRenderbuffer)(
GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER,
GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0,
self.rbo, GL_RENDERBUFFER,
); self.rbo,
let status = (gles.glCheckFramebufferStatus)(GL_FRAMEBUFFER); );
(gles.glBindFramebuffer)(GL_FRAMEBUFFER, 0); let status = (gles.glCheckFramebufferStatus)(GL_FRAMEBUFFER);
let fb = GlFrameBuffer { (gles.glBindFramebuffer)(GL_FRAMEBUFFER, 0);
rb: self.clone(), let fb = GlFrameBuffer {
_tex: None, rb: self.clone(),
ctx: self.ctx.clone(), _tex: None,
fbo, ctx: self.ctx.clone(),
width: self.width, fbo,
height: self.height, width: self.width,
}; height: self.height,
if status != GL_FRAMEBUFFER_COMPLETE { };
return Err(RenderError::CreateFramebuffer); if status != GL_FRAMEBUFFER_COMPLETE {
return Err(RenderError::CreateFramebuffer);
}
Ok(fb)
} }
Ok(fb)
} }
} }

View file

@ -20,17 +20,21 @@ impl GlShader {
src: &str, src: &str,
) -> Result<Self, RenderError> { ) -> Result<Self, RenderError> {
let gles = ctx.dpy.gles; let gles = ctx.dpy.gles;
let shader = (gles.glCreateShader)(ty); let shader = unsafe { (gles.glCreateShader)(ty) };
let res = GlShader { let res = GlShader {
ctx: ctx.clone(), ctx: ctx.clone(),
shader, shader,
}; };
let len = src.len() as _; let len = src.len() as _;
(gles.glShaderSource)(shader, 1, &(src.as_ptr() as _), &len); unsafe {
(gles.glCompileShader)(shader); (gles.glShaderSource)(shader, 1, &(src.as_ptr() as _), &len);
(gles.glCompileShader)(shader);
}
let mut ok = 0; let mut ok = 0;
(gles.glGetShaderiv)(shader, GL_COMPILE_STATUS, &mut ok); unsafe {
(gles.glGetShaderiv)(shader, GL_COMPILE_STATUS, &mut ok);
}
if ok == GL_FALSE as GLint { if ok == GL_FALSE as GLint {
return Err(RenderError::ShaderCompileFailed); return Err(RenderError::ShaderCompileFailed);
} }

View file

@ -44,16 +44,18 @@ pub(crate) struct TexProg {
impl TexProg { impl TexProg {
unsafe fn from(prog: GlProgram, alpha_multiplier: bool) -> Self { unsafe fn from(prog: GlProgram, alpha_multiplier: bool) -> Self {
let alpha = match alpha_multiplier { unsafe {
true => prog.get_uniform_location(c"alpha"), let alpha = match alpha_multiplier {
false => 0, true => prog.get_uniform_location(c"alpha"),
}; false => 0,
Self { };
pos: prog.get_attrib_location(c"pos"), Self {
texcoord: prog.get_attrib_location(c"texcoord"), pos: prog.get_attrib_location(c"pos"),
tex: prog.get_uniform_location(c"tex"), texcoord: prog.get_attrib_location(c"texcoord"),
alpha, tex: prog.get_uniform_location(c"tex"),
prog, alpha,
prog,
}
} }
} }
} }
@ -129,8 +131,10 @@ impl GlRenderContext {
tex_frac_src.push_str("#define ALPHA\n"); tex_frac_src.push_str("#define ALPHA\n");
} }
tex_frac_src.push_str(tex_frag); tex_frac_src.push_str(tex_frag);
let prog = GlProgram::from_shaders(ctx, tex_vert, &tex_frac_src)?; unsafe {
Ok::<_, RenderError>(TexProg::from(prog, alpha_multiplier)) let prog = GlProgram::from_shaders(ctx, tex_vert, &tex_frac_src)?;
Ok::<_, RenderError>(TexProg::from(prog, alpha_multiplier))
}
}; };
Ok::<_, RenderError>(enum_map! { Ok::<_, RenderError>(enum_map! {
TexCopyType::Identity => enum_map! { TexCopyType::Identity => enum_map! {
@ -149,11 +153,13 @@ impl GlRenderContext {
} else { } else {
None None
}; };
let fill_prog = GlProgram::from_shaders( let fill_prog = unsafe {
ctx, GlProgram::from_shaders(
include_str!("../shaders/fill.vert.glsl"), ctx,
include_str!("../shaders/fill.frag.glsl"), include_str!("../shaders/fill.vert.glsl"),
)?; include_str!("../shaders/fill.frag.glsl"),
)?
};
Ok(Self { Ok(Self {
ctx: ctx.clone(), ctx: ctx.clone(),
gbm: ctx.dpy.gbm.clone(), gbm: ctx.dpy.gbm.clone(),
@ -164,8 +170,8 @@ impl GlRenderContext {
tex_internal, tex_internal,
tex_external, tex_external,
fill_prog_pos: fill_prog.get_attrib_location(c"pos"), fill_prog_pos: unsafe { fill_prog.get_attrib_location(c"pos") },
fill_prog_color: fill_prog.get_uniform_location(c"color"), fill_prog_color: unsafe { fill_prog.get_uniform_location(c"color") },
fill_prog, fill_prog,
gl_state: Default::default(), gl_state: Default::default(),

View file

@ -67,7 +67,9 @@ impl VulkanAllocation {
) { ) {
allocator.total.fetch_sub(self.size); allocator.total.fetch_sub(self.size);
let block = self.block.take().unwrap(); let block = self.block.take().unwrap();
do_free(gpu, &device.device, block, self.mem); unsafe {
do_free(gpu, &device.device, block, self.mem);
}
} }
} }
@ -363,12 +365,14 @@ unsafe fn do_free(
mut block: MemoryBlock<DeviceMemory>, mut block: MemoryBlock<DeviceMemory>,
ptr: Option<*mut u8>, ptr: Option<*mut u8>,
) { ) {
let device = AshMemoryDevice::wrap(device); unsafe {
if let Some(_ptr) = ptr { let device = AshMemoryDevice::wrap(device);
// log::info!("free = {:?} - {:?} ({})", ptr, ptr.add(block.size() as usize), block.size()); if let Some(_ptr) = ptr {
block.unmap(device); // log::info!("free = {:?} - {:?} ({})", ptr, ptr.add(block.size() as usize), block.size());
block.unmap(device);
}
gpu.dealloc(device, block);
} }
gpu.dealloc(device, block);
} }
impl Drop for UnsyncAllocatorStorage { impl Drop for UnsyncAllocatorStorage {

View file

@ -671,7 +671,7 @@ impl Drop for VulkanBoMapping {
impl MappedBuffer for VulkanBoMapping { impl MappedBuffer for VulkanBoMapping {
unsafe fn data(&self) -> &[u8] { unsafe fn data(&self) -> &[u8] {
&*self.data unsafe { &*self.data }
} }
fn data_ptr(&self) -> *mut u8 { fn data_ptr(&self) -> *mut u8 {

View file

@ -190,12 +190,12 @@ unsafe extern "system" fn debug_callback(
DebugUtilsMessageSeverityFlagsEXT::VERBOSE => Level::Trace, DebugUtilsMessageSeverityFlagsEXT::VERBOSE => Level::Trace,
_ => Level::Warn, _ => Level::Warn,
}; };
let data = &*p_callback_data; let data = unsafe { &*p_callback_data };
let message = Ustr::from_ptr(data.p_message); let message = unsafe { Ustr::from_ptr(data.p_message) };
let message_id_name = if data.p_message_id_name.is_null() { let message_id_name = if data.p_message_id_name.is_null() {
ustr!("<null>") ustr!("<null>")
} else { } else {
Ustr::from_ptr(data.p_message_id_name) unsafe { Ustr::from_ptr(data.p_message_id_name) }
}; };
log::log!( log::log!(
Level::Info, Level::Info,

View file

@ -41,12 +41,14 @@ unsafe extern "C" fn open_restricted(
_flags: c::c_int, _flags: c::c_int,
user_data: *mut c::c_void, user_data: *mut c::c_void,
) -> c::c_int { ) -> c::c_int {
let ud = (user_data as *const UserData).deref(); unsafe {
match ud.adapter.open(CStr::from_ptr(path)) { let ud = (user_data as *const UserData).deref();
Ok(f) => f.unwrap(), match ud.adapter.open(CStr::from_ptr(path)) {
Err(e) => { Ok(f) => f.unwrap(),
log::error!("Could not open device for libinput: {}", ErrorFmt(e)); Err(e) => {
-1 log::error!("Could not open device for libinput: {}", ErrorFmt(e));
-1
}
} }
} }
} }
@ -173,7 +175,7 @@ unsafe extern "C" fn jay_libinput_log_handler(
line: *const c::c_char, line: *const c::c_char,
) { ) {
assert!(line.is_not_null()); assert!(line.is_not_null());
let str = CStr::from_ptr(line); let str = unsafe { CStr::from_ptr(line) };
let priority = match LogPriority(priority as _) { let priority = match LogPriority(priority as _) {
LIBINPUT_LOG_PRIORITY_DEBUG => log::Level::Debug, LIBINPUT_LOG_PRIORITY_DEBUG => log::Level::Debug,
LIBINPUT_LOG_PRIORITY_INFO => log::Level::Info, LIBINPUT_LOG_PRIORITY_INFO => log::Level::Info,

View file

@ -37,7 +37,7 @@
clippy::unnecessary_cast, clippy::unnecessary_cast,
clippy::manual_flatten clippy::manual_flatten
)] )]
#![warn(clippy::allow_attributes)] #![warn(clippy::allow_attributes, unsafe_op_in_unsafe_fn)]
#[macro_use] #[macro_use]
mod macros; mod macros;

View file

@ -88,21 +88,23 @@ impl PwMemMap {
#[expect(dead_code)] #[expect(dead_code)]
pub unsafe fn read<T: Pod>(&self) -> &T { pub unsafe fn read<T: Pod>(&self) -> &T {
self.check::<T>(0); self.check::<T>(0);
(self.map.ptr.cast::<u8>().add(self.range.start) as *const T).deref() unsafe { (self.map.ptr.cast::<u8>().add(self.range.start) as *const T).deref() }
} }
#[expect(dead_code)] #[expect(dead_code)]
pub unsafe fn write<T: Pod>(&self) -> &mut T { pub unsafe fn write<T: Pod>(&self) -> &mut T {
self.check::<T>(0); self.check::<T>(0);
(self.map.ptr.cast::<u8>().add(self.range.start) as *mut T).deref_mut() unsafe { (self.map.ptr.cast::<u8>().add(self.range.start) as *mut T).deref_mut() }
} }
#[expect(dead_code)] #[expect(dead_code)]
pub unsafe fn bytes_mut(&self) -> &mut [u8] { pub unsafe fn bytes_mut(&self) -> &mut [u8] {
std::slice::from_raw_parts_mut( unsafe {
self.map.ptr.cast::<u8>().add(self.range.start) as _, std::slice::from_raw_parts_mut(
self.range.len(), self.map.ptr.cast::<u8>().add(self.range.start) as _,
) self.range.len(),
)
}
} }
fn check<T>(&self, offset: usize) { fn check<T>(&self, offset: usize) {
@ -136,11 +138,11 @@ impl PwMemMap {
impl<T: Pod> PwMemTyped<T> { impl<T: Pod> PwMemTyped<T> {
pub unsafe fn read(&self) -> &T { pub unsafe fn read(&self) -> &T {
(self.mem.map.ptr.cast::<u8>().add(self.offset) as *const T).deref() unsafe { (self.mem.map.ptr.cast::<u8>().add(self.offset) as *const T).deref() }
} }
pub unsafe fn write(&self) -> &mut T { pub unsafe fn write(&self) -> &mut T {
(self.mem.map.ptr.cast::<u8>().add(self.offset) as *mut T).deref_mut() unsafe { (self.mem.map.ptr.cast::<u8>().add(self.offset) as *mut T).deref_mut() }
} }
} }

View file

@ -241,7 +241,7 @@ impl Drop for UdmabufMap {
impl MappedBuffer for UdmabufMap { impl MappedBuffer for UdmabufMap {
unsafe fn data(&self) -> &[u8] { unsafe fn data(&self) -> &[u8] {
&*self.data unsafe { &*self.data }
} }
fn data_ptr(&self) -> *mut u8 { fn data_ptr(&self) -> *mut u8 {

View file

@ -296,8 +296,10 @@ struct NodeData<T> {
} }
unsafe fn dec_ref_count<T>(slf: NonNull<NodeData<T>>, n: usize) { unsafe fn dec_ref_count<T>(slf: NonNull<NodeData<T>>, n: usize) {
if slf.as_ref().rc.fetch_sub(n) == n { unsafe {
drop(Box::from_raw(slf.as_ptr())); if slf.as_ref().rc.fetch_sub(n) == n {
drop(Box::from_raw(slf.as_ptr()));
}
} }
} }
@ -337,55 +339,63 @@ impl<T> LinkedNode<T> {
} }
unsafe fn prepend_existing<T>(data: NonNull<NodeData<T>>, t: &NodeRef<T>) { unsafe fn prepend_existing<T>(data: NonNull<NodeData<T>>, t: &NodeRef<T>) {
let dref = data.as_ref(); unsafe {
let tref = t.data.as_ref(); let dref = data.as_ref();
if tref.rc.get() < LINKED_NODE_REF_COUNT { let tref = t.data.as_ref();
log::error!("Trying to prepend a node whose linked node has already been dropped"); if tref.rc.get() < LINKED_NODE_REF_COUNT {
return; log::error!("Trying to prepend a node whose linked node has already been dropped");
return;
}
t.detach();
tref.prev.set(dref.prev.get());
tref.next.set(data);
dref.prev.get().as_ref().next.set(t.data);
dref.prev.set(t.data);
} }
t.detach();
tref.prev.set(dref.prev.get());
tref.next.set(data);
dref.prev.get().as_ref().next.set(t.data);
dref.prev.set(t.data);
} }
unsafe fn prepend<T>(data: NonNull<NodeData<T>>, t: T) -> LinkedNode<T> { unsafe fn prepend<T>(data: NonNull<NodeData<T>>, t: T) -> LinkedNode<T> {
let dref = data.as_ref(); unsafe {
let node = NonNull::new_unchecked(Box::into_raw(Box::new(NodeData { let dref = data.as_ref();
rc: NumCell::new(LINKED_NODE_REF_COUNT), let node = NonNull::new_unchecked(Box::into_raw(Box::new(NodeData {
prev: Cell::new(dref.prev.get()), rc: NumCell::new(LINKED_NODE_REF_COUNT),
next: Cell::new(data), prev: Cell::new(dref.prev.get()),
data: Some(t), next: Cell::new(data),
}))); data: Some(t),
dref.prev.get().as_ref().next.set(node); })));
dref.prev.set(node); dref.prev.get().as_ref().next.set(node);
LinkedNode { data: node } dref.prev.set(node);
LinkedNode { data: node }
}
} }
unsafe fn append_existing<T>(data: NonNull<NodeData<T>>, t: &NodeRef<T>) { unsafe fn append_existing<T>(data: NonNull<NodeData<T>>, t: &NodeRef<T>) {
let dref = data.as_ref(); unsafe {
let tref = t.data.as_ref(); let dref = data.as_ref();
if tref.rc.get() < LINKED_NODE_REF_COUNT { let tref = t.data.as_ref();
log::error!("Trying to append a node whose linked node has already been dropped"); if tref.rc.get() < LINKED_NODE_REF_COUNT {
return; log::error!("Trying to append a node whose linked node has already been dropped");
return;
}
t.detach();
tref.prev.set(data);
tref.next.set(dref.next.get());
dref.next.get().as_ref().prev.set(t.data);
dref.next.set(t.data);
} }
t.detach();
tref.prev.set(data);
tref.next.set(dref.next.get());
dref.next.get().as_ref().prev.set(t.data);
dref.next.set(t.data);
} }
unsafe fn append<T>(data: NonNull<NodeData<T>>, t: T) -> LinkedNode<T> { unsafe fn append<T>(data: NonNull<NodeData<T>>, t: T) -> LinkedNode<T> {
let dref = data.as_ref(); unsafe {
let node = NonNull::new_unchecked(Box::into_raw(Box::new(NodeData { let dref = data.as_ref();
rc: NumCell::new(LINKED_NODE_REF_COUNT), let node = NonNull::new_unchecked(Box::into_raw(Box::new(NodeData {
prev: Cell::new(data), rc: NumCell::new(LINKED_NODE_REF_COUNT),
next: Cell::new(dref.next.get()), prev: Cell::new(data),
data: Some(t), next: Cell::new(dref.next.get()),
}))); data: Some(t),
dref.next.get().as_ref().prev.set(node); })));
dref.next.set(node); dref.next.get().as_ref().prev.set(node);
LinkedNode { data: node } dref.next.set(node);
LinkedNode { data: node }
}
} }

View file

@ -9,20 +9,20 @@ pub trait MutPtrExt<T: ?Sized> {
impl<T: ?Sized> PtrExt<T> for *const T { impl<T: ?Sized> PtrExt<T> for *const T {
#[inline(always)] #[inline(always)]
unsafe fn deref<'a>(self) -> &'a T { unsafe fn deref<'a>(self) -> &'a T {
&*self unsafe { &*self }
} }
} }
impl<T: ?Sized> PtrExt<T> for *mut T { impl<T: ?Sized> PtrExt<T> for *mut T {
#[inline(always)] #[inline(always)]
unsafe fn deref<'a>(self) -> &'a T { unsafe fn deref<'a>(self) -> &'a T {
&*self unsafe { &*self }
} }
} }
impl<T: ?Sized> MutPtrExt<T> for *mut T { impl<T: ?Sized> MutPtrExt<T> for *mut T {
#[inline(always)] #[inline(always)]
unsafe fn deref_mut<'a>(self) -> &'a mut T { unsafe fn deref_mut<'a>(self) -> &'a mut T {
&mut *self unsafe { &mut *self }
} }
} }

View file

@ -35,7 +35,7 @@ impl<T> VecStorage<T> {
} }
unsafe fn to_vector<U>(&mut self) -> Vec<U> { unsafe fn to_vector<U>(&mut self) -> Vec<U> {
Vec::from_raw_parts(self.ptr as _, 0, self.cap) unsafe { Vec::from_raw_parts(self.ptr as _, 0, self.cap) }
} }
} }

View file

@ -23,7 +23,7 @@ use {
pub unsafe fn ioctl<T>(fd: c::c_int, request: c::c_ulong, t: &mut T) -> Result<c::c_int, OsError> { pub unsafe fn ioctl<T>(fd: c::c_int, request: c::c_ulong, t: &mut T) -> Result<c::c_int, OsError> {
let mut ret; let mut ret;
loop { loop {
ret = c::ioctl(fd, request, &mut *t); ret = unsafe { c::ioctl(fd, request, &mut *t) };
if ret != -1 { if ret != -1 {
return Ok(ret); return Ok(ret);
} }

View file

@ -158,7 +158,7 @@ pub struct GbmBoMap {
impl MappedBuffer for GbmBoMap { impl MappedBuffer for GbmBoMap {
unsafe fn data(&self) -> &[u8] { unsafe fn data(&self) -> &[u8] {
&*self.data unsafe { &*self.data }
} }
fn data_ptr(&self) -> *mut u8 { fn data_ptr(&self) -> *mut u8 {
@ -171,36 +171,38 @@ impl MappedBuffer for GbmBoMap {
} }
unsafe fn export_bo(dmabuf_ids: &DmaBufIds, bo: *mut Bo) -> Result<DmaBuf, GbmError> { unsafe fn export_bo(dmabuf_ids: &DmaBufIds, bo: *mut Bo) -> Result<DmaBuf, GbmError> {
Ok(DmaBuf { unsafe {
id: dmabuf_ids.next(), Ok(DmaBuf {
width: gbm_bo_get_width(bo) as _, id: dmabuf_ids.next(),
height: gbm_bo_get_height(bo) as _, width: gbm_bo_get_width(bo) as _,
modifier: gbm_bo_get_modifier(bo), height: gbm_bo_get_height(bo) as _,
format: { modifier: gbm_bo_get_modifier(bo),
let format = gbm_bo_get_format(bo); format: {
match formats().get(&format).copied() { let format = gbm_bo_get_format(bo);
Some(f) => f, match formats().get(&format).copied() {
_ => return Err(GbmError::UnknownFormat), Some(f) => f,
} _ => return Err(GbmError::UnknownFormat),
},
planes: {
let mut planes = PlaneVec::new();
for plane in 0..gbm_bo_get_plane_count(bo) {
let offset = gbm_bo_get_offset(bo, plane);
let stride = gbm_bo_get_stride_for_plane(bo, plane);
let fd = gbm_bo_get_fd_for_plane(bo, plane);
if fd < 0 {
return Err(GbmError::DrmFd);
} }
planes.push(DmaBufPlane { },
offset, planes: {
stride, let mut planes = PlaneVec::new();
fd: Rc::new(OwnedFd::new(fd)), for plane in 0..gbm_bo_get_plane_count(bo) {
}) let offset = gbm_bo_get_offset(bo, plane);
} let stride = gbm_bo_get_stride_for_plane(bo, plane);
planes let fd = gbm_bo_get_fd_for_plane(bo, plane);
}, if fd < 0 {
}) return Err(GbmError::DrmFd);
}
planes.push(DmaBufPlane {
offset,
stride,
fd: Rc::new(OwnedFd::new(fd)),
})
}
planes
},
})
}
} }
impl GbmDevice { impl GbmDevice {

View file

@ -415,7 +415,7 @@ unsafe extern "C" fn jay_xkbcommon_log_handler(
line: *const c::c_char, line: *const c::c_char,
) { ) {
assert!(line.is_not_null()); assert!(line.is_not_null());
let buf = CStr::from_ptr(line); let buf = unsafe { CStr::from_ptr(line) };
let level = match XkbLogLevel(level) { let level = match XkbLogLevel(level) {
XKB_LOG_LEVEL_CRITICAL | XKB_LOG_LEVEL_ERROR => log::Level::Error, XKB_LOG_LEVEL_CRITICAL | XKB_LOG_LEVEL_ERROR => log::Level::Error,
XKB_LOG_LEVEL_WARNING => log::Level::Warn, XKB_LOG_LEVEL_WARNING => log::Level::Warn,