X11: Add #[deny(unsafe_op_in_unsafe_fn)] (#3121)

* X11: Add #[deny(unsafe_op_in_unsafe_fn)]

* Enable #![deny(unsafe_op_in_unsafe_fn)] everywhere
This commit is contained in:
Mads Marquart 2023-09-30 21:43:41 +02:00 committed by GitHub
parent b2b4564a5f
commit af247eac0f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 237 additions and 191 deletions

View file

@ -572,7 +572,8 @@ impl DeviceId {
/// ///
/// **Passing this into a winit function will result in undefined behavior.** /// **Passing this into a winit function will result in undefined behavior.**
pub const unsafe fn dummy() -> Self { pub const unsafe fn dummy() -> Self {
DeviceId(platform_impl::DeviceId::dummy()) #[allow(unused_unsafe)]
DeviceId(unsafe { platform_impl::DeviceId::dummy() })
} }
} }

View file

@ -132,6 +132,7 @@
#![deny(rust_2018_idioms)] #![deny(rust_2018_idioms)]
#![deny(rustdoc::broken_intra_doc_links)] #![deny(rustdoc::broken_intra_doc_links)]
#![deny(clippy::all)] #![deny(clippy::all)]
#![deny(unsafe_op_in_unsafe_fn)]
#![cfg_attr(feature = "cargo-clippy", deny(warnings))] #![cfg_attr(feature = "cargo-clippy", deny(warnings))]
// Doc feature labels can be tested locally by running RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly doc // Doc feature labels can be tested locally by running RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly doc
#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![cfg_attr(docsrs, feature(doc_auto_cfg))]

View file

@ -1,4 +1,3 @@
#![deny(unsafe_op_in_unsafe_fn)]
#![allow(non_snake_case)] #![allow(non_snake_case)]
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]

View file

