|
|
@ -96,7 +96,8 @@ impl Swkbd { |
|
|
|
|
|
|
|
|
|
|
|
/// Gets input from this keyboard and appends it to the provided string.
|
|
|
|
/// Gets input from this keyboard and appends it to the provided string.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// The text received from the keyboard can be up to 2048 bytes in length.
|
|
|
|
/// The text received from the keyboard will be truncated if it is greater than 2048 bytes
|
|
|
|
|
|
|
|
/// in length.
|
|
|
|
pub fn get_utf8(&mut self, buf: &mut String) -> Result<Button, Error> { |
|
|
|
pub fn get_utf8(&mut self, buf: &mut String) -> Result<Button, Error> { |
|
|
|
// Unfortunately the libctru API doesn't really provide a way to get the exact length
|
|
|
|
// Unfortunately the libctru API doesn't really provide a way to get the exact length
|
|
|
|
// of the string that it receieves from the software keyboard. Instead it expects you
|
|
|
|
// of the string that it receieves from the software keyboard. Instead it expects you
|
|
|
@ -104,34 +105,26 @@ impl Swkbd { |
|
|
|
// you have to set some upper limit on the potential size of the user's input.
|
|
|
|
// you have to set some upper limit on the potential size of the user's input.
|
|
|
|
const MAX_BYTES: usize = 2048; |
|
|
|
const MAX_BYTES: usize = 2048; |
|
|
|
let mut tmp = [0u8; MAX_BYTES]; |
|
|
|
let mut tmp = [0u8; MAX_BYTES]; |
|
|
|
let button = unsafe { self.get_bytes(&mut tmp)? }; |
|
|
|
let button = self.get_bytes(&mut tmp)?; |
|
|
|
|
|
|
|
|
|
|
|
// Make sure we haven't overflowed our buffer. libctru might already check this,
|
|
|
|
// libctru does, however, seem to ensure that the buffer will always contain a properly
|
|
|
|
// but we'll do it here too just in case
|
|
|
|
// terminated UTF-8 sequence even if the input has to be truncated, so these operations
|
|
|
|
|
|
|
|
// should be safe.
|
|
|
|
let len = unsafe { libc::strlen(tmp.as_ptr()) }; |
|
|
|
let len = unsafe { libc::strlen(tmp.as_ptr()) }; |
|
|
|
assert!(len <= MAX_BYTES); |
|
|
|
let utf8 = unsafe { str::from_utf8_unchecked(&tmp[..len]) }; |
|
|
|
|
|
|
|
|
|
|
|
// Not sure if this is falliable or not in this stage of the process,
|
|
|
|
// Copy the input into the user's `String`
|
|
|
|
// but catch any decoding errors to be sure
|
|
|
|
|
|
|
|
let utf8 = match str::from_utf8(&tmp[..len]) { |
|
|
|
|
|
|
|
Ok(parsed) => parsed, |
|
|
|
|
|
|
|
Err(_) => return Err(Error::InvalidInput), |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Finally, copy the validated input into the user's `String`
|
|
|
|
|
|
|
|
*buf += utf8; |
|
|
|
*buf += utf8; |
|
|
|
Ok(button) |
|
|
|
Ok(button) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Fills the provided buffer with a NUL-terminated sequence of bytes from the software
|
|
|
|
/// Fills the provided buffer with a UTF-8 encoded, NUL-terminated sequence of bytes from
|
|
|
|
/// keyboard
|
|
|
|
/// this software keyboard.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Unsafety
|
|
|
|
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// The received bytes are nominally UTF-8 formatted, but the provided buffer must be large
|
|
|
|
/// If the buffer is too small to contain the entire sequence received from the keyboard,
|
|
|
|
/// enough to receive both the text from the software keyboard along with a NUL-terminator.
|
|
|
|
/// the output will be truncated but should still be well-formed UTF-8
|
|
|
|
/// Otherwise undefined behavior can result.
|
|
|
|
pub fn get_bytes(&mut self, buf: &mut [u8]) -> Result<Button, Error> { |
|
|
|
pub unsafe fn get_bytes(&mut self, buf: &mut [u8]) -> Result<Button, Error> { |
|
|
|
unsafe { |
|
|
|
match swkbdInputText(self.state.as_mut(), buf.as_mut_ptr(), buf.len()) { |
|
|
|
match swkbdInputText(self.state.as_mut(), buf.as_mut_ptr(), buf.len()) { |
|
|
|
libctru::SWKBD_BUTTON_NONE => Err(self.parse_swkbd_error()), |
|
|
|
libctru::SWKBD_BUTTON_NONE => Err(self.parse_swkbd_error()), |
|
|
|
libctru::SWKBD_BUTTON_LEFT => Ok(Button::Left), |
|
|
|
libctru::SWKBD_BUTTON_LEFT => Ok(Button::Left), |
|
|
@ -140,6 +133,7 @@ impl Swkbd { |
|
|
|
_ => unreachable!(), |
|
|
|
_ => unreachable!(), |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Sets special features for this keyboard
|
|
|
|
/// Sets special features for this keyboard
|
|
|
|
pub fn set_features(&mut self, features: Features) { |
|
|
|
pub fn set_features(&mut self, features: Features) { |
|
|
|