From 1c7fb6507f818c92de57c7ca15a6ff4bc3f73bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 25 Aug 2022 19:41:50 +0200 Subject: [PATCH 1/2] Add a method to show the keyboard --- android-activity/src/game_activity/mod.rs | 11 +++++++++++ android-activity/src/lib.rs | 4 ++++ android-activity/src/native_activity/mod.rs | 4 ++++ 3 files changed, 19 insertions(+) diff --git a/android-activity/src/game_activity/mod.rs b/android-activity/src/game_activity/mod.rs index c551dae..312ee99 100644 --- a/android-activity/src/game_activity/mod.rs +++ b/android-activity/src/game_activity/mod.rs @@ -309,6 +309,17 @@ impl AndroidAppInner { } } + pub fn set_soft_input(&self, show: bool) { + unsafe { + let activity = (*self.native_app.as_ptr()).activity; + if show { + ffi::GameActivity_showSoftInput(activity, 0); + } else { + ffi::GameActivity_hideSoftInput(activity, 0); + } + } + } + pub fn enable_motion_axis(&mut self, axis: Axis) { unsafe { ffi::GameActivityPointerAxes_enableAxis(axis as i32) } } diff --git a/android-activity/src/lib.rs b/android-activity/src/lib.rs index 06c5b2e..1a0fb80 100644 --- a/android-activity/src/lib.rs +++ b/android-activity/src/lib.rs @@ -241,6 +241,10 @@ impl AndroidApp { self.inner.write().unwrap().disable_motion_axis(axis); } + pub fn set_soft_input(&self, show: bool) { + self.inner.read().unwrap().set_soft_input(show); + } + pub fn input_events<'b, F>(&self, callback: F) where F: FnMut(&input::InputEvent), diff --git a/android-activity/src/native_activity/mod.rs b/android-activity/src/native_activity/mod.rs index 552dd34..0ed672e 100644 --- a/android-activity/src/native_activity/mod.rs +++ b/android-activity/src/native_activity/mod.rs @@ -353,6 +353,10 @@ impl AndroidAppInner { } } + pub fn set_soft_input(&self, _show: bool) { + // Unsupported + } + pub fn enable_motion_axis(&self, _axis: input::Axis) { // NOP - The InputQueue API doesn't let us optimize which axis values are read } From f3d0e3f4dcb4662b36b896b65a054c4ac7c5f1f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 27 Aug 2022 13:15:44 +0200 Subject: [PATCH 2/2] Pull text from game text input --- .../native_app_glue/android_native_app_glue.c | 1 + android-activity/src/game_activity/input.rs | 6 +++ android-activity/src/game_activity/mod.rs | 39 ++++++++++++++++++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/android-activity/game-activity-csrc/game-activity/native_app_glue/android_native_app_glue.c b/android-activity/game-activity-csrc/game-activity/native_app_glue/android_native_app_glue.c index 5fd3eb8..3640d7c 100644 --- a/android-activity/game-activity-csrc/game-activity/native_app_glue/android_native_app_glue.c +++ b/android-activity/game-activity-csrc/game-activity/native_app_glue/android_native_app_glue.c @@ -601,6 +601,7 @@ static void onTextInputEvent(GameActivity* activity, pthread_mutex_lock(&android_app->mutex); android_app->textInputState = 1; + notifyInput(android_app); pthread_mutex_unlock(&android_app->mutex); } diff --git a/android-activity/src/game_activity/input.rs b/android-activity/src/game_activity/input.rs index d75bc96..b0fb2b7 100644 --- a/android-activity/src/game_activity/input.rs +++ b/android-activity/src/game_activity/input.rs @@ -26,6 +26,12 @@ use bitflags::bitflags; pub enum InputEvent { MotionEvent(MotionEvent), KeyEvent(KeyEvent), + CharacterEvent(CharacterEvent), +} + +#[derive(Debug, Clone)] +pub struct CharacterEvent { + pub character: char, } /// An enum representing the source of an [`MotionEvent`] or [`KeyEvent`] diff --git a/android-activity/src/game_activity/mod.rs b/android-activity/src/game_activity/mod.rs index 312ee99..da8428f 100644 --- a/android-activity/src/game_activity/mod.rs +++ b/android-activity/src/game_activity/mod.rs @@ -5,12 +5,12 @@ use std::fs::File; use std::io::{BufRead, BufReader}; use std::marker::PhantomData; use std::ops::Deref; -use std::os::raw; +use std::os::raw::{self, c_void}; use std::os::unix::prelude::*; use std::ptr::NonNull; use std::sync::{Arc, RwLock}; use std::time::Duration; -use std::{ptr, thread}; +use std::{ptr, slice, thread}; use log::{error, trace, Level}; @@ -23,6 +23,8 @@ use ndk::asset::AssetManager; use ndk::configuration::Configuration; use ndk::native_window::NativeWindow; +use crate::game_activity::ffi::{GameTextInputSpan, GameTextInputState}; +use crate::input::CharacterEvent; use crate::{util, AndroidApp, ConfigurationRef, MainEvent, PollEvent, Rect}; mod ffi; @@ -367,6 +369,39 @@ impl AndroidAppInner { where F: FnMut(&InputEvent), { + let mut chars = String::new(); + unsafe { + let activity = (*self.native_app.as_ptr()).activity; + + unsafe extern "C" fn callback(context: *mut c_void, state: *const GameTextInputState) { + *(context as *mut String) = std::str::from_utf8_unchecked(slice::from_raw_parts( + (*state).text_UTF8, + (*state).text_length as usize, + )) + .to_owned(); + } + ffi::GameActivity_getTextInputState( + activity, + Some(callback), + &mut chars as *mut String as *mut c_void, + ); + if !chars.is_empty() { + ffi::GameActivity_setTextInputState( + activity, + &GameTextInputState { + text_UTF8: ptr::null(), + text_length: 0, + selection: GameTextInputSpan { start: 0, end: 0 }, + composingRegion: GameTextInputSpan { start: 0, end: 0 }, + } as *const _, + ); + } + } + + for character in chars.chars() { + callback(&InputEvent::CharacterEvent(CharacterEvent { character })); + } + let buf = unsafe { let app_ptr = self.native_app.as_ptr(); let input_buffer = ffi::android_app_swap_input_buffers(app_ptr);