@ -250,37 +250,43 @@ impl KbdState {
.unwrap_or_else(|| "C".into()); .unwrap_or_else(|| "C".into());
let locale = CString::new(locale.into_vec()).unwrap(); let locale = CString::new(locale.into_vec()).unwrap();
let compose_table = (XKBCH.xkb_compose_table_new_from_locale)( let compose_table = unsafe {
self.xkb_context, (XKBCH.xkb_compose_table_new_from_locale)(
locale.as_ptr(), self.xkb_context,
ffi::xkb_compose_compile_flags::XKB_COMPOSE_COMPILE_NO_FLAGS, locale.as_ptr(),
); ffi::xkb_compose_compile_flags::XKB_COMPOSE_COMPILE_NO_FLAGS,
)
};
if compose_table.is_null() { if compose_table.is_null() {
// init of compose table failed, continue without compose // init of compose table failed, continue without compose
return; return;
} }
let compose_state = (XKBCH.xkb_compose_state_new)( let compose_state = unsafe {
compose_table, (XKBCH.xkb_compose_state_new)(
ffi::xkb_compose_state_flags::XKB_COMPOSE_STATE_NO_FLAGS, compose_table,
); ffi::xkb_compose_state_flags::XKB_COMPOSE_STATE_NO_FLAGS,
)
};
if compose_state.is_null() { if compose_state.is_null() {
// init of compose state failed, continue without compose // init of compose state failed, continue without compose
(XKBCH.xkb_compose_table_unref)(compose_table); unsafe { (XKBCH.xkb_compose_table_unref)(compose_table) };
return; return;
} }
let compose_state_2 = (XKBCH.xkb_compose_state_new)( let compose_state_2 = unsafe {
compose_table, (XKBCH.xkb_compose_state_new)(
ffi::xkb_compose_state_flags::XKB_COMPOSE_STATE_NO_FLAGS, compose_table,
); ffi::xkb_compose_state_flags::XKB_COMPOSE_STATE_NO_FLAGS,
)
};
if compose_state_2.is_null() { if compose_state_2.is_null() {
// init of compose state failed, continue without compose // init of compose state failed, continue without compose
(XKBCH.xkb_compose_table_unref)(compose_table); unsafe { (XKBCH.xkb_compose_table_unref)(compose_table) };
(XKBCH.xkb_compose_state_unref)(compose_state); unsafe { (XKBCH.xkb_compose_state_unref)(compose_state) };
return; return;
} }
@ -296,62 +302,71 @@ impl KbdState {
} }
unsafe fn de_init(&mut self) { unsafe fn de_init(&mut self) {
(XKBH.xkb_state_unref)(self.xkb_state); unsafe { (XKBH.xkb_state_unref)(self.xkb_state) };
self.xkb_state = ptr::null_mut(); self.xkb_state = ptr::null_mut();
(XKBH.xkb_keymap_unref)(self.xkb_keymap); unsafe { (XKBH.xkb_keymap_unref)(self.xkb_keymap) };
self.xkb_keymap = ptr::null_mut(); self.xkb_keymap = ptr::null_mut();
} }
#[cfg(feature = "x11")] #[cfg(feature = "x11")]
pub unsafe fn init_with_x11_keymap(&mut self) { pub unsafe fn init_with_x11_keymap(&mut self) {
if !self.xkb_keymap.is_null() { if !self.xkb_keymap.is_null() {
self.de_init(); unsafe { self.de_init() };
} }
// TODO: Support keyboards other than the "virtual core keyboard device". // TODO: Support keyboards other than the "virtual core keyboard device".
self.core_keyboard_id = (XKBXH.xkb_x11_get_core_keyboard_device_id)(self.xcb_connection); self.core_keyboard_id =
let keymap = (XKBXH.xkb_x11_keymap_new_from_device)( unsafe { (XKBXH.xkb_x11_get_core_keyboard_device_id)(self.xcb_connection) };
self.xkb_context, let keymap = unsafe {
self.xcb_connection, (XKBXH.xkb_x11_keymap_new_from_device)(
self.core_keyboard_id, self.xkb_context,
xkbcommon_dl::xkb_keymap_compile_flags::XKB_KEYMAP_COMPILE_NO_FLAGS, self.xcb_connection,
); self.core_keyboard_id,
xkbcommon_dl::xkb_keymap_compile_flags::XKB_KEYMAP_COMPILE_NO_FLAGS,
)
};
if keymap.is_null() { if keymap.is_null() {
panic!("Failed to get keymap from X11 server."); panic!("Failed to get keymap from X11 server.");
} }
let state = (XKBXH.xkb_x11_state_new_from_device)( let state = unsafe {
keymap, (XKBXH.xkb_x11_state_new_from_device)(
self.xcb_connection, keymap,
self.core_keyboard_id, self.xcb_connection,
); self.core_keyboard_id,
self.post_init(state, keymap); )
};
unsafe { self.post_init(state, keymap) };
} }
#[cfg(feature = "wayland")] #[cfg(feature = "wayland")]
pub unsafe fn init_with_fd(&mut self, fd: OwnedFd, size: usize) { pub unsafe fn init_with_fd(&mut self, fd: OwnedFd, size: usize) {
if !self.xkb_keymap.is_null() { if !self.xkb_keymap.is_null() {
self.de_init(); unsafe { self.de_init() };
} }
let map = MmapOptions::new() let map = unsafe {
.len(size) MmapOptions::new()
.map_copy_read_only(&fd) .len(size)
.unwrap(); .map_copy_read_only(&fd)
.unwrap()
};
let keymap = (XKBH.xkb_keymap_new_from_string)( let keymap = unsafe {
self.xkb_context, (XKBH.xkb_keymap_new_from_string)(
map.as_ptr() as *const _, self.xkb_context,
ffi::xkb_keymap_format::XKB_KEYMAP_FORMAT_TEXT_V1, map.as_ptr() as *const _,
ffi::xkb_keymap_compile_flags::XKB_KEYMAP_COMPILE_NO_FLAGS, ffi::xkb_keymap_format::XKB_KEYMAP_FORMAT_TEXT_V1,
); ffi::xkb_keymap_compile_flags::XKB_KEYMAP_COMPILE_NO_FLAGS,
)
};
if keymap.is_null() { if keymap.is_null() {
panic!("Received invalid keymap from compositor."); panic!("Received invalid keymap from compositor.");
} }
let state = (XKBH.xkb_state_new)(keymap); let state = unsafe { (XKBH.xkb_state_new)(keymap) };
self.post_init(state, keymap); unsafe { self.post_init(state, keymap) };
} }
pub fn key_repeats(&mut self, keycode: ffi::xkb_keycode_t) -> bool { pub fn key_repeats(&mut self, keycode: ffi::xkb_keycode_t) -> bool {

View file

@ -178,9 +178,9 @@ pub enum DeviceId {
impl DeviceId { impl DeviceId {
pub const unsafe fn dummy() -> Self { pub const unsafe fn dummy() -> Self {
#[cfg(wayland_platform)] #[cfg(wayland_platform)]
return DeviceId::Wayland(wayland::DeviceId::dummy()); return DeviceId::Wayland(unsafe { wayland::DeviceId::dummy() });
#[cfg(all(not(wayland_platform), x11_platform))] #[cfg(all(not(wayland_platform), x11_platform))]
return DeviceId::X(x11::DeviceId::dummy()); return DeviceId::X(unsafe { x11::DeviceId::dummy() });
} }
} }
@ -649,26 +649,31 @@ unsafe extern "C" fn x_error_callback(
if let Ok(ref xconn) = *xconn_lock { if let Ok(ref xconn) = *xconn_lock {
// Call all the hooks. // Call all the hooks.
let mut error_handled = false; let mut error_handled = false;
for hook in XLIB_ERROR_HOOKS.lock().unwrap().iter() { for hook in unsafe { XLIB_ERROR_HOOKS.lock() }.unwrap().iter() {
error_handled |= hook(display as *mut _, event as *mut _); error_handled |= hook(display as *mut _, event as *mut _);
} }
// `assume_init` is safe here because the array consists of `MaybeUninit` values, // `assume_init` is safe here because the array consists of `MaybeUninit` values,
// which do not require initialization. // which do not require initialization.
let mut buf: [MaybeUninit<c_char>; 1024] = MaybeUninit::uninit().assume_init(); let mut buf: [MaybeUninit<c_char>; 1024] = unsafe { MaybeUninit::uninit().assume_init() };
(xconn.xlib.XGetErrorText)( unsafe {
display, (xconn.xlib.XGetErrorText)(
(*event).error_code as c_int, display,
buf.as_mut_ptr() as *mut c_char, (*event).error_code as c_int,
buf.len() as c_int, buf.as_mut_ptr() as *mut c_char,
); buf.len() as c_int,
let description = CStr::from_ptr(buf.as_ptr() as *const c_char).to_string_lossy(); )
};
let description =
unsafe { CStr::from_ptr(buf.as_ptr() as *const c_char) }.to_string_lossy();
let error = XError { let error = unsafe {
description: description.into_owned(), XError {
error_code: (*event).error_code, description: description.into_owned(),
request_code: (*event).request_code, error_code: (*event).error_code,
minor_code: (*event).minor_code, request_code: (*event).request_code,
minor_code: (*event).minor_code,
}
}; };
// Don't log error. // Don't log error.

View file

@ -122,12 +122,14 @@ impl<T: 'static> EventProcessor<T> {
1 1
} }
let result = (wt.xconn.xlib.XCheckIfEvent)( let result = unsafe {
wt.xconn.display, (wt.xconn.xlib.XCheckIfEvent)(
event_ptr, wt.xconn.display,
Some(predicate), event_ptr,
std::ptr::null_mut(), Some(predicate),
); std::ptr::null_mut(),
)
};
result != 0 result != 0
} }

View file

@ -16,7 +16,7 @@ pub(crate) unsafe fn xim_set_callback(
) -> Result<(), XError> { ) -> Result<(), XError> {
// It's advisable to wrap variadic FFI functions in our own functions, as we want to minimize // It's advisable to wrap variadic FFI functions in our own functions, as we want to minimize
// access that isn't type-checked. // access that isn't type-checked.
(xconn.xlib.XSetIMValues)(xim, field, callback, ptr::null_mut::<()>()); unsafe { (xconn.xlib.XSetIMValues)(xim, field, callback, ptr::null_mut::<()>()) };
xconn.check_errors() xconn.check_errors()
} }
@ -30,14 +30,16 @@ pub(crate) unsafe fn set_instantiate_callback(
xconn: &Arc<XConnection>, xconn: &Arc<XConnection>,
client_data: ffi::XPointer, client_data: ffi::XPointer,
) -> Result<(), XError> { ) -> Result<(), XError> {
(xconn.xlib.XRegisterIMInstantiateCallback)( unsafe {
xconn.display, (xconn.xlib.XRegisterIMInstantiateCallback)(
ptr::null_mut(), xconn.display,
ptr::null_mut(), ptr::null_mut(),
ptr::null_mut(), ptr::null_mut(),
Some(xim_instantiate_callback), ptr::null_mut(),
client_data, Some(xim_instantiate_callback),
); client_data,
)
};
xconn.check_errors() xconn.check_errors()
} }
@ -45,14 +47,16 @@ pub(crate) unsafe fn unset_instantiate_callback(
xconn: &Arc<XConnection>, xconn: &Arc<XConnection>,
client_data: ffi::XPointer, client_data: ffi::XPointer,
) -> Result<(), XError> { ) -> Result<(), XError> {
(xconn.xlib.XUnregisterIMInstantiateCallback)( unsafe {
xconn.display, (xconn.xlib.XUnregisterIMInstantiateCallback)(
ptr::null_mut(), xconn.display,
ptr::null_mut(), ptr::null_mut(),
ptr::null_mut(), ptr::null_mut(),
Some(xim_instantiate_callback), ptr::null_mut(),
client_data, Some(xim_instantiate_callback),
); client_data,
)
};
xconn.check_errors() xconn.check_errors()
} }
@ -61,12 +65,14 @@ pub(crate) unsafe fn set_destroy_callback(
im: ffi::XIM, im: ffi::XIM,
inner: &ImeInner, inner: &ImeInner,
) -> Result<(), XError> { ) -> Result<(), XError> {
xim_set_callback( unsafe {
xconn, xim_set_callback(
im, xconn,
ffi::XNDestroyCallback_0.as_ptr() as *const _, im,
&inner.destroy_callback as *const _ as *mut _, ffi::XNDestroyCallback_0.as_ptr() as *const _,
) &inner.destroy_callback as *const _ as *mut _,
)
}
} }
#[derive(Debug)] #[derive(Debug)]
@ -82,14 +88,16 @@ enum ReplaceImError {
// includes replacing all existing input contexts and free'ing resources as necessary. This only // includes replacing all existing input contexts and free'ing resources as necessary. This only
// modifies existing state if all operations succeed. // modifies existing state if all operations succeed.
unsafe fn replace_im(inner: *mut ImeInner) -> Result<(), ReplaceImError> { unsafe fn replace_im(inner: *mut ImeInner) -> Result<(), ReplaceImError> {
let xconn = &(*inner).xconn; let xconn = unsafe { &(*inner).xconn };
let (new_im, is_fallback) = { let (new_im, is_fallback) = {
let new_im = (*inner).potential_input_methods.open_im(xconn, None); let new_im = unsafe { (*inner).potential_input_methods.open_im(xconn, None) };
let is_fallback = new_im.is_fallback(); let is_fallback = new_im.is_fallback();
( (
new_im.ok().ok_or_else(|| { new_im.ok().ok_or_else(|| {
ReplaceImError::MethodOpenFailed(Box::new((*inner).potential_input_methods.clone())) ReplaceImError::MethodOpenFailed(Box::new(unsafe {
(*inner).potential_input_methods.clone()
}))
})?, })?,
is_fallback, is_fallback,
) )
@ -98,16 +106,16 @@ unsafe fn replace_im(inner: *mut ImeInner) -> Result<(), ReplaceImError> {
// It's important to always set a destroy callback, since there's otherwise potential for us // It's important to always set a destroy callback, since there's otherwise potential for us
// to try to use or free a resource that's already been destroyed on the server. // to try to use or free a resource that's already been destroyed on the server.
{ {
let result = set_destroy_callback(xconn, new_im.im, &*inner); let result = unsafe { set_destroy_callback(xconn, new_im.im, &*inner) };
if result.is_err() { if result.is_err() {
let _ = close_im(xconn, new_im.im); let _ = unsafe { close_im(xconn, new_im.im) };
} }
result result
} }
.map_err(ReplaceImError::SetDestroyCallbackFailed)?; .map_err(ReplaceImError::SetDestroyCallbackFailed)?;
let mut new_contexts = HashMap::new(); let mut new_contexts = HashMap::new();
for (window, old_context) in (*inner).contexts.iter() { for (window, old_context) in unsafe { (*inner).contexts.iter() } {
let spot = old_context.as_ref().map(|old_context| old_context.ic_spot); let spot = old_context.as_ref().map(|old_context| old_context.ic_spot);
// Check if the IME was allowed on that context. // Check if the IME was allowed on that context.
@ -125,16 +133,18 @@ unsafe fn replace_im(inner: *mut ImeInner) -> Result<(), ReplaceImError> {
}; };
let new_context = { let new_context = {
let result = ImeContext::new( let result = unsafe {
xconn, ImeContext::new(
new_im.im, xconn,
style, new_im.im,
*window, style,
spot, *window,
(*inner).event_sender.clone(), spot,
); (*inner).event_sender.clone(),
)
};
if result.is_err() { if result.is_err() {
let _ = close_im(xconn, new_im.im); let _ = unsafe { close_im(xconn, new_im.im) };
} }
result.map_err(ReplaceImError::ContextCreationFailed)? result.map_err(ReplaceImError::ContextCreationFailed)?
}; };
@ -142,12 +152,14 @@ unsafe fn replace_im(inner: *mut ImeInner) -> Result<(), ReplaceImError> {
} }
// If we've made it this far, everything succeeded. // If we've made it this far, everything succeeded.
let _ = (*inner).destroy_all_contexts_if_necessary(); unsafe {
let _ = (*inner).close_im_if_necessary(); let _ = (*inner).destroy_all_contexts_if_necessary();
(*inner).im = Some(new_im); let _ = (*inner).close_im_if_necessary();
(*inner).contexts = new_contexts; (*inner).im = Some(new_im);
(*inner).is_destroyed = false; (*inner).contexts = new_contexts;
(*inner).is_fallback = is_fallback; (*inner).is_destroyed = false;
(*inner).is_fallback = is_fallback;
}
Ok(()) Ok(())
} }
@ -159,18 +171,18 @@ pub unsafe extern "C" fn xim_instantiate_callback(
) { ) {
let inner: *mut ImeInner = client_data as _; let inner: *mut ImeInner = client_data as _;
if !inner.is_null() { if !inner.is_null() {
let xconn = &(*inner).xconn; let xconn = unsafe { &(*inner).xconn };
match replace_im(inner) { match unsafe { replace_im(inner) } {
Ok(()) => { Ok(()) => unsafe {
let _ = unset_instantiate_callback(xconn, client_data); let _ = unset_instantiate_callback(xconn, client_data);
(*inner).is_fallback = false; (*inner).is_fallback = false;
} },
Err(err) => { Err(err) => unsafe {
if (*inner).is_destroyed { if (*inner).is_destroyed {
// We have no usable input methods! // We have no usable input methods!
panic!("Failed to reopen input method: {err:?}"); panic!("Failed to reopen input method: {err:?}");
} }
} },
} }
} }
} }
@ -186,13 +198,13 @@ pub unsafe extern "C" fn xim_destroy_callback(
) { ) {
let inner: *mut ImeInner = client_data as _; let inner: *mut ImeInner = client_data as _;
if !inner.is_null() { if !inner.is_null() {
(*inner).is_destroyed = true; unsafe { (*inner).is_destroyed = true };
let xconn = &(*inner).xconn; let xconn = unsafe { &(*inner).xconn };
if !(*inner).is_fallback { if unsafe { !(*inner).is_fallback } {
let _ = set_instantiate_callback(xconn, client_data); let _ = unsafe { set_instantiate_callback(xconn, client_data) };
// Attempt to open fallback input method. // Attempt to open fallback input method.
match replace_im(inner) { match unsafe { replace_im(inner) } {
Ok(()) => (*inner).is_fallback = true, Ok(()) => unsafe { (*inner).is_fallback = true },
Err(err) => { Err(err) => {
// We have no usable input methods! // We have no usable input methods!
panic!("Failed to open fallback input method: {err:?}"); panic!("Failed to open fallback input method: {err:?}");

View file

@ -217,15 +217,19 @@ impl ImeContext {
})); }));
let ic = match style as _ { let ic = match style as _ {
Style::Preedit(style) => ImeContext::create_preedit_ic( Style::Preedit(style) => unsafe {
xconn, ImeContext::create_preedit_ic(
im, xconn,
style, im,
window, style,
client_data as ffi::XPointer, window,
), client_data as ffi::XPointer,
Style::Nothing(style) => ImeContext::create_nothing_ic(xconn, im, style, window), )
Style::None(style) => ImeContext::create_none_ic(xconn, im, style, window), },
Style::Nothing(style) => unsafe {
ImeContext::create_nothing_ic(xconn, im, style, window)
},
Style::None(style) => unsafe { ImeContext::create_none_ic(xconn, im, style, window) },
} }
.ok_or(ImeContextCreationError::Null)?; .ok_or(ImeContextCreationError::Null)?;
@ -237,7 +241,7 @@ impl ImeContext {
ic, ic,
ic_spot: ffi::XPoint { x: 0, y: 0 }, ic_spot: ffi::XPoint { x: 0, y: 0 },
style, style,
_client_data: Box::from_raw(client_data), _client_data: unsafe { Box::from_raw(client_data) },
}; };
// Set the spot location, if it's present. // Set the spot location, if it's present.
@ -254,14 +258,16 @@ impl ImeContext {
style: XIMStyle, style: XIMStyle,
window: ffi::Window, window: ffi::Window,
) -> Option<ffi::XIC> { ) -> Option<ffi::XIC> {
let ic = (xconn.xlib.XCreateIC)( let ic = unsafe {
im, (xconn.xlib.XCreateIC)(
ffi::XNInputStyle_0.as_ptr() as *const _, im,
style, ffi::XNInputStyle_0.as_ptr() as *const _,
ffi::XNClientWindow_0.as_ptr() as *const _, style,
window, ffi::XNClientWindow_0.as_ptr() as *const _,
ptr::null_mut::<()>(), window,
); ptr::null_mut::<()>(),
)
};
(!ic.is_null()).then_some(ic) (!ic.is_null()).then_some(ic)
} }
@ -274,8 +280,7 @@ impl ImeContext {
client_data: ffi::XPointer, client_data: ffi::XPointer,
) -> Option<ffi::XIC> { ) -> Option<ffi::XIC> {
let preedit_callbacks = PreeditCallbacks::new(client_data); let preedit_callbacks = PreeditCallbacks::new(client_data);
let preedit_attr = util::memory::XSmartPointer::new( let preedit_attr = util::memory::XSmartPointer::new(xconn, unsafe {
xconn,
(xconn.xlib.XVaCreateNestedList)( (xconn.xlib.XVaCreateNestedList)(
0, 0,
ffi::XNPreeditStartCallback_0.as_ptr() as *const _, ffi::XNPreeditStartCallback_0.as_ptr() as *const _,
@ -287,20 +292,22 @@ impl ImeContext {
ffi::XNPreeditDrawCallback_0.as_ptr() as *const _, ffi::XNPreeditDrawCallback_0.as_ptr() as *const _,
&(preedit_callbacks.draw_callback) as *const _, &(preedit_callbacks.draw_callback) as *const _,
ptr::null_mut::<()>(), ptr::null_mut::<()>(),
), )
) })
.expect("XVaCreateNestedList returned NULL"); .expect("XVaCreateNestedList returned NULL");
let ic = (xconn.xlib.XCreateIC)( let ic = unsafe {
im, (xconn.xlib.XCreateIC)(
ffi::XNInputStyle_0.as_ptr() as *const _, im,
style, ffi::XNInputStyle_0.as_ptr() as *const _,
ffi::XNClientWindow_0.as_ptr() as *const _, style,
window, ffi::XNClientWindow_0.as_ptr() as *const _,
ffi::XNPreeditAttributes_0.as_ptr() as *const _, window,
preedit_attr.ptr, ffi::XNPreeditAttributes_0.as_ptr() as *const _,
ptr::null_mut::<()>(), preedit_attr.ptr,
); ptr::null_mut::<()>(),
)
};
(!ic.is_null()).then_some(ic) (!ic.is_null()).then_some(ic)
} }
@ -311,14 +318,16 @@ impl ImeContext {
style: XIMStyle, style: XIMStyle,
window: ffi::Window, window: ffi::Window,
) -> Option<ffi::XIC> { ) -> Option<ffi::XIC> {
let ic = (xconn.xlib.XCreateIC)( let ic = unsafe {
im, (xconn.xlib.XCreateIC)(
ffi::XNInputStyle_0.as_ptr() as *const _, im,
style, ffi::XNInputStyle_0.as_ptr() as *const _,
ffi::XNClientWindow_0.as_ptr() as *const _, style,
window, ffi::XNClientWindow_0.as_ptr() as *const _,
ptr::null_mut::<()>(), window,
); ptr::null_mut::<()>(),
)
};
(!ic.is_null()).then_some(ic) (!ic.is_null()).then_some(ic)
} }

View file

@ -9,12 +9,12 @@ use super::{
use crate::platform_impl::platform::x11::ime::ImeEventSender; use crate::platform_impl::platform::x11::ime::ImeEventSender;
pub(crate) unsafe fn close_im(xconn: &Arc<XConnection>, im: ffi::XIM) -> Result<(), XError> { pub(crate) unsafe fn close_im(xconn: &Arc<XConnection>, im: ffi::XIM) -> Result<(), XError> {
(xconn.xlib.XCloseIM)(im); unsafe { (xconn.xlib.XCloseIM)(im) };
xconn.check_errors() xconn.check_errors()
} }
pub(crate) unsafe fn destroy_ic(xconn: &Arc<XConnection>, ic: ffi::XIC) -> Result<(), XError> { pub(crate) unsafe fn destroy_ic(xconn: &Arc<XConnection>, ic: ffi::XIC) -> Result<(), XError> {
(xconn.xlib.XDestroyIC)(ic); unsafe { (xconn.xlib.XDestroyIC)(ic) };
xconn.check_errors() xconn.check_errors()
} }
@ -52,7 +52,7 @@ impl ImeInner {
pub unsafe fn close_im_if_necessary(&self) -> Result<bool, XError> { pub unsafe fn close_im_if_necessary(&self) -> Result<bool, XError> {
if !self.is_destroyed && self.im.is_some() { if !self.is_destroyed && self.im.is_some() {
close_im(&self.xconn, self.im.as_ref().unwrap().im).map(|_| true) unsafe { close_im(&self.xconn, self.im.as_ref().unwrap().im) }.map(|_| true)
} else { } else {
Ok(false) Ok(false)
} }
@ -60,7 +60,7 @@ impl ImeInner {
pub unsafe fn destroy_ic_if_necessary(&self, ic: ffi::XIC) -> Result<bool, XError> { pub unsafe fn destroy_ic_if_necessary(&self, ic: ffi::XIC) -> Result<bool, XError> {
if !self.is_destroyed { if !self.is_destroyed {
destroy_ic(&self.xconn, ic).map(|_| true) unsafe { destroy_ic(&self.xconn, ic) }.map(|_| true)
} else { } else {
Ok(false) Ok(false)
} }
@ -68,7 +68,7 @@ impl ImeInner {
pub unsafe fn destroy_all_contexts_if_necessary(&self) -> Result<bool, XError> { pub unsafe fn destroy_all_contexts_if_necessary(&self) -> Result<bool, XError> {
for context in self.contexts.values().flatten() { for context in self.contexts.values().flatten() {
self.destroy_ic_if_necessary(context.ic)?; unsafe { self.destroy_ic_if_necessary(context.ic)? };
} }
Ok(!self.is_destroyed) Ok(!self.is_destroyed)
} }

View file

@ -21,14 +21,16 @@ unsafe fn open_im(xconn: &Arc<XConnection>, locale_modifiers: &CStr) -> Option<f
// * The new locale modifiers if we succeeded in setting them. // * The new locale modifiers if we succeeded in setting them.
// * NULL if the locale modifiers string is malformed or if the // * NULL if the locale modifiers string is malformed or if the
// current locale is not supported by Xlib. // current locale is not supported by Xlib.
(xconn.xlib.XSetLocaleModifiers)(locale_modifiers.as_ptr()); unsafe { (xconn.xlib.XSetLocaleModifiers)(locale_modifiers.as_ptr()) };
let im = (xconn.xlib.XOpenIM)( let im = unsafe {
xconn.display, (xconn.xlib.XOpenIM)(
ptr::null_mut(), xconn.display,
ptr::null_mut(), ptr::null_mut(),
ptr::null_mut(), ptr::null_mut(),
); ptr::null_mut(),
)
};
if im.is_null() { if im.is_null() {
None None
@ -178,7 +180,7 @@ unsafe fn get_xim_servers(xconn: &Arc<XConnection>) -> Result<Vec<String>, GetXi
let atoms = xconn.atoms(); let atoms = xconn.atoms();
let servers_atom = atoms[XIM_SERVERS]; let servers_atom = atoms[XIM_SERVERS];
let root = (xconn.xlib.XDefaultRootWindow)(xconn.display); let root = unsafe { (xconn.xlib.XDefaultRootWindow)(xconn.display) };
let mut atoms: Vec<ffi::Atom> = xconn let mut atoms: Vec<ffi::Atom> = xconn
.get_property::<xproto::Atom>( .get_property::<xproto::Atom>(
@ -192,21 +194,23 @@ unsafe fn get_xim_servers(xconn: &Arc<XConnection>) -> Result<Vec<String>, GetXi
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let mut names: Vec<*const c_char> = Vec::with_capacity(atoms.len()); let mut names: Vec<*const c_char> = Vec::with_capacity(atoms.len());
(xconn.xlib.XGetAtomNames)( unsafe {
xconn.display, (xconn.xlib.XGetAtomNames)(
atoms.as_mut_ptr(), xconn.display,
atoms.len() as _, atoms.as_mut_ptr(),
names.as_mut_ptr() as _, atoms.len() as _,
); names.as_mut_ptr() as _,
names.set_len(atoms.len()); )
};
unsafe { names.set_len(atoms.len()) };
let mut formatted_names = Vec::with_capacity(names.len()); let mut formatted_names = Vec::with_capacity(names.len());
for name in names { for name in names {
let string = CStr::from_ptr(name) let string = unsafe { CStr::from_ptr(name) }
.to_owned() .to_owned()
.into_string() .into_string()
.map_err(GetXimServersError::InvalidUtf8)?; .map_err(GetXimServersError::InvalidUtf8)?;
(xconn.xlib.XFree)(name as _); unsafe { (xconn.xlib.XFree)(name as _) };
formatted_names.push(string.replace("@server=", "@im=")); formatted_names.push(string.replace("@server=", "@im="));
} }
xconn.check_errors().map_err(GetXimServersError::XError)?; xconn.check_errors().map_err(GetXimServersError::XError)?;

View file

@ -1,5 +1,3 @@
#![deny(unsafe_op_in_unsafe_fn)]
#[macro_use] #[macro_use]
mod util; mod util;

View file

@ -1,5 +1,4 @@
#![cfg(windows_platform)] #![cfg(windows_platform)]
#![deny(unsafe_op_in_unsafe_fn)]
use smol_str::SmolStr; use smol_str::SmolStr;
use windows_sys::Win32::{ use windows_sys::Win32::{

View file

@ -101,7 +101,8 @@ impl WindowId {
/// ///
/// **Passing this into a winit function will result in undefined behavior.** /// **Passing this into a winit function will result in undefined behavior.**
pub const unsafe fn dummy() -> Self { pub const unsafe fn dummy() -> Self {
WindowId(platform_impl::WindowId::dummy()) #[allow(unused_unsafe)]
WindowId(unsafe { platform_impl::WindowId::dummy() })
} }
} }