Skip to content

Commit 0eb4efe

Browse files
committed
Get rid of static mut by using our own callback data
1 parent 757afe9 commit 0eb4efe

File tree

1 file changed

+35
-19
lines changed

1 file changed

+35
-19
lines changed

ctru-rs/src/applets/swkbd.rs

+35-19
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,12 @@ use std::str;
2121

2222
type CallbackFunction = dyn Fn(&CStr) -> (CallbackResult, Option<CString>);
2323

24-
// I hate that we have to use this, but sometimes you gotta smuggle pointers into C callbacks
25-
// and that's just how things are
26-
static mut SWKBD_SHARED_MEM: *mut libc::c_void = std::ptr::null_mut();
27-
2824
/// Configuration structure to setup the Software Keyboard applet.
2925
#[doc(alias = "SwkbdState")]
3026
pub struct SoftwareKeyboard {
3127
state: Box<SwkbdState>,
3228
callback: Option<Box<CallbackFunction>>,
29+
callback_data: InternalCallbackData,
3330
error_message: Option<CString>,
3431
initial_text: Option<CString>,
3532
}
@@ -216,6 +213,20 @@ bitflags! {
216213
}
217214
}
218215

216+
struct InternalCallbackData {
217+
extra: *mut SwkbdExtra,
218+
swkbd_shared_mem_ptr: *mut libc::c_void,
219+
}
220+
221+
impl InternalCallbackData {
222+
fn new() -> Self {
223+
Self {
224+
extra: std::ptr::null_mut(),
225+
swkbd_shared_mem_ptr: std::ptr::null_mut(),
226+
}
227+
}
228+
}
229+
219230
impl SoftwareKeyboard {
220231
/// Initialize a new configuration for the Software Keyboard applet depending on how many "exit" buttons are available to the user (1, 2 or 3).
221232
///
@@ -244,6 +255,7 @@ impl SoftwareKeyboard {
244255
callback: None,
245256
error_message: None,
246257
initial_text: None,
258+
callback_data: InternalCallbackData::new(),
247259
}
248260
}
249261
}
@@ -684,19 +696,19 @@ impl SoftwareKeyboard {
684696
swkbd.shared_memory_size = shared_mem_size;
685697

686698
// Allocate shared mem
687-
unsafe { SWKBD_SHARED_MEM = libc::memalign(0x1000, shared_mem_size).cast() };
699+
let swkbd_shared_mem_ptr = unsafe { libc::memalign(0x1000, shared_mem_size) };
688700

689701
let mut swkbd_shared_mem_handle = 0;
690702

691-
if unsafe { SWKBD_SHARED_MEM.is_null() } {
703+
if swkbd_shared_mem_ptr.is_null() {
692704
swkbd.result = SWKBD_OUTOFMEM;
693705
return SWKBD_BUTTON_NONE;
694706
}
695707

696708
let res = unsafe {
697709
svcCreateMemoryBlock(
698710
&mut swkbd_shared_mem_handle,
699-
SWKBD_SHARED_MEM as _,
711+
swkbd_shared_mem_ptr as _,
700712
shared_mem_size as _,
701713
MEMPERM_READ | MEMPERM_WRITE,
702714
MEMPERM_READ | MEMPERM_WRITE,
@@ -705,7 +717,7 @@ impl SoftwareKeyboard {
705717

706718
if R_FAILED(res) {
707719
unsafe {
708-
libc::free(SWKBD_SHARED_MEM);
720+
libc::free(swkbd_shared_mem_ptr);
709721
swkbd.result = SWKBD_OUTOFMEM;
710722
return SWKBD_BUTTON_NONE;
711723
}
@@ -722,7 +734,7 @@ impl SoftwareKeyboard {
722734
.take(swkbd.max_text_len as _)
723735
.chain(once(0));
724736

725-
let mut initial_text_cursor = SWKBD_SHARED_MEM.cast();
737+
let mut initial_text_cursor = swkbd_shared_mem_ptr.cast();
726738

727739
for code_point in utf16_iter {
728740
*initial_text_cursor = code_point;
@@ -736,7 +748,7 @@ impl SoftwareKeyboard {
736748
unsafe {
737749
std::ptr::copy_nonoverlapping(
738750
extra.dict,
739-
SWKBD_SHARED_MEM.add(dict_off).cast(),
751+
swkbd_shared_mem_ptr.add(dict_off).cast(),
740752
swkbd.dict_word_count as _,
741753
)
742754
};
@@ -747,7 +759,7 @@ impl SoftwareKeyboard {
747759
unsafe {
748760
std::ptr::copy_nonoverlapping(
749761
extra.status_data,
750-
SWKBD_SHARED_MEM.add(status_off).cast(),
762+
swkbd_shared_mem_ptr.add(status_off).cast(),
751763
1,
752764
)
753765
};
@@ -758,7 +770,7 @@ impl SoftwareKeyboard {
758770
unsafe {
759771
std::ptr::copy_nonoverlapping(
760772
extra.learning_data,
761-
SWKBD_SHARED_MEM.add(learning_off).cast(),
773+
swkbd_shared_mem_ptr.add(learning_off).cast(),
762774
1,
763775
)
764776
};
@@ -775,9 +787,12 @@ impl SoftwareKeyboard {
775787
swkbd.__bindgen_anon_1.reserved.fill(0);
776788

777789
if extra.callback.is_some() {
790+
self.callback_data.extra = std::ptr::addr_of_mut!(extra);
791+
self.callback_data.swkbd_shared_mem_ptr = swkbd_shared_mem_ptr;
792+
778793
aptSetMessageCallback(
779794
Some(Self::swkbd_message_callback),
780-
std::ptr::addr_of_mut!(extra).cast(),
795+
(&mut self.callback_data as *mut InternalCallbackData).cast(),
781796
);
782797
}
783798

@@ -805,7 +820,7 @@ impl SoftwareKeyboard {
805820
if swkbd.text_length > 0 {
806821
let text16 = unsafe {
807822
widestring::Utf16Str::from_slice_unchecked(std::slice::from_raw_parts(
808-
SWKBD_SHARED_MEM.add(swkbd.text_offset as _).cast(),
823+
swkbd_shared_mem_ptr.add(swkbd.text_offset as _).cast(),
809824
swkbd.text_length as _,
810825
))
811826
};
@@ -816,7 +831,7 @@ impl SoftwareKeyboard {
816831
if swkbd.save_state_flags & (1 << 0) != 0 {
817832
unsafe {
818833
std::ptr::copy_nonoverlapping(
819-
SWKBD_SHARED_MEM.add(swkbd.status_offset as _).cast(),
834+
swkbd_shared_mem_ptr.add(swkbd.status_offset as _).cast(),
820835
extra.status_data,
821836
1,
822837
)
@@ -826,14 +841,14 @@ impl SoftwareKeyboard {
826841
if swkbd.save_state_flags & (1 << 1) != 0 {
827842
unsafe {
828843
std::ptr::copy_nonoverlapping(
829-
SWKBD_SHARED_MEM.add(swkbd.learning_offset as _).cast(),
844+
swkbd_shared_mem_ptr.add(swkbd.learning_offset as _).cast(),
830845
extra.learning_data,
831846
1,
832847
)
833848
};
834849
}
835850

836-
unsafe { libc::free(SWKBD_SHARED_MEM) };
851+
unsafe { libc::free(swkbd_shared_mem_ptr) };
837852

838853
button
839854
}
@@ -848,8 +863,9 @@ impl SoftwareKeyboard {
848863
msg: *mut libc::c_void,
849864
msg_size: libc::size_t,
850865
) {
851-
let extra = unsafe { &mut *user.cast::<SwkbdExtra>() };
866+
let data = unsafe { &mut *user.cast::<InternalCallbackData>() };
852867
let swkbd = unsafe { &mut *msg.cast::<SwkbdState>() };
868+
let extra = unsafe { &mut *data.extra };
853869

854870
if sender != ctru_sys::APPID_SOFTWARE_KEYBOARD
855871
|| msg_size != std::mem::size_of::<SwkbdState>()
@@ -859,7 +875,7 @@ impl SoftwareKeyboard {
859875

860876
let text16 = unsafe {
861877
widestring::Utf16Str::from_slice_unchecked(std::slice::from_raw_parts(
862-
SWKBD_SHARED_MEM.add(swkbd.text_offset as _).cast(),
878+
data.swkbd_shared_mem_ptr.add(swkbd.text_offset as _).cast(),
863879
swkbd.text_length as usize + 1,
864880
))
865881
};

0 commit comments

Comments
 (0)