@@ -21,15 +21,12 @@ use std::str;
21
21
22
22
type CallbackFunction = dyn Fn ( & CStr ) -> ( CallbackResult , Option < CString > ) ;
23
23
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
-
28
24
/// Configuration structure to setup the Software Keyboard applet.
29
25
#[ doc( alias = "SwkbdState" ) ]
30
26
pub struct SoftwareKeyboard {
31
27
state : Box < SwkbdState > ,
32
28
callback : Option < Box < CallbackFunction > > ,
29
+ callback_data : InternalCallbackData ,
33
30
error_message : Option < CString > ,
34
31
initial_text : Option < CString > ,
35
32
}
@@ -216,6 +213,20 @@ bitflags! {
216
213
}
217
214
}
218
215
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
+
219
230
impl SoftwareKeyboard {
220
231
/// Initialize a new configuration for the Software Keyboard applet depending on how many "exit" buttons are available to the user (1, 2 or 3).
221
232
///
@@ -244,6 +255,7 @@ impl SoftwareKeyboard {
244
255
callback : None ,
245
256
error_message : None ,
246
257
initial_text : None ,
258
+ callback_data : InternalCallbackData :: new ( ) ,
247
259
}
248
260
}
249
261
}
@@ -684,19 +696,19 @@ impl SoftwareKeyboard {
684
696
swkbd. shared_memory_size = shared_mem_size;
685
697
686
698
// 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) } ;
688
700
689
701
let mut swkbd_shared_mem_handle = 0 ;
690
702
691
- if unsafe { SWKBD_SHARED_MEM . is_null ( ) } {
703
+ if swkbd_shared_mem_ptr . is_null ( ) {
692
704
swkbd. result = SWKBD_OUTOFMEM ;
693
705
return SWKBD_BUTTON_NONE ;
694
706
}
695
707
696
708
let res = unsafe {
697
709
svcCreateMemoryBlock (
698
710
& mut swkbd_shared_mem_handle,
699
- SWKBD_SHARED_MEM as _ ,
711
+ swkbd_shared_mem_ptr as _ ,
700
712
shared_mem_size as _ ,
701
713
MEMPERM_READ | MEMPERM_WRITE ,
702
714
MEMPERM_READ | MEMPERM_WRITE ,
@@ -705,7 +717,7 @@ impl SoftwareKeyboard {
705
717
706
718
if R_FAILED ( res) {
707
719
unsafe {
708
- libc:: free ( SWKBD_SHARED_MEM ) ;
720
+ libc:: free ( swkbd_shared_mem_ptr ) ;
709
721
swkbd. result = SWKBD_OUTOFMEM ;
710
722
return SWKBD_BUTTON_NONE ;
711
723
}
@@ -722,7 +734,7 @@ impl SoftwareKeyboard {
722
734
. take ( swkbd. max_text_len as _ )
723
735
. chain ( once ( 0 ) ) ;
724
736
725
- let mut initial_text_cursor = SWKBD_SHARED_MEM . cast ( ) ;
737
+ let mut initial_text_cursor = swkbd_shared_mem_ptr . cast ( ) ;
726
738
727
739
for code_point in utf16_iter {
728
740
* initial_text_cursor = code_point;
@@ -736,7 +748,7 @@ impl SoftwareKeyboard {
736
748
unsafe {
737
749
std:: ptr:: copy_nonoverlapping (
738
750
extra. dict ,
739
- SWKBD_SHARED_MEM . add ( dict_off) . cast ( ) ,
751
+ swkbd_shared_mem_ptr . add ( dict_off) . cast ( ) ,
740
752
swkbd. dict_word_count as _ ,
741
753
)
742
754
} ;
@@ -747,7 +759,7 @@ impl SoftwareKeyboard {
747
759
unsafe {
748
760
std:: ptr:: copy_nonoverlapping (
749
761
extra. status_data ,
750
- SWKBD_SHARED_MEM . add ( status_off) . cast ( ) ,
762
+ swkbd_shared_mem_ptr . add ( status_off) . cast ( ) ,
751
763
1 ,
752
764
)
753
765
} ;
@@ -758,7 +770,7 @@ impl SoftwareKeyboard {
758
770
unsafe {
759
771
std:: ptr:: copy_nonoverlapping (
760
772
extra. learning_data ,
761
- SWKBD_SHARED_MEM . add ( learning_off) . cast ( ) ,
773
+ swkbd_shared_mem_ptr . add ( learning_off) . cast ( ) ,
762
774
1 ,
763
775
)
764
776
} ;
@@ -775,9 +787,12 @@ impl SoftwareKeyboard {
775
787
swkbd. __bindgen_anon_1 . reserved . fill ( 0 ) ;
776
788
777
789
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
+
778
793
aptSetMessageCallback (
779
794
Some ( Self :: swkbd_message_callback) ,
780
- std :: ptr :: addr_of_mut! ( extra ) . cast ( ) ,
795
+ ( & mut self . callback_data as * mut InternalCallbackData ) . cast ( ) ,
781
796
) ;
782
797
}
783
798
@@ -805,7 +820,7 @@ impl SoftwareKeyboard {
805
820
if swkbd. text_length > 0 {
806
821
let text16 = unsafe {
807
822
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 ( ) ,
809
824
swkbd. text_length as _ ,
810
825
) )
811
826
} ;
@@ -816,7 +831,7 @@ impl SoftwareKeyboard {
816
831
if swkbd. save_state_flags & ( 1 << 0 ) != 0 {
817
832
unsafe {
818
833
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 ( ) ,
820
835
extra. status_data ,
821
836
1 ,
822
837
)
@@ -826,14 +841,14 @@ impl SoftwareKeyboard {
826
841
if swkbd. save_state_flags & ( 1 << 1 ) != 0 {
827
842
unsafe {
828
843
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 ( ) ,
830
845
extra. learning_data ,
831
846
1 ,
832
847
)
833
848
} ;
834
849
}
835
850
836
- unsafe { libc:: free ( SWKBD_SHARED_MEM ) } ;
851
+ unsafe { libc:: free ( swkbd_shared_mem_ptr ) } ;
837
852
838
853
button
839
854
}
@@ -848,8 +863,9 @@ impl SoftwareKeyboard {
848
863
msg : * mut libc:: c_void ,
849
864
msg_size : libc:: size_t ,
850
865
) {
851
- let extra = unsafe { & mut * user. cast :: < SwkbdExtra > ( ) } ;
866
+ let data = unsafe { & mut * user. cast :: < InternalCallbackData > ( ) } ;
852
867
let swkbd = unsafe { & mut * msg. cast :: < SwkbdState > ( ) } ;
868
+ let extra = unsafe { & mut * data. extra } ;
853
869
854
870
if sender != ctru_sys:: APPID_SOFTWARE_KEYBOARD
855
871
|| msg_size != std:: mem:: size_of :: < SwkbdState > ( )
@@ -859,7 +875,7 @@ impl SoftwareKeyboard {
859
875
860
876
let text16 = unsafe {
861
877
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 ( ) ,
863
879
swkbd. text_length as usize + 1 ,
864
880
) )
865
881
} ;
0 commit comments