mirror of
https://github.com/rust-mobile/android-activity.git
synced 2026-07-05 06:17:27 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ea5932b272 | |||
| 618c8d6de5 | |||
| 23c9933354 | |||
| 8912aaba71 |
@@ -6,19 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
- input: Replaced custom types with their `ndk` crate equivalent.
|
||||
> [!NOTE]
|
||||
> These types existed because the `ndk` crate didn't provide them in an extensible way. Now that they have the `#[non_exhaustive]` flag and contain a `__Unknown(T)` variant to provide lossless conversions, and not to mention use an ABI type that matches how it is being used by most functions (when the original constants were defined in a "typeless" way), the `ndk` types are used and reexported once again.
|
||||
### Added
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Relevant breaking changes**:
|
||||
> - `repr()` types for some `enum`s have changed to match the ABI type that is used by most functions that are returning or consuming this wrapper type.
|
||||
> - `Source::is_xxx_class()` functions are replaced by querying `Source::class()` and comparing against variants from the returned `SourceClass` `bitflags` enum.
|
||||
> - `SourceFlags::TRACKBALL` (from `Source::is_trackball_class()`) is named `SourceClass::NAVIGATION` in the `ndk`.
|
||||
|
||||
- rust-version bumped to 1.73.0 ([#193](https://github.com/rust-mobile/android-activity/pull/193))
|
||||
- The `ndk` and `ndk-sys` crates are now re-exported under `android_activity::ndk` and `android_activity::ndk_sys` ([#194](https://github.com/rust-mobile/android-activity/pull/194))
|
||||
- input: TextInputAction enum representing action button types on soft keyboards.
|
||||
- input: InputEvent::TextAction event for handling action button presses from soft keyboards.
|
||||
|
||||
### Changed
|
||||
- rust-version bumped to 1.73.0 ([#193](https://github.com/rust-mobile/android-activity/pull/193))
|
||||
- GameActivity updated to 4.0.0 (requires the corresponding 4.0.0 `.aar` release from Google) ([#191](https://github.com/rust-mobile/android-activity/pull/191))
|
||||
|
||||
## [0.6.0] - 2024-04-26
|
||||
|
||||
@@ -32,7 +32,6 @@ default = []
|
||||
game-activity = []
|
||||
native-activity = []
|
||||
api-level-30 = ["ndk/api-level-30"]
|
||||
api-level-33 = ["api-level-30", "ndk/api-level-33"]
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
|
||||
+4
@@ -226,6 +226,10 @@ struct android_app {
|
||||
* thread, so we can't say that this is only valid within the `APP_CMD_` handler.
|
||||
*/
|
||||
int editorAction;
|
||||
/**
|
||||
* true when editorAction has been set
|
||||
*/
|
||||
bool pendingEditorAction;
|
||||
|
||||
/**
|
||||
* Current state of the app's activity. May be either APP_CMD_START,
|
||||
|
||||
+8
-2
@@ -726,9 +726,15 @@ static bool onEditorAction(GameActivity* activity, int action) {
|
||||
// XXX: this is a racy design that could lose InputConnection actions if the
|
||||
// application doesn't manage to look at app->editorAction before another
|
||||
// action is delivered.
|
||||
if (android_app->pendingEditorAction) {
|
||||
LOGW("Dropping editor action %d because previous action %d not yet "
|
||||
"handled",
|
||||
action, android_app->editorAction);
|
||||
}
|
||||
android_app->editorAction = action;
|
||||
// TODO: buffer these actions like other input events
|
||||
//notifyInput(android_app);
|
||||
android_app->pendingEditorAction = true;
|
||||
notifyInput(android_app);
|
||||
// TODO: buffer IME text events and editor actions like other input events
|
||||
|
||||
//android_app_write_cmd(android_app, APP_CMD_EDITOR_ACTION);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
|
||||
@@ -6259,6 +6259,8 @@ pub struct android_app {
|
||||
pub softwareKeyboardVisible: bool,
|
||||
#[doc = " Last editor action. Valid within APP_CMD_SOFTWARE_KB_VIS_CHANGED handler.\n\n Note: the upstream comment above isn't accurate.\n - `APP_CMD_SOFTWARE_KB_VIS_CHANGED` is associated with `softwareKeyboardVisible`\n changes, not `editorAction`.\n - `APP_CMD_EDITOR_ACTION` is associated with this state but unlike for\n `window` state there's no synchonization that blocks the Java main\n thread, so we can't say that this is only valid within the `APP_CMD_` handler."]
|
||||
pub editorAction: ::std::os::raw::c_int,
|
||||
#[doc = " true when editorAction has been set"]
|
||||
pub pendingEditorAction: bool,
|
||||
#[doc = " Current state of the app's activity. May be either APP_CMD_START,\n APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP."]
|
||||
pub activityState: ::std::os::raw::c_int,
|
||||
#[doc = " This is non-zero when the application's GameActivity is being\n destroyed and waiting for the app thread to complete."]
|
||||
@@ -6292,7 +6294,7 @@ fn bindgen_test_layout_android_app() {
|
||||
let ptr = UNINIT.as_ptr();
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<android_app>(),
|
||||
392usize,
|
||||
400usize,
|
||||
"Size of android_app"
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -6356,108 +6358,113 @@ fn bindgen_test_layout_android_app() {
|
||||
"Offset of field: android_app::editorAction"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).activityState) as usize - ptr as usize },
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).pendingEditorAction) as usize - ptr as usize },
|
||||
88usize,
|
||||
"Offset of field: android_app::pendingEditorAction"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).activityState) as usize - ptr as usize },
|
||||
92usize,
|
||||
"Offset of field: android_app::activityState"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).destroyRequested) as usize - ptr as usize },
|
||||
92usize,
|
||||
96usize,
|
||||
"Offset of field: android_app::destroyRequested"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).inputBuffers) as usize - ptr as usize },
|
||||
96usize,
|
||||
104usize,
|
||||
"Offset of field: android_app::inputBuffers"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).currentInputBuffer) as usize - ptr as usize },
|
||||
192usize,
|
||||
200usize,
|
||||
"Offset of field: android_app::currentInputBuffer"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).textInputState) as usize - ptr as usize },
|
||||
196usize,
|
||||
204usize,
|
||||
"Offset of field: android_app::textInputState"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).mutex) as usize - ptr as usize },
|
||||
200usize,
|
||||
208usize,
|
||||
"Offset of field: android_app::mutex"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).cond) as usize - ptr as usize },
|
||||
240usize,
|
||||
248usize,
|
||||
"Offset of field: android_app::cond"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).msgread) as usize - ptr as usize },
|
||||
288usize,
|
||||
296usize,
|
||||
"Offset of field: android_app::msgread"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).msgwrite) as usize - ptr as usize },
|
||||
292usize,
|
||||
300usize,
|
||||
"Offset of field: android_app::msgwrite"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).thread) as usize - ptr as usize },
|
||||
296usize,
|
||||
304usize,
|
||||
"Offset of field: android_app::thread"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).cmdPollSource) as usize - ptr as usize },
|
||||
304usize,
|
||||
312usize,
|
||||
"Offset of field: android_app::cmdPollSource"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).running) as usize - ptr as usize },
|
||||
328usize,
|
||||
336usize,
|
||||
"Offset of field: android_app::running"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).stateSaved) as usize - ptr as usize },
|
||||
332usize,
|
||||
340usize,
|
||||
"Offset of field: android_app::stateSaved"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).destroyed) as usize - ptr as usize },
|
||||
336usize,
|
||||
344usize,
|
||||
"Offset of field: android_app::destroyed"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).redrawNeeded) as usize - ptr as usize },
|
||||
340usize,
|
||||
348usize,
|
||||
"Offset of field: android_app::redrawNeeded"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).pendingWindow) as usize - ptr as usize },
|
||||
344usize,
|
||||
352usize,
|
||||
"Offset of field: android_app::pendingWindow"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).pendingContentRect) as usize - ptr as usize },
|
||||
352usize,
|
||||
360usize,
|
||||
"Offset of field: android_app::pendingContentRect"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).keyEventFilter) as usize - ptr as usize },
|
||||
368usize,
|
||||
376usize,
|
||||
"Offset of field: android_app::keyEventFilter"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).motionEventFilter) as usize - ptr as usize },
|
||||
376usize,
|
||||
384usize,
|
||||
"Offset of field: android_app::motionEventFilter"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).inputAvailableWakeUp) as usize - ptr as usize },
|
||||
384usize,
|
||||
392usize,
|
||||
"Offset of field: android_app::inputAvailableWakeUp"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).inputSwapPending) as usize - ptr as usize },
|
||||
385usize,
|
||||
393usize,
|
||||
"Offset of field: android_app::inputSwapPending"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6724,6 +6724,8 @@ pub struct android_app {
|
||||
pub softwareKeyboardVisible: bool,
|
||||
#[doc = " Last editor action. Valid within APP_CMD_SOFTWARE_KB_VIS_CHANGED handler.\n\n Note: the upstream comment above isn't accurate.\n - `APP_CMD_SOFTWARE_KB_VIS_CHANGED` is associated with `softwareKeyboardVisible`\n changes, not `editorAction`.\n - `APP_CMD_EDITOR_ACTION` is associated with this state but unlike for\n `window` state there's no synchonization that blocks the Java main\n thread, so we can't say that this is only valid within the `APP_CMD_` handler."]
|
||||
pub editorAction: ::std::os::raw::c_int,
|
||||
#[doc = " true when editorAction has been set"]
|
||||
pub pendingEditorAction: bool,
|
||||
#[doc = " Current state of the app's activity. May be either APP_CMD_START,\n APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP."]
|
||||
pub activityState: ::std::os::raw::c_int,
|
||||
#[doc = " This is non-zero when the application's GameActivity is being\n destroyed and waiting for the app thread to complete."]
|
||||
@@ -6757,7 +6759,7 @@ fn bindgen_test_layout_android_app() {
|
||||
let ptr = UNINIT.as_ptr();
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<android_app>(),
|
||||
248usize,
|
||||
256usize,
|
||||
"Size of android_app"
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -6821,108 +6823,113 @@ fn bindgen_test_layout_android_app() {
|
||||
"Offset of field: android_app::editorAction"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).activityState) as usize - ptr as usize },
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).pendingEditorAction) as usize - ptr as usize },
|
||||
56usize,
|
||||
"Offset of field: android_app::pendingEditorAction"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).activityState) as usize - ptr as usize },
|
||||
60usize,
|
||||
"Offset of field: android_app::activityState"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).destroyRequested) as usize - ptr as usize },
|
||||
60usize,
|
||||
64usize,
|
||||
"Offset of field: android_app::destroyRequested"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).inputBuffers) as usize - ptr as usize },
|
||||
64usize,
|
||||
72usize,
|
||||
"Offset of field: android_app::inputBuffers"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).currentInputBuffer) as usize - ptr as usize },
|
||||
160usize,
|
||||
168usize,
|
||||
"Offset of field: android_app::currentInputBuffer"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).textInputState) as usize - ptr as usize },
|
||||
164usize,
|
||||
172usize,
|
||||
"Offset of field: android_app::textInputState"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).mutex) as usize - ptr as usize },
|
||||
168usize,
|
||||
176usize,
|
||||
"Offset of field: android_app::mutex"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).cond) as usize - ptr as usize },
|
||||
172usize,
|
||||
180usize,
|
||||
"Offset of field: android_app::cond"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).msgread) as usize - ptr as usize },
|
||||
176usize,
|
||||
184usize,
|
||||
"Offset of field: android_app::msgread"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).msgwrite) as usize - ptr as usize },
|
||||
180usize,
|
||||
188usize,
|
||||
"Offset of field: android_app::msgwrite"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).thread) as usize - ptr as usize },
|
||||
184usize,
|
||||
192usize,
|
||||
"Offset of field: android_app::thread"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).cmdPollSource) as usize - ptr as usize },
|
||||
188usize,
|
||||
196usize,
|
||||
"Offset of field: android_app::cmdPollSource"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).running) as usize - ptr as usize },
|
||||
200usize,
|
||||
208usize,
|
||||
"Offset of field: android_app::running"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).stateSaved) as usize - ptr as usize },
|
||||
204usize,
|
||||
212usize,
|
||||
"Offset of field: android_app::stateSaved"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).destroyed) as usize - ptr as usize },
|
||||
208usize,
|
||||
216usize,
|
||||
"Offset of field: android_app::destroyed"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).redrawNeeded) as usize - ptr as usize },
|
||||
212usize,
|
||||
220usize,
|
||||
"Offset of field: android_app::redrawNeeded"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).pendingWindow) as usize - ptr as usize },
|
||||
216usize,
|
||||
224usize,
|
||||
"Offset of field: android_app::pendingWindow"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).pendingContentRect) as usize - ptr as usize },
|
||||
220usize,
|
||||
228usize,
|
||||
"Offset of field: android_app::pendingContentRect"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).keyEventFilter) as usize - ptr as usize },
|
||||
236usize,
|
||||
244usize,
|
||||
"Offset of field: android_app::keyEventFilter"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).motionEventFilter) as usize - ptr as usize },
|
||||
240usize,
|
||||
248usize,
|
||||
"Offset of field: android_app::motionEventFilter"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).inputAvailableWakeUp) as usize - ptr as usize },
|
||||
244usize,
|
||||
252usize,
|
||||
"Offset of field: android_app::inputAvailableWakeUp"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).inputSwapPending) as usize - ptr as usize },
|
||||
245usize,
|
||||
253usize,
|
||||
"Offset of field: android_app::inputSwapPending"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7442,6 +7442,8 @@ pub struct android_app {
|
||||
pub softwareKeyboardVisible: bool,
|
||||
#[doc = " Last editor action. Valid within APP_CMD_SOFTWARE_KB_VIS_CHANGED handler.\n\n Note: the upstream comment above isn't accurate.\n - `APP_CMD_SOFTWARE_KB_VIS_CHANGED` is associated with `softwareKeyboardVisible`\n changes, not `editorAction`.\n - `APP_CMD_EDITOR_ACTION` is associated with this state but unlike for\n `window` state there's no synchonization that blocks the Java main\n thread, so we can't say that this is only valid within the `APP_CMD_` handler."]
|
||||
pub editorAction: ::std::os::raw::c_int,
|
||||
#[doc = " true when editorAction has been set"]
|
||||
pub pendingEditorAction: bool,
|
||||
#[doc = " Current state of the app's activity. May be either APP_CMD_START,\n APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP."]
|
||||
pub activityState: ::std::os::raw::c_int,
|
||||
#[doc = " This is non-zero when the application's GameActivity is being\n destroyed and waiting for the app thread to complete."]
|
||||
@@ -7475,7 +7477,7 @@ fn bindgen_test_layout_android_app() {
|
||||
let ptr = UNINIT.as_ptr();
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<android_app>(),
|
||||
232usize,
|
||||
236usize,
|
||||
"Size of android_app"
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -7539,108 +7541,113 @@ fn bindgen_test_layout_android_app() {
|
||||
"Offset of field: android_app::editorAction"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).activityState) as usize - ptr as usize },
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).pendingEditorAction) as usize - ptr as usize },
|
||||
56usize,
|
||||
"Offset of field: android_app::pendingEditorAction"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).activityState) as usize - ptr as usize },
|
||||
60usize,
|
||||
"Offset of field: android_app::activityState"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).destroyRequested) as usize - ptr as usize },
|
||||
60usize,
|
||||
64usize,
|
||||
"Offset of field: android_app::destroyRequested"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).inputBuffers) as usize - ptr as usize },
|
||||
64usize,
|
||||
68usize,
|
||||
"Offset of field: android_app::inputBuffers"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).currentInputBuffer) as usize - ptr as usize },
|
||||
144usize,
|
||||
148usize,
|
||||
"Offset of field: android_app::currentInputBuffer"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).textInputState) as usize - ptr as usize },
|
||||
148usize,
|
||||
152usize,
|
||||
"Offset of field: android_app::textInputState"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).mutex) as usize - ptr as usize },
|
||||
152usize,
|
||||
156usize,
|
||||
"Offset of field: android_app::mutex"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).cond) as usize - ptr as usize },
|
||||
156usize,
|
||||
160usize,
|
||||
"Offset of field: android_app::cond"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).msgread) as usize - ptr as usize },
|
||||
160usize,
|
||||
164usize,
|
||||
"Offset of field: android_app::msgread"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).msgwrite) as usize - ptr as usize },
|
||||
164usize,
|
||||
168usize,
|
||||
"Offset of field: android_app::msgwrite"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).thread) as usize - ptr as usize },
|
||||
168usize,
|
||||
172usize,
|
||||
"Offset of field: android_app::thread"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).cmdPollSource) as usize - ptr as usize },
|
||||
172usize,
|
||||
176usize,
|
||||
"Offset of field: android_app::cmdPollSource"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).running) as usize - ptr as usize },
|
||||
184usize,
|
||||
188usize,
|
||||
"Offset of field: android_app::running"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).stateSaved) as usize - ptr as usize },
|
||||
188usize,
|
||||
192usize,
|
||||
"Offset of field: android_app::stateSaved"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).destroyed) as usize - ptr as usize },
|
||||
192usize,
|
||||
196usize,
|
||||
"Offset of field: android_app::destroyed"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).redrawNeeded) as usize - ptr as usize },
|
||||
196usize,
|
||||
200usize,
|
||||
"Offset of field: android_app::redrawNeeded"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).pendingWindow) as usize - ptr as usize },
|
||||
200usize,
|
||||
204usize,
|
||||
"Offset of field: android_app::pendingWindow"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).pendingContentRect) as usize - ptr as usize },
|
||||
204usize,
|
||||
208usize,
|
||||
"Offset of field: android_app::pendingContentRect"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).keyEventFilter) as usize - ptr as usize },
|
||||
220usize,
|
||||
224usize,
|
||||
"Offset of field: android_app::keyEventFilter"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).motionEventFilter) as usize - ptr as usize },
|
||||
224usize,
|
||||
228usize,
|
||||
"Offset of field: android_app::motionEventFilter"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).inputAvailableWakeUp) as usize - ptr as usize },
|
||||
228usize,
|
||||
232usize,
|
||||
"Offset of field: android_app::inputAvailableWakeUp"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).inputSwapPending) as usize - ptr as usize },
|
||||
229usize,
|
||||
233usize,
|
||||
"Offset of field: android_app::inputSwapPending"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7466,6 +7466,8 @@ pub struct android_app {
|
||||
pub softwareKeyboardVisible: bool,
|
||||
#[doc = " Last editor action. Valid within APP_CMD_SOFTWARE_KB_VIS_CHANGED handler.\n\n Note: the upstream comment above isn't accurate.\n - `APP_CMD_SOFTWARE_KB_VIS_CHANGED` is associated with `softwareKeyboardVisible`\n changes, not `editorAction`.\n - `APP_CMD_EDITOR_ACTION` is associated with this state but unlike for\n `window` state there's no synchonization that blocks the Java main\n thread, so we can't say that this is only valid within the `APP_CMD_` handler."]
|
||||
pub editorAction: ::std::os::raw::c_int,
|
||||
#[doc = " true when editorAction has been set"]
|
||||
pub pendingEditorAction: bool,
|
||||
#[doc = " Current state of the app's activity. May be either APP_CMD_START,\n APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP."]
|
||||
pub activityState: ::std::os::raw::c_int,
|
||||
#[doc = " This is non-zero when the application's GameActivity is being\n destroyed and waiting for the app thread to complete."]
|
||||
@@ -7499,7 +7501,7 @@ fn bindgen_test_layout_android_app() {
|
||||
let ptr = UNINIT.as_ptr();
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<android_app>(),
|
||||
392usize,
|
||||
400usize,
|
||||
"Size of android_app"
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -7563,108 +7565,113 @@ fn bindgen_test_layout_android_app() {
|
||||
"Offset of field: android_app::editorAction"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).activityState) as usize - ptr as usize },
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).pendingEditorAction) as usize - ptr as usize },
|
||||
88usize,
|
||||
"Offset of field: android_app::pendingEditorAction"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).activityState) as usize - ptr as usize },
|
||||
92usize,
|
||||
"Offset of field: android_app::activityState"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).destroyRequested) as usize - ptr as usize },
|
||||
92usize,
|
||||
96usize,
|
||||
"Offset of field: android_app::destroyRequested"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).inputBuffers) as usize - ptr as usize },
|
||||
96usize,
|
||||
104usize,
|
||||
"Offset of field: android_app::inputBuffers"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).currentInputBuffer) as usize - ptr as usize },
|
||||
192usize,
|
||||
200usize,
|
||||
"Offset of field: android_app::currentInputBuffer"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).textInputState) as usize - ptr as usize },
|
||||
196usize,
|
||||
204usize,
|
||||
"Offset of field: android_app::textInputState"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).mutex) as usize - ptr as usize },
|
||||
200usize,
|
||||
208usize,
|
||||
"Offset of field: android_app::mutex"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).cond) as usize - ptr as usize },
|
||||
240usize,
|
||||
248usize,
|
||||
"Offset of field: android_app::cond"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).msgread) as usize - ptr as usize },
|
||||
288usize,
|
||||
296usize,
|
||||
"Offset of field: android_app::msgread"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).msgwrite) as usize - ptr as usize },
|
||||
292usize,
|
||||
300usize,
|
||||
"Offset of field: android_app::msgwrite"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).thread) as usize - ptr as usize },
|
||||
296usize,
|
||||
304usize,
|
||||
"Offset of field: android_app::thread"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).cmdPollSource) as usize - ptr as usize },
|
||||
304usize,
|
||||
312usize,
|
||||
"Offset of field: android_app::cmdPollSource"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).running) as usize - ptr as usize },
|
||||
328usize,
|
||||
336usize,
|
||||
"Offset of field: android_app::running"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).stateSaved) as usize - ptr as usize },
|
||||
332usize,
|
||||
340usize,
|
||||
"Offset of field: android_app::stateSaved"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).destroyed) as usize - ptr as usize },
|
||||
336usize,
|
||||
344usize,
|
||||
"Offset of field: android_app::destroyed"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).redrawNeeded) as usize - ptr as usize },
|
||||
340usize,
|
||||
348usize,
|
||||
"Offset of field: android_app::redrawNeeded"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).pendingWindow) as usize - ptr as usize },
|
||||
344usize,
|
||||
352usize,
|
||||
"Offset of field: android_app::pendingWindow"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).pendingContentRect) as usize - ptr as usize },
|
||||
352usize,
|
||||
360usize,
|
||||
"Offset of field: android_app::pendingContentRect"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).keyEventFilter) as usize - ptr as usize },
|
||||
368usize,
|
||||
376usize,
|
||||
"Offset of field: android_app::keyEventFilter"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).motionEventFilter) as usize - ptr as usize },
|
||||
376usize,
|
||||
384usize,
|
||||
"Offset of field: android_app::motionEventFilter"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).inputAvailableWakeUp) as usize - ptr as usize },
|
||||
384usize,
|
||||
392usize,
|
||||
"Offset of field: android_app::inputAvailableWakeUp"
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { ::std::ptr::addr_of!((*ptr).inputSwapPending) as usize - ptr as usize },
|
||||
385usize,
|
||||
393usize,
|
||||
"Offset of field: android_app::inputSwapPending"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,12 +13,10 @@
|
||||
// The `Class` was also bound differently to `android-ndk-rs` considering how the class is defined
|
||||
// by masking bits from the `Source`.
|
||||
|
||||
use ndk::event::ButtonState;
|
||||
|
||||
use crate::activity_impl::ffi::{GameActivityKeyEvent, GameActivityMotionEvent};
|
||||
use crate::input::{
|
||||
Axis, Button, EdgeFlags, KeyAction, KeyEventFlags, Keycode, MetaState, MotionAction,
|
||||
MotionEventFlags, Pointer, PointersIter, Source, ToolType,
|
||||
Axis, Button, ButtonState, EdgeFlags, KeyAction, KeyEventFlags, Keycode, MetaState,
|
||||
MotionAction, MotionEventFlags, Pointer, PointersIter, Source, ToolType,
|
||||
};
|
||||
|
||||
// Note: try to keep this wrapper API compatible with the AInputEvent API if possible
|
||||
@@ -29,6 +27,7 @@ pub enum InputEvent<'a> {
|
||||
MotionEvent(MotionEvent<'a>),
|
||||
KeyEvent(KeyEvent<'a>),
|
||||
TextEvent(crate::input::TextInputState),
|
||||
TextAction(crate::input::TextInputAction),
|
||||
}
|
||||
|
||||
/// A motion event.
|
||||
@@ -49,7 +48,7 @@ impl<'a> MotionEvent<'a> {
|
||||
///
|
||||
#[inline]
|
||||
pub fn source(&self) -> Source {
|
||||
let source = self.ga_event.source;
|
||||
let source = self.ga_event.source as u32;
|
||||
source.into()
|
||||
}
|
||||
|
||||
@@ -65,7 +64,7 @@ impl<'a> MotionEvent<'a> {
|
||||
/// See [the MotionEvent docs](https://developer.android.com/reference/android/view/MotionEvent#getActionMasked())
|
||||
#[inline]
|
||||
pub fn action(&self) -> MotionAction {
|
||||
let action = self.ga_event.action & ndk_sys::AMOTION_EVENT_ACTION_MASK as i32;
|
||||
let action = self.ga_event.action as u32 & ndk_sys::AMOTION_EVENT_ACTION_MASK;
|
||||
action.into()
|
||||
}
|
||||
|
||||
@@ -178,7 +177,6 @@ impl<'a> MotionEvent<'a> {
|
||||
/// See [the NDK
|
||||
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getbuttonstate)
|
||||
#[inline]
|
||||
// TODO: Button enum to signify only one bitflag can be set?
|
||||
pub fn button_state(&self) -> ButtonState {
|
||||
ButtonState(self.ga_event.buttonState as u32)
|
||||
}
|
||||
@@ -281,7 +279,7 @@ impl PointerImpl<'_> {
|
||||
#[inline]
|
||||
pub fn axis_value(&self, axis: Axis) -> f32 {
|
||||
let pointer = &self.event.ga_event.pointers[self.index];
|
||||
let axis: i32 = axis.into();
|
||||
let axis: u32 = axis.into();
|
||||
pointer.axisValues[axis as usize]
|
||||
}
|
||||
|
||||
@@ -300,7 +298,8 @@ impl PointerImpl<'_> {
|
||||
#[inline]
|
||||
pub fn tool_type(&self) -> ToolType {
|
||||
let pointer = &self.event.ga_event.pointers[self.index];
|
||||
pointer.toolType.into()
|
||||
let tool_type = pointer.toolType as u32;
|
||||
tool_type.into()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -667,7 +666,7 @@ impl<'a> KeyEvent<'a> {
|
||||
///
|
||||
#[inline]
|
||||
pub fn source(&self) -> Source {
|
||||
let source = self.ga_event.source;
|
||||
let source = self.ga_event.source as u32;
|
||||
source.into()
|
||||
}
|
||||
|
||||
@@ -683,13 +682,13 @@ impl<'a> KeyEvent<'a> {
|
||||
/// See [the KeyEvent docs](https://developer.android.com/reference/android/view/KeyEvent#getAction())
|
||||
#[inline]
|
||||
pub fn action(&self) -> KeyAction {
|
||||
let action = self.ga_event.action;
|
||||
let action = self.ga_event.action as u32;
|
||||
action.into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn action_button(&self) -> KeyAction {
|
||||
let action = self.ga_event.action;
|
||||
let action = self.ga_event.action as u32;
|
||||
action.into()
|
||||
}
|
||||
|
||||
@@ -719,7 +718,7 @@ impl<'a> KeyEvent<'a> {
|
||||
/// docs](https://developer.android.com/ndk/reference/group/input#akeyevent_getkeycode)
|
||||
#[inline]
|
||||
pub fn key_code(&self) -> Keycode {
|
||||
let keycode = self.ga_event.keyCode;
|
||||
let keycode = self.ga_event.keyCode as u32;
|
||||
keycode.into()
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ use ndk::configuration::Configuration;
|
||||
use ndk::native_window::NativeWindow;
|
||||
|
||||
use crate::error::InternalResult;
|
||||
use crate::input::{Axis, KeyCharacterMap, KeyCharacterMapBinding};
|
||||
use crate::input::{Axis, KeyCharacterMap, KeyCharacterMapBinding, TextInputAction};
|
||||
use crate::jni_utils::{self, CloneJavaVM};
|
||||
use crate::util::{abort_on_panic, forward_stdio_to_logcat, log_panic, try_get_path_from_ptr};
|
||||
use crate::{
|
||||
@@ -174,9 +174,6 @@ impl NativeAppGlue {
|
||||
};
|
||||
let out_ptr = &mut out_state as *mut TextInputState;
|
||||
|
||||
let app_ptr = self.as_ptr();
|
||||
(*app_ptr).textInputState = 0;
|
||||
|
||||
// NEON WARNING:
|
||||
//
|
||||
// It's not clearly documented but the GameActivity API over the
|
||||
@@ -204,6 +201,14 @@ impl NativeAppGlue {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn take_text_input_state(&self) -> TextInputState {
|
||||
unsafe {
|
||||
let app_ptr = self.as_ptr();
|
||||
(*app_ptr).textInputState = 0;
|
||||
}
|
||||
self.text_input_state()
|
||||
}
|
||||
|
||||
// TODO: move into a trait
|
||||
pub fn set_text_input_state(&self, state: TextInputState) {
|
||||
unsafe {
|
||||
@@ -247,6 +252,18 @@ impl NativeAppGlue {
|
||||
ffi::GameActivity_setTextInputState(activity, &ffi_state as *const _);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn take_pending_editor_action(&self) -> Option<i32> {
|
||||
unsafe {
|
||||
let app_ptr = self.as_ptr();
|
||||
if (*app_ptr).pendingEditorAction {
|
||||
(*app_ptr).pendingEditorAction = false;
|
||||
Some((*app_ptr).editorAction)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -351,46 +368,61 @@ impl AndroidAppInner {
|
||||
let cmd = match cmd_i as ffi::NativeAppGlueAppCmd {
|
||||
//NativeAppGlueAppCmd_UNUSED_APP_CMD_INPUT_CHANGED => AndroidAppMainEvent::InputChanged,
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_INIT_WINDOW => {
|
||||
MainEvent::InitWindow {}
|
||||
Some(MainEvent::InitWindow {})
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_TERM_WINDOW => {
|
||||
MainEvent::TerminateWindow {}
|
||||
Some(MainEvent::TerminateWindow {})
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_WINDOW_RESIZED => {
|
||||
MainEvent::WindowResized {}
|
||||
Some(MainEvent::WindowResized {})
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_WINDOW_REDRAW_NEEDED => {
|
||||
MainEvent::RedrawNeeded {}
|
||||
Some(MainEvent::RedrawNeeded {})
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_CONTENT_RECT_CHANGED => {
|
||||
MainEvent::ContentRectChanged {}
|
||||
Some(MainEvent::ContentRectChanged {})
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_GAINED_FOCUS => {
|
||||
MainEvent::GainedFocus
|
||||
Some(MainEvent::GainedFocus)
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_LOST_FOCUS => {
|
||||
MainEvent::LostFocus
|
||||
Some(MainEvent::LostFocus)
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_CONFIG_CHANGED => {
|
||||
MainEvent::ConfigChanged {}
|
||||
Some(MainEvent::ConfigChanged {})
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_LOW_MEMORY => {
|
||||
MainEvent::LowMemory
|
||||
Some(MainEvent::LowMemory)
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_START => {
|
||||
Some(MainEvent::Start)
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_RESUME => {
|
||||
Some(MainEvent::Resume {
|
||||
loader: StateLoader { app: self },
|
||||
})
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_START => MainEvent::Start,
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_RESUME => MainEvent::Resume {
|
||||
loader: StateLoader { app: self },
|
||||
},
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_SAVE_STATE => {
|
||||
MainEvent::SaveState {
|
||||
Some(MainEvent::SaveState {
|
||||
saver: StateSaver { app: self },
|
||||
}
|
||||
})
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_PAUSE => {
|
||||
Some(MainEvent::Pause)
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_STOP => Some(MainEvent::Stop),
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_DESTROY => {
|
||||
Some(MainEvent::Destroy)
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_PAUSE => MainEvent::Pause,
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_STOP => MainEvent::Stop,
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_DESTROY => MainEvent::Destroy,
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_WINDOW_INSETS_CHANGED => {
|
||||
MainEvent::InsetsChanged {}
|
||||
Some(MainEvent::InsetsChanged {})
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_SOFTWARE_KB_VIS_CHANGED => {
|
||||
// NOOP: we ignore these events because they are driven by a
|
||||
// potentially-unreliable heuristic (based on watching for
|
||||
// inset changes) and we don't currently have a public event
|
||||
// for exposing this state.
|
||||
None
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@@ -399,30 +431,35 @@ impl AndroidAppInner {
|
||||
|
||||
trace!("Calling android_app_pre_exec_cmd({cmd_i})");
|
||||
ffi::android_app_pre_exec_cmd(native_app.as_ptr(), cmd_i);
|
||||
match cmd {
|
||||
MainEvent::ConfigChanged { .. } => {
|
||||
self.config.replace(Configuration::clone_from_ptr(
|
||||
NonNull::new_unchecked((*native_app.as_ptr()).config),
|
||||
));
|
||||
}
|
||||
MainEvent::InitWindow { .. } => {
|
||||
let win_ptr = (*native_app.as_ptr()).window;
|
||||
// It's important that we use ::clone_from_ptr() here
|
||||
// because NativeWindow has a Drop implementation that
|
||||
// will unconditionally _release() the native window
|
||||
*self.native_window.write().unwrap() =
|
||||
Some(NativeWindow::clone_from_ptr(
|
||||
NonNull::new(win_ptr).unwrap(),
|
||||
));
|
||||
}
|
||||
MainEvent::TerminateWindow { .. } => {
|
||||
*self.native_window.write().unwrap() = None;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
trace!("Invoking callback for ID_MAIN command = {:?}", cmd);
|
||||
callback(PollEvent::Main(cmd));
|
||||
if let Some(cmd) = cmd {
|
||||
match cmd {
|
||||
MainEvent::ConfigChanged { .. } => {
|
||||
self.config.replace(Configuration::clone_from_ptr(
|
||||
NonNull::new_unchecked(
|
||||
(*native_app.as_ptr()).config,
|
||||
),
|
||||
));
|
||||
}
|
||||
MainEvent::InitWindow { .. } => {
|
||||
let win_ptr = (*native_app.as_ptr()).window;
|
||||
// It's important that we use ::clone_from_ptr() here
|
||||
// because NativeWindow has a Drop implementation that
|
||||
// will unconditionally _release() the native window
|
||||
*self.native_window.write().unwrap() =
|
||||
Some(NativeWindow::clone_from_ptr(
|
||||
NonNull::new(win_ptr).unwrap(),
|
||||
));
|
||||
}
|
||||
MainEvent::TerminateWindow { .. } => {
|
||||
*self.native_window.write().unwrap() = None;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
trace!("Invoking callback for ID_MAIN command = {:?}", cmd);
|
||||
callback(PollEvent::Main(cmd));
|
||||
}
|
||||
|
||||
trace!("Calling android_app_post_exec_cmd({cmd_i})");
|
||||
ffi::android_app_post_exec_cmd(native_app.as_ptr(), cmd_i);
|
||||
@@ -547,11 +584,13 @@ impl AndroidAppInner {
|
||||
}
|
||||
|
||||
pub fn enable_motion_axis(&mut self, axis: Axis) {
|
||||
unsafe { ffi::GameActivityPointerAxes_enableAxis(axis.into()) }
|
||||
let axis: u32 = axis.into();
|
||||
unsafe { ffi::GameActivityPointerAxes_enableAxis(axis as i32) }
|
||||
}
|
||||
|
||||
pub fn disable_motion_axis(&mut self, axis: Axis) {
|
||||
unsafe { ffi::GameActivityPointerAxes_disableAxis(axis.into()) }
|
||||
let axis: u32 = axis.into();
|
||||
unsafe { ffi::GameActivityPointerAxes_disableAxis(axis as i32) }
|
||||
}
|
||||
|
||||
pub fn create_waker(&self) -> AndroidAppWaker {
|
||||
@@ -782,7 +821,8 @@ impl<'a> From<Arc<InputReceiver>> for InputIteratorInner<'a> {
|
||||
_receiver: receiver,
|
||||
buffered,
|
||||
native_app,
|
||||
text_event_checked: false,
|
||||
ime_text_input_state_checked: false,
|
||||
ime_editor_action_checked: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -799,7 +839,8 @@ pub(crate) struct InputIteratorInner<'a> {
|
||||
|
||||
buffered: Option<BufferedEvents<'a>>,
|
||||
native_app: NativeAppGlue,
|
||||
text_event_checked: bool,
|
||||
ime_text_input_state_checked: bool,
|
||||
ime_editor_action_checked: bool,
|
||||
}
|
||||
|
||||
impl InputIteratorInner<'_> {
|
||||
@@ -819,8 +860,10 @@ impl InputIteratorInner<'_> {
|
||||
self.buffered = None;
|
||||
}
|
||||
|
||||
if !self.text_event_checked {
|
||||
self.text_event_checked = true;
|
||||
// We make sure any input state changes are sent before we check
|
||||
// for editor actions, so actions will apply to the latest state.
|
||||
if !self.ime_text_input_state_checked {
|
||||
self.ime_text_input_state_checked = true;
|
||||
unsafe {
|
||||
let app_ptr = self.native_app.as_ptr();
|
||||
|
||||
@@ -832,12 +875,21 @@ impl InputIteratorInner<'_> {
|
||||
// the compiler isn't reordering code so this gets flagged
|
||||
// before the java main thread really updates the state.
|
||||
if (*app_ptr).textInputState != 0 {
|
||||
let state = self.native_app.text_input_state(); // Will clear .textInputState
|
||||
let state = self.native_app.take_text_input_state(); // Will clear .textInputState
|
||||
let _ = callback(&InputEvent::TextEvent(state));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !self.ime_editor_action_checked {
|
||||
self.ime_editor_action_checked = true;
|
||||
if let Some(action) = self.native_app.take_pending_editor_action() {
|
||||
let _ = callback(&InputEvent::TextAction(TextInputAction::from(action)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
pub use ndk::event::{
|
||||
Axis, EdgeFlags, KeyAction, KeyEventFlags, Keycode, MetaState, MotionAction, MotionEventFlags,
|
||||
Source, SourceClass, ToolType,
|
||||
};
|
||||
use bitflags::bitflags;
|
||||
|
||||
pub use crate::activity_impl::input::*;
|
||||
use crate::InputStatus;
|
||||
@@ -9,6 +6,238 @@ use crate::InputStatus;
|
||||
mod sdk;
|
||||
pub use sdk::*;
|
||||
|
||||
/// An enum representing the source of an [`MotionEvent`] or [`KeyEvent`]
|
||||
///
|
||||
/// See [the InputDevice docs](https://developer.android.com/reference/android/view/InputDevice#SOURCE_ANY)
|
||||
///
|
||||
/// # Android Extensible Enum
|
||||
///
|
||||
/// This is a runtime [extensible enum](`crate#android-extensible-enums`) and
|
||||
/// should be handled similar to a `#[non_exhaustive]` enum to maintain
|
||||
/// forwards compatibility.
|
||||
///
|
||||
/// This implements `Into<u32>` and `From<u32>` for converting to/from Android
|
||||
/// SDK integer values.
|
||||
///
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
|
||||
#[non_exhaustive]
|
||||
#[repr(u32)]
|
||||
pub enum Source {
|
||||
BluetoothStylus = 0x0000c002,
|
||||
Dpad = 0x00000201,
|
||||
/// Either a gamepad or a joystick
|
||||
Gamepad = 0x00000401,
|
||||
Hdmi = 0x02000001,
|
||||
/// Either a gamepad or a joystick
|
||||
Joystick = 0x01000010,
|
||||
/// Pretty much any device with buttons. Query the keyboard type to determine
|
||||
/// if it has alphabetic keys and can be used for text entry.
|
||||
Keyboard = 0x00000101,
|
||||
/// A pointing device, such as a mouse or trackpad
|
||||
Mouse = 0x00002002,
|
||||
/// A pointing device, such as a mouse or trackpad whose relative motions should be treated as navigation events
|
||||
MouseRelative = 0x00020004,
|
||||
/// An input device akin to a scroll wheel
|
||||
RotaryEncoder = 0x00400000,
|
||||
Sensor = 0x04000000,
|
||||
Stylus = 0x00004002,
|
||||
Touchpad = 0x00100008,
|
||||
Touchscreen = 0x00001002,
|
||||
TouchNavigation = 0x00200000,
|
||||
Trackball = 0x00010004,
|
||||
|
||||
// We need to consider that the enum variants may be extended across
|
||||
// different versions of Android (i.e. effectively at runtime) but at the
|
||||
// same time we don't want it to be an API break to extend this enum in
|
||||
// future releases of `android-activity` with new variants from the latest
|
||||
// NDK/SDK.
|
||||
//
|
||||
// We can't just use `#[non_exhaustive]` because that only really helps
|
||||
// when adding new variants in sync with android-activity releases.
|
||||
//
|
||||
// On the other hand we also can't rely on a catch-all `Unknown(u32)` that
|
||||
// only really helps with unknown variants seen at runtime.
|
||||
//
|
||||
// What we aim for instead is to have a hidden catch-all variant that
|
||||
// is considered (practically) unmatchable so code is forced to have
|
||||
// a `unknown => {}` catch-all pattern match that will cover unknown variants
|
||||
// either in the form of Rust variants added in future versions or
|
||||
// in the form of an `__Unknown(u32)` integer that represents an unknown
|
||||
// variant seen at runtime.
|
||||
//
|
||||
// Any `unknown => {}` pattern match can rely on `IntoPrimitive` to convert
|
||||
// the `unknown` variant to the integer that comes from the Android SDK
|
||||
// in case that values needs to be passed on, even without knowing its
|
||||
// semantic meaning at compile time.
|
||||
#[doc(hidden)]
|
||||
#[num_enum(catch_all)]
|
||||
__Unknown(u32),
|
||||
}
|
||||
|
||||
// ndk_sys doesn't currently have the `TRACKBALL` flag so we define our
|
||||
// own internal class constants for now
|
||||
bitflags! {
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
struct SourceFlags: u32 {
|
||||
const CLASS_MASK = 0x000000ff;
|
||||
|
||||
const BUTTON = 0x00000001;
|
||||
const POINTER = 0x00000002;
|
||||
const TRACKBALL = 0x00000004;
|
||||
const POSITION = 0x00000008;
|
||||
const JOYSTICK = 0x00000010;
|
||||
const NONE = 0;
|
||||
}
|
||||
}
|
||||
|
||||
impl Source {
|
||||
#[inline]
|
||||
pub fn is_button_class(self) -> bool {
|
||||
let class = SourceFlags::from_bits_truncate(self.into());
|
||||
class.contains(SourceFlags::BUTTON)
|
||||
}
|
||||
#[inline]
|
||||
pub fn is_pointer_class(self) -> bool {
|
||||
let class = SourceFlags::from_bits_truncate(self.into());
|
||||
class.contains(SourceFlags::POINTER)
|
||||
}
|
||||
#[inline]
|
||||
pub fn is_trackball_class(self) -> bool {
|
||||
let class = SourceFlags::from_bits_truncate(self.into());
|
||||
class.contains(SourceFlags::TRACKBALL)
|
||||
}
|
||||
#[inline]
|
||||
pub fn is_position_class(self) -> bool {
|
||||
let class = SourceFlags::from_bits_truncate(self.into());
|
||||
class.contains(SourceFlags::POSITION)
|
||||
}
|
||||
#[inline]
|
||||
pub fn is_joystick_class(self) -> bool {
|
||||
let class = SourceFlags::from_bits_truncate(self.into());
|
||||
class.contains(SourceFlags::JOYSTICK)
|
||||
}
|
||||
}
|
||||
|
||||
/// A bitfield representing the state of modifier keys during an event.
|
||||
///
|
||||
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-25)
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct MetaState(pub u32);
|
||||
|
||||
impl MetaState {
|
||||
#[inline]
|
||||
pub fn alt_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_ALT_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn alt_left_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_ALT_LEFT_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn alt_right_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_ALT_RIGHT_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn shift_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_SHIFT_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn shift_left_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_SHIFT_LEFT_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn shift_right_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_SHIFT_RIGHT_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn sym_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_SYM_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn function_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_FUNCTION_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn ctrl_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_CTRL_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn ctrl_left_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_CTRL_LEFT_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn ctrl_right_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_CTRL_RIGHT_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn meta_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_META_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn meta_left_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_META_LEFT_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn meta_right_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_META_RIGHT_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn caps_lock_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_CAPS_LOCK_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn num_lock_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_NUM_LOCK_ON != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn scroll_lock_on(self) -> bool {
|
||||
self.0 & ndk_sys::AMETA_SCROLL_LOCK_ON != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ndk::event::MetaState> for MetaState {
|
||||
fn from(value: ndk::event::MetaState) -> Self {
|
||||
Self(value.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// A motion action.
|
||||
///
|
||||
/// See [the NDK
|
||||
/// docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-29)
|
||||
///
|
||||
/// # Android Extensible Enum
|
||||
///
|
||||
/// This is a runtime [extensible enum](`crate#android-extensible-enums`) and
|
||||
/// should be handled similar to a `#[non_exhaustive]` enum to maintain
|
||||
/// forwards compatibility.
|
||||
///
|
||||
/// This implements `Into<u32>` and `From<u32>` for converting to/from Android
|
||||
/// SDK integer values.
|
||||
///
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
|
||||
#[non_exhaustive]
|
||||
#[repr(u32)]
|
||||
pub enum MotionAction {
|
||||
Down = ndk_sys::AMOTION_EVENT_ACTION_DOWN,
|
||||
Up = ndk_sys::AMOTION_EVENT_ACTION_UP,
|
||||
Move = ndk_sys::AMOTION_EVENT_ACTION_MOVE,
|
||||
Cancel = ndk_sys::AMOTION_EVENT_ACTION_CANCEL,
|
||||
Outside = ndk_sys::AMOTION_EVENT_ACTION_OUTSIDE,
|
||||
PointerDown = ndk_sys::AMOTION_EVENT_ACTION_POINTER_DOWN,
|
||||
PointerUp = ndk_sys::AMOTION_EVENT_ACTION_POINTER_UP,
|
||||
HoverMove = ndk_sys::AMOTION_EVENT_ACTION_HOVER_MOVE,
|
||||
Scroll = ndk_sys::AMOTION_EVENT_ACTION_SCROLL,
|
||||
HoverEnter = ndk_sys::AMOTION_EVENT_ACTION_HOVER_ENTER,
|
||||
HoverExit = ndk_sys::AMOTION_EVENT_ACTION_HOVER_EXIT,
|
||||
ButtonPress = ndk_sys::AMOTION_EVENT_ACTION_BUTTON_PRESS,
|
||||
ButtonRelease = ndk_sys::AMOTION_EVENT_ACTION_BUTTON_RELEASE,
|
||||
|
||||
#[doc(hidden)]
|
||||
#[num_enum(catch_all)]
|
||||
__Unknown(u32),
|
||||
}
|
||||
|
||||
/// Identifies buttons that are associated with motion events.
|
||||
///
|
||||
/// See [the NDK
|
||||
@@ -40,6 +269,606 @@ pub enum Button {
|
||||
__Unknown(u32),
|
||||
}
|
||||
|
||||
/// An axis of a motion event.
|
||||
///
|
||||
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-32)
|
||||
///
|
||||
/// # Android Extensible Enum
|
||||
///
|
||||
/// This is a runtime [extensible enum](`crate#android-extensible-enums`) and
|
||||
/// should be handled similar to a `#[non_exhaustive]` enum to maintain
|
||||
/// forwards compatibility.
|
||||
///
|
||||
/// This implements `Into<u32>` and `From<u32>` for converting to/from Android
|
||||
/// SDK integer values.
|
||||
///
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
|
||||
#[non_exhaustive]
|
||||
#[repr(u32)]
|
||||
pub enum Axis {
|
||||
X = ndk_sys::AMOTION_EVENT_AXIS_X,
|
||||
Y = ndk_sys::AMOTION_EVENT_AXIS_Y,
|
||||
Pressure = ndk_sys::AMOTION_EVENT_AXIS_PRESSURE,
|
||||
Size = ndk_sys::AMOTION_EVENT_AXIS_SIZE,
|
||||
TouchMajor = ndk_sys::AMOTION_EVENT_AXIS_TOUCH_MAJOR,
|
||||
TouchMinor = ndk_sys::AMOTION_EVENT_AXIS_TOUCH_MINOR,
|
||||
ToolMajor = ndk_sys::AMOTION_EVENT_AXIS_TOOL_MAJOR,
|
||||
ToolMinor = ndk_sys::AMOTION_EVENT_AXIS_TOOL_MINOR,
|
||||
Orientation = ndk_sys::AMOTION_EVENT_AXIS_ORIENTATION,
|
||||
Vscroll = ndk_sys::AMOTION_EVENT_AXIS_VSCROLL,
|
||||
Hscroll = ndk_sys::AMOTION_EVENT_AXIS_HSCROLL,
|
||||
Z = ndk_sys::AMOTION_EVENT_AXIS_Z,
|
||||
Rx = ndk_sys::AMOTION_EVENT_AXIS_RX,
|
||||
Ry = ndk_sys::AMOTION_EVENT_AXIS_RY,
|
||||
Rz = ndk_sys::AMOTION_EVENT_AXIS_RZ,
|
||||
HatX = ndk_sys::AMOTION_EVENT_AXIS_HAT_X,
|
||||
HatY = ndk_sys::AMOTION_EVENT_AXIS_HAT_Y,
|
||||
Ltrigger = ndk_sys::AMOTION_EVENT_AXIS_LTRIGGER,
|
||||
Rtrigger = ndk_sys::AMOTION_EVENT_AXIS_RTRIGGER,
|
||||
Throttle = ndk_sys::AMOTION_EVENT_AXIS_THROTTLE,
|
||||
Rudder = ndk_sys::AMOTION_EVENT_AXIS_RUDDER,
|
||||
Wheel = ndk_sys::AMOTION_EVENT_AXIS_WHEEL,
|
||||
Gas = ndk_sys::AMOTION_EVENT_AXIS_GAS,
|
||||
Brake = ndk_sys::AMOTION_EVENT_AXIS_BRAKE,
|
||||
Distance = ndk_sys::AMOTION_EVENT_AXIS_DISTANCE,
|
||||
Tilt = ndk_sys::AMOTION_EVENT_AXIS_TILT,
|
||||
Scroll = ndk_sys::AMOTION_EVENT_AXIS_SCROLL,
|
||||
RelativeX = ndk_sys::AMOTION_EVENT_AXIS_RELATIVE_X,
|
||||
RelativeY = ndk_sys::AMOTION_EVENT_AXIS_RELATIVE_Y,
|
||||
Generic1 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_1,
|
||||
Generic2 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_2,
|
||||
Generic3 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_3,
|
||||
Generic4 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_4,
|
||||
Generic5 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_5,
|
||||
Generic6 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_6,
|
||||
Generic7 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_7,
|
||||
Generic8 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_8,
|
||||
Generic9 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_9,
|
||||
Generic10 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_10,
|
||||
Generic11 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_11,
|
||||
Generic12 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_12,
|
||||
Generic13 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_13,
|
||||
Generic14 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_14,
|
||||
Generic15 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_15,
|
||||
Generic16 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_16,
|
||||
|
||||
#[doc(hidden)]
|
||||
#[num_enum(catch_all)]
|
||||
__Unknown(u32),
|
||||
}
|
||||
|
||||
/// The tool type of a pointer.
|
||||
///
|
||||
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-48)
|
||||
///
|
||||
/// # Android Extensible Enum
|
||||
///
|
||||
/// This is a runtime [extensible enum](`crate#android-extensible-enums`) and
|
||||
/// should be handled similar to a `#[non_exhaustive]` enum to maintain
|
||||
/// forwards compatibility.
|
||||
///
|
||||
/// Implements `Into<u32>` and `From<u32>` for converting to/from Android SDK
|
||||
/// integer values.
|
||||
///
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
|
||||
#[non_exhaustive]
|
||||
#[repr(u32)]
|
||||
pub enum ToolType {
|
||||
/// Unknown tool type.
|
||||
///
|
||||
/// This constant is used when the tool type is not known or is not relevant, such as for a trackball or other non-pointing device.
|
||||
Unknown = ndk_sys::AMOTION_EVENT_TOOL_TYPE_UNKNOWN,
|
||||
|
||||
/// The tool is a finger.
|
||||
Finger = ndk_sys::AMOTION_EVENT_TOOL_TYPE_FINGER,
|
||||
|
||||
/// The tool is a stylus.
|
||||
Stylus = ndk_sys::AMOTION_EVENT_TOOL_TYPE_STYLUS,
|
||||
|
||||
/// The tool is a mouse.
|
||||
Mouse = ndk_sys::AMOTION_EVENT_TOOL_TYPE_MOUSE,
|
||||
|
||||
/// The tool is an eraser or a stylus being used in an inverted posture.
|
||||
Eraser = ndk_sys::AMOTION_EVENT_TOOL_TYPE_ERASER,
|
||||
|
||||
/// The tool is a palm and should be rejected
|
||||
Palm = ndk_sys::AMOTION_EVENT_TOOL_TYPE_PALM,
|
||||
|
||||
#[doc(hidden)]
|
||||
#[num_enum(catch_all)]
|
||||
__Unknown(u32),
|
||||
}
|
||||
|
||||
/// A bitfield representing the state of buttons during a motion event.
|
||||
///
|
||||
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-33)
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct ButtonState(pub u32);
|
||||
|
||||
impl ButtonState {
|
||||
#[inline]
|
||||
pub fn primary(self) -> bool {
|
||||
self.0 & ndk_sys::AMOTION_EVENT_BUTTON_PRIMARY != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn secondary(self) -> bool {
|
||||
self.0 & ndk_sys::AMOTION_EVENT_BUTTON_SECONDARY != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn teriary(self) -> bool {
|
||||
self.0 & ndk_sys::AMOTION_EVENT_BUTTON_TERTIARY != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn back(self) -> bool {
|
||||
self.0 & ndk_sys::AMOTION_EVENT_BUTTON_BACK != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn forward(self) -> bool {
|
||||
self.0 & ndk_sys::AMOTION_EVENT_BUTTON_FORWARD != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn stylus_primary(self) -> bool {
|
||||
self.0 & ndk_sys::AMOTION_EVENT_BUTTON_STYLUS_PRIMARY != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn stylus_secondary(self) -> bool {
|
||||
self.0 & ndk_sys::AMOTION_EVENT_BUTTON_STYLUS_SECONDARY != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ndk::event::ButtonState> for ButtonState {
|
||||
fn from(value: ndk::event::ButtonState) -> Self {
|
||||
Self(value.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// A bitfield representing which edges were touched by a motion event.
|
||||
///
|
||||
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-31)
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct EdgeFlags(pub u32);
|
||||
|
||||
impl EdgeFlags {
|
||||
#[inline]
|
||||
pub fn top(self) -> bool {
|
||||
self.0 & ndk_sys::AMOTION_EVENT_EDGE_FLAG_TOP != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn bottom(self) -> bool {
|
||||
self.0 & ndk_sys::AMOTION_EVENT_EDGE_FLAG_BOTTOM != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn left(self) -> bool {
|
||||
self.0 & ndk_sys::AMOTION_EVENT_EDGE_FLAG_LEFT != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn right(self) -> bool {
|
||||
self.0 & ndk_sys::AMOTION_EVENT_EDGE_FLAG_RIGHT != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ndk::event::EdgeFlags> for EdgeFlags {
|
||||
fn from(value: ndk::event::EdgeFlags) -> Self {
|
||||
Self(value.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Flags associated with this [`MotionEvent`].
|
||||
///
|
||||
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-30)
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct MotionEventFlags(pub u32);
|
||||
|
||||
impl MotionEventFlags {
|
||||
#[inline]
|
||||
pub fn window_is_obscured(self) -> bool {
|
||||
self.0 & ndk_sys::AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ndk::event::MotionEventFlags> for MotionEventFlags {
|
||||
fn from(value: ndk::event::MotionEventFlags) -> Self {
|
||||
Self(value.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Key actions.
|
||||
///
|
||||
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-27)
|
||||
///
|
||||
/// # Android Extensible Enum
|
||||
///
|
||||
/// This is a runtime [extensible enum](`crate#android-extensible-enums`) and
|
||||
/// should be handled similar to a `#[non_exhaustive]` enum to maintain
|
||||
/// forwards compatibility.
|
||||
///
|
||||
/// Implements `Into<u32>` and `From<u32>` for converting to/from Android SDK
|
||||
/// integer values.
|
||||
///
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
|
||||
#[non_exhaustive]
|
||||
#[repr(u32)]
|
||||
pub enum KeyAction {
|
||||
Down = ndk_sys::AKEY_EVENT_ACTION_DOWN,
|
||||
Up = ndk_sys::AKEY_EVENT_ACTION_UP,
|
||||
Multiple = ndk_sys::AKEY_EVENT_ACTION_MULTIPLE,
|
||||
|
||||
#[doc(hidden)]
|
||||
#[num_enum(catch_all)]
|
||||
__Unknown(u32),
|
||||
}
|
||||
|
||||
/// Key codes.
|
||||
///
|
||||
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-39)
|
||||
///
|
||||
/// # Android Extensible Enum
|
||||
///
|
||||
/// This is a runtime [extensible enum](`crate#android-extensible-enums`) and
|
||||
/// should be handled similar to a `#[non_exhaustive]` enum to maintain
|
||||
/// forwards compatibility.
|
||||
///
|
||||
/// Implements `Into<u32>` and `From<u32>` for converting to/from Android SDK
|
||||
/// integer values.
|
||||
///
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
|
||||
#[non_exhaustive]
|
||||
#[repr(u32)]
|
||||
pub enum Keycode {
|
||||
Unknown = ndk_sys::AKEYCODE_UNKNOWN,
|
||||
SoftLeft = ndk_sys::AKEYCODE_SOFT_LEFT,
|
||||
SoftRight = ndk_sys::AKEYCODE_SOFT_RIGHT,
|
||||
Home = ndk_sys::AKEYCODE_HOME,
|
||||
Back = ndk_sys::AKEYCODE_BACK,
|
||||
Call = ndk_sys::AKEYCODE_CALL,
|
||||
Endcall = ndk_sys::AKEYCODE_ENDCALL,
|
||||
Keycode0 = ndk_sys::AKEYCODE_0,
|
||||
Keycode1 = ndk_sys::AKEYCODE_1,
|
||||
Keycode2 = ndk_sys::AKEYCODE_2,
|
||||
Keycode3 = ndk_sys::AKEYCODE_3,
|
||||
Keycode4 = ndk_sys::AKEYCODE_4,
|
||||
Keycode5 = ndk_sys::AKEYCODE_5,
|
||||
Keycode6 = ndk_sys::AKEYCODE_6,
|
||||
Keycode7 = ndk_sys::AKEYCODE_7,
|
||||
Keycode8 = ndk_sys::AKEYCODE_8,
|
||||
Keycode9 = ndk_sys::AKEYCODE_9,
|
||||
Star = ndk_sys::AKEYCODE_STAR,
|
||||
Pound = ndk_sys::AKEYCODE_POUND,
|
||||
DpadUp = ndk_sys::AKEYCODE_DPAD_UP,
|
||||
DpadDown = ndk_sys::AKEYCODE_DPAD_DOWN,
|
||||
DpadLeft = ndk_sys::AKEYCODE_DPAD_LEFT,
|
||||
DpadRight = ndk_sys::AKEYCODE_DPAD_RIGHT,
|
||||
DpadCenter = ndk_sys::AKEYCODE_DPAD_CENTER,
|
||||
VolumeUp = ndk_sys::AKEYCODE_VOLUME_UP,
|
||||
VolumeDown = ndk_sys::AKEYCODE_VOLUME_DOWN,
|
||||
Power = ndk_sys::AKEYCODE_POWER,
|
||||
Camera = ndk_sys::AKEYCODE_CAMERA,
|
||||
Clear = ndk_sys::AKEYCODE_CLEAR,
|
||||
A = ndk_sys::AKEYCODE_A,
|
||||
B = ndk_sys::AKEYCODE_B,
|
||||
C = ndk_sys::AKEYCODE_C,
|
||||
D = ndk_sys::AKEYCODE_D,
|
||||
E = ndk_sys::AKEYCODE_E,
|
||||
F = ndk_sys::AKEYCODE_F,
|
||||
G = ndk_sys::AKEYCODE_G,
|
||||
H = ndk_sys::AKEYCODE_H,
|
||||
I = ndk_sys::AKEYCODE_I,
|
||||
J = ndk_sys::AKEYCODE_J,
|
||||
K = ndk_sys::AKEYCODE_K,
|
||||
L = ndk_sys::AKEYCODE_L,
|
||||
M = ndk_sys::AKEYCODE_M,
|
||||
N = ndk_sys::AKEYCODE_N,
|
||||
O = ndk_sys::AKEYCODE_O,
|
||||
P = ndk_sys::AKEYCODE_P,
|
||||
Q = ndk_sys::AKEYCODE_Q,
|
||||
R = ndk_sys::AKEYCODE_R,
|
||||
S = ndk_sys::AKEYCODE_S,
|
||||
T = ndk_sys::AKEYCODE_T,
|
||||
U = ndk_sys::AKEYCODE_U,
|
||||
V = ndk_sys::AKEYCODE_V,
|
||||
W = ndk_sys::AKEYCODE_W,
|
||||
X = ndk_sys::AKEYCODE_X,
|
||||
Y = ndk_sys::AKEYCODE_Y,
|
||||
Z = ndk_sys::AKEYCODE_Z,
|
||||
Comma = ndk_sys::AKEYCODE_COMMA,
|
||||
Period = ndk_sys::AKEYCODE_PERIOD,
|
||||
AltLeft = ndk_sys::AKEYCODE_ALT_LEFT,
|
||||
AltRight = ndk_sys::AKEYCODE_ALT_RIGHT,
|
||||
ShiftLeft = ndk_sys::AKEYCODE_SHIFT_LEFT,
|
||||
ShiftRight = ndk_sys::AKEYCODE_SHIFT_RIGHT,
|
||||
Tab = ndk_sys::AKEYCODE_TAB,
|
||||
Space = ndk_sys::AKEYCODE_SPACE,
|
||||
Sym = ndk_sys::AKEYCODE_SYM,
|
||||
Explorer = ndk_sys::AKEYCODE_EXPLORER,
|
||||
Envelope = ndk_sys::AKEYCODE_ENVELOPE,
|
||||
Enter = ndk_sys::AKEYCODE_ENTER,
|
||||
Del = ndk_sys::AKEYCODE_DEL,
|
||||
Grave = ndk_sys::AKEYCODE_GRAVE,
|
||||
Minus = ndk_sys::AKEYCODE_MINUS,
|
||||
Equals = ndk_sys::AKEYCODE_EQUALS,
|
||||
LeftBracket = ndk_sys::AKEYCODE_LEFT_BRACKET,
|
||||
RightBracket = ndk_sys::AKEYCODE_RIGHT_BRACKET,
|
||||
Backslash = ndk_sys::AKEYCODE_BACKSLASH,
|
||||
Semicolon = ndk_sys::AKEYCODE_SEMICOLON,
|
||||
Apostrophe = ndk_sys::AKEYCODE_APOSTROPHE,
|
||||
Slash = ndk_sys::AKEYCODE_SLASH,
|
||||
At = ndk_sys::AKEYCODE_AT,
|
||||
Num = ndk_sys::AKEYCODE_NUM,
|
||||
Headsethook = ndk_sys::AKEYCODE_HEADSETHOOK,
|
||||
Focus = ndk_sys::AKEYCODE_FOCUS,
|
||||
Plus = ndk_sys::AKEYCODE_PLUS,
|
||||
Menu = ndk_sys::AKEYCODE_MENU,
|
||||
Notification = ndk_sys::AKEYCODE_NOTIFICATION,
|
||||
Search = ndk_sys::AKEYCODE_SEARCH,
|
||||
MediaPlayPause = ndk_sys::AKEYCODE_MEDIA_PLAY_PAUSE,
|
||||
MediaStop = ndk_sys::AKEYCODE_MEDIA_STOP,
|
||||
MediaNext = ndk_sys::AKEYCODE_MEDIA_NEXT,
|
||||
MediaPrevious = ndk_sys::AKEYCODE_MEDIA_PREVIOUS,
|
||||
MediaRewind = ndk_sys::AKEYCODE_MEDIA_REWIND,
|
||||
MediaFastForward = ndk_sys::AKEYCODE_MEDIA_FAST_FORWARD,
|
||||
Mute = ndk_sys::AKEYCODE_MUTE,
|
||||
PageUp = ndk_sys::AKEYCODE_PAGE_UP,
|
||||
PageDown = ndk_sys::AKEYCODE_PAGE_DOWN,
|
||||
Pictsymbols = ndk_sys::AKEYCODE_PICTSYMBOLS,
|
||||
SwitchCharset = ndk_sys::AKEYCODE_SWITCH_CHARSET,
|
||||
ButtonA = ndk_sys::AKEYCODE_BUTTON_A,
|
||||
ButtonB = ndk_sys::AKEYCODE_BUTTON_B,
|
||||
ButtonC = ndk_sys::AKEYCODE_BUTTON_C,
|
||||
ButtonX = ndk_sys::AKEYCODE_BUTTON_X,
|
||||
ButtonY = ndk_sys::AKEYCODE_BUTTON_Y,
|
||||
ButtonZ = ndk_sys::AKEYCODE_BUTTON_Z,
|
||||
ButtonL1 = ndk_sys::AKEYCODE_BUTTON_L1,
|
||||
ButtonR1 = ndk_sys::AKEYCODE_BUTTON_R1,
|
||||
ButtonL2 = ndk_sys::AKEYCODE_BUTTON_L2,
|
||||
ButtonR2 = ndk_sys::AKEYCODE_BUTTON_R2,
|
||||
ButtonThumbl = ndk_sys::AKEYCODE_BUTTON_THUMBL,
|
||||
ButtonThumbr = ndk_sys::AKEYCODE_BUTTON_THUMBR,
|
||||
ButtonStart = ndk_sys::AKEYCODE_BUTTON_START,
|
||||
ButtonSelect = ndk_sys::AKEYCODE_BUTTON_SELECT,
|
||||
ButtonMode = ndk_sys::AKEYCODE_BUTTON_MODE,
|
||||
Escape = ndk_sys::AKEYCODE_ESCAPE,
|
||||
ForwardDel = ndk_sys::AKEYCODE_FORWARD_DEL,
|
||||
CtrlLeft = ndk_sys::AKEYCODE_CTRL_LEFT,
|
||||
CtrlRight = ndk_sys::AKEYCODE_CTRL_RIGHT,
|
||||
CapsLock = ndk_sys::AKEYCODE_CAPS_LOCK,
|
||||
ScrollLock = ndk_sys::AKEYCODE_SCROLL_LOCK,
|
||||
MetaLeft = ndk_sys::AKEYCODE_META_LEFT,
|
||||
MetaRight = ndk_sys::AKEYCODE_META_RIGHT,
|
||||
Function = ndk_sys::AKEYCODE_FUNCTION,
|
||||
Sysrq = ndk_sys::AKEYCODE_SYSRQ,
|
||||
Break = ndk_sys::AKEYCODE_BREAK,
|
||||
MoveHome = ndk_sys::AKEYCODE_MOVE_HOME,
|
||||
MoveEnd = ndk_sys::AKEYCODE_MOVE_END,
|
||||
Insert = ndk_sys::AKEYCODE_INSERT,
|
||||
Forward = ndk_sys::AKEYCODE_FORWARD,
|
||||
MediaPlay = ndk_sys::AKEYCODE_MEDIA_PLAY,
|
||||
MediaPause = ndk_sys::AKEYCODE_MEDIA_PAUSE,
|
||||
MediaClose = ndk_sys::AKEYCODE_MEDIA_CLOSE,
|
||||
MediaEject = ndk_sys::AKEYCODE_MEDIA_EJECT,
|
||||
MediaRecord = ndk_sys::AKEYCODE_MEDIA_RECORD,
|
||||
F1 = ndk_sys::AKEYCODE_F1,
|
||||
F2 = ndk_sys::AKEYCODE_F2,
|
||||
F3 = ndk_sys::AKEYCODE_F3,
|
||||
F4 = ndk_sys::AKEYCODE_F4,
|
||||
F5 = ndk_sys::AKEYCODE_F5,
|
||||
F6 = ndk_sys::AKEYCODE_F6,
|
||||
F7 = ndk_sys::AKEYCODE_F7,
|
||||
F8 = ndk_sys::AKEYCODE_F8,
|
||||
F9 = ndk_sys::AKEYCODE_F9,
|
||||
F10 = ndk_sys::AKEYCODE_F10,
|
||||
F11 = ndk_sys::AKEYCODE_F11,
|
||||
F12 = ndk_sys::AKEYCODE_F12,
|
||||
NumLock = ndk_sys::AKEYCODE_NUM_LOCK,
|
||||
Numpad0 = ndk_sys::AKEYCODE_NUMPAD_0,
|
||||
Numpad1 = ndk_sys::AKEYCODE_NUMPAD_1,
|
||||
Numpad2 = ndk_sys::AKEYCODE_NUMPAD_2,
|
||||
Numpad3 = ndk_sys::AKEYCODE_NUMPAD_3,
|
||||
Numpad4 = ndk_sys::AKEYCODE_NUMPAD_4,
|
||||
Numpad5 = ndk_sys::AKEYCODE_NUMPAD_5,
|
||||
Numpad6 = ndk_sys::AKEYCODE_NUMPAD_6,
|
||||
Numpad7 = ndk_sys::AKEYCODE_NUMPAD_7,
|
||||
Numpad8 = ndk_sys::AKEYCODE_NUMPAD_8,
|
||||
Numpad9 = ndk_sys::AKEYCODE_NUMPAD_9,
|
||||
NumpadDivide = ndk_sys::AKEYCODE_NUMPAD_DIVIDE,
|
||||
NumpadMultiply = ndk_sys::AKEYCODE_NUMPAD_MULTIPLY,
|
||||
NumpadSubtract = ndk_sys::AKEYCODE_NUMPAD_SUBTRACT,
|
||||
NumpadAdd = ndk_sys::AKEYCODE_NUMPAD_ADD,
|
||||
NumpadDot = ndk_sys::AKEYCODE_NUMPAD_DOT,
|
||||
NumpadComma = ndk_sys::AKEYCODE_NUMPAD_COMMA,
|
||||
NumpadEnter = ndk_sys::AKEYCODE_NUMPAD_ENTER,
|
||||
NumpadEquals = ndk_sys::AKEYCODE_NUMPAD_EQUALS,
|
||||
NumpadLeftParen = ndk_sys::AKEYCODE_NUMPAD_LEFT_PAREN,
|
||||
NumpadRightParen = ndk_sys::AKEYCODE_NUMPAD_RIGHT_PAREN,
|
||||
VolumeMute = ndk_sys::AKEYCODE_VOLUME_MUTE,
|
||||
Info = ndk_sys::AKEYCODE_INFO,
|
||||
ChannelUp = ndk_sys::AKEYCODE_CHANNEL_UP,
|
||||
ChannelDown = ndk_sys::AKEYCODE_CHANNEL_DOWN,
|
||||
ZoomIn = ndk_sys::AKEYCODE_ZOOM_IN,
|
||||
ZoomOut = ndk_sys::AKEYCODE_ZOOM_OUT,
|
||||
Tv = ndk_sys::AKEYCODE_TV,
|
||||
Window = ndk_sys::AKEYCODE_WINDOW,
|
||||
Guide = ndk_sys::AKEYCODE_GUIDE,
|
||||
Dvr = ndk_sys::AKEYCODE_DVR,
|
||||
Bookmark = ndk_sys::AKEYCODE_BOOKMARK,
|
||||
Captions = ndk_sys::AKEYCODE_CAPTIONS,
|
||||
Settings = ndk_sys::AKEYCODE_SETTINGS,
|
||||
TvPower = ndk_sys::AKEYCODE_TV_POWER,
|
||||
TvInput = ndk_sys::AKEYCODE_TV_INPUT,
|
||||
StbPower = ndk_sys::AKEYCODE_STB_POWER,
|
||||
StbInput = ndk_sys::AKEYCODE_STB_INPUT,
|
||||
AvrPower = ndk_sys::AKEYCODE_AVR_POWER,
|
||||
AvrInput = ndk_sys::AKEYCODE_AVR_INPUT,
|
||||
ProgRed = ndk_sys::AKEYCODE_PROG_RED,
|
||||
ProgGreen = ndk_sys::AKEYCODE_PROG_GREEN,
|
||||
ProgYellow = ndk_sys::AKEYCODE_PROG_YELLOW,
|
||||
ProgBlue = ndk_sys::AKEYCODE_PROG_BLUE,
|
||||
AppSwitch = ndk_sys::AKEYCODE_APP_SWITCH,
|
||||
Button1 = ndk_sys::AKEYCODE_BUTTON_1,
|
||||
Button2 = ndk_sys::AKEYCODE_BUTTON_2,
|
||||
Button3 = ndk_sys::AKEYCODE_BUTTON_3,
|
||||
Button4 = ndk_sys::AKEYCODE_BUTTON_4,
|
||||
Button5 = ndk_sys::AKEYCODE_BUTTON_5,
|
||||
Button6 = ndk_sys::AKEYCODE_BUTTON_6,
|
||||
Button7 = ndk_sys::AKEYCODE_BUTTON_7,
|
||||
Button8 = ndk_sys::AKEYCODE_BUTTON_8,
|
||||
Button9 = ndk_sys::AKEYCODE_BUTTON_9,
|
||||
Button10 = ndk_sys::AKEYCODE_BUTTON_10,
|
||||
Button11 = ndk_sys::AKEYCODE_BUTTON_11,
|
||||
Button12 = ndk_sys::AKEYCODE_BUTTON_12,
|
||||
Button13 = ndk_sys::AKEYCODE_BUTTON_13,
|
||||
Button14 = ndk_sys::AKEYCODE_BUTTON_14,
|
||||
Button15 = ndk_sys::AKEYCODE_BUTTON_15,
|
||||
Button16 = ndk_sys::AKEYCODE_BUTTON_16,
|
||||
LanguageSwitch = ndk_sys::AKEYCODE_LANGUAGE_SWITCH,
|
||||
MannerMode = ndk_sys::AKEYCODE_MANNER_MODE,
|
||||
Keycode3dMode = ndk_sys::AKEYCODE_3D_MODE,
|
||||
Contacts = ndk_sys::AKEYCODE_CONTACTS,
|
||||
Calendar = ndk_sys::AKEYCODE_CALENDAR,
|
||||
Music = ndk_sys::AKEYCODE_MUSIC,
|
||||
Calculator = ndk_sys::AKEYCODE_CALCULATOR,
|
||||
ZenkakuHankaku = ndk_sys::AKEYCODE_ZENKAKU_HANKAKU,
|
||||
Eisu = ndk_sys::AKEYCODE_EISU,
|
||||
Muhenkan = ndk_sys::AKEYCODE_MUHENKAN,
|
||||
Henkan = ndk_sys::AKEYCODE_HENKAN,
|
||||
KatakanaHiragana = ndk_sys::AKEYCODE_KATAKANA_HIRAGANA,
|
||||
Yen = ndk_sys::AKEYCODE_YEN,
|
||||
Ro = ndk_sys::AKEYCODE_RO,
|
||||
Kana = ndk_sys::AKEYCODE_KANA,
|
||||
Assist = ndk_sys::AKEYCODE_ASSIST,
|
||||
BrightnessDown = ndk_sys::AKEYCODE_BRIGHTNESS_DOWN,
|
||||
BrightnessUp = ndk_sys::AKEYCODE_BRIGHTNESS_UP,
|
||||
MediaAudioTrack = ndk_sys::AKEYCODE_MEDIA_AUDIO_TRACK,
|
||||
Sleep = ndk_sys::AKEYCODE_SLEEP,
|
||||
Wakeup = ndk_sys::AKEYCODE_WAKEUP,
|
||||
Pairing = ndk_sys::AKEYCODE_PAIRING,
|
||||
MediaTopMenu = ndk_sys::AKEYCODE_MEDIA_TOP_MENU,
|
||||
Keycode11 = ndk_sys::AKEYCODE_11,
|
||||
Keycode12 = ndk_sys::AKEYCODE_12,
|
||||
LastChannel = ndk_sys::AKEYCODE_LAST_CHANNEL,
|
||||
TvDataService = ndk_sys::AKEYCODE_TV_DATA_SERVICE,
|
||||
VoiceAssist = ndk_sys::AKEYCODE_VOICE_ASSIST,
|
||||
TvRadioService = ndk_sys::AKEYCODE_TV_RADIO_SERVICE,
|
||||
TvTeletext = ndk_sys::AKEYCODE_TV_TELETEXT,
|
||||
TvNumberEntry = ndk_sys::AKEYCODE_TV_NUMBER_ENTRY,
|
||||
TvTerrestrialAnalog = ndk_sys::AKEYCODE_TV_TERRESTRIAL_ANALOG,
|
||||
TvTerrestrialDigital = ndk_sys::AKEYCODE_TV_TERRESTRIAL_DIGITAL,
|
||||
TvSatellite = ndk_sys::AKEYCODE_TV_SATELLITE,
|
||||
TvSatelliteBs = ndk_sys::AKEYCODE_TV_SATELLITE_BS,
|
||||
TvSatelliteCs = ndk_sys::AKEYCODE_TV_SATELLITE_CS,
|
||||
TvSatelliteService = ndk_sys::AKEYCODE_TV_SATELLITE_SERVICE,
|
||||
TvNetwork = ndk_sys::AKEYCODE_TV_NETWORK,
|
||||
TvAntennaCable = ndk_sys::AKEYCODE_TV_ANTENNA_CABLE,
|
||||
TvInputHdmi1 = ndk_sys::AKEYCODE_TV_INPUT_HDMI_1,
|
||||
TvInputHdmi2 = ndk_sys::AKEYCODE_TV_INPUT_HDMI_2,
|
||||
TvInputHdmi3 = ndk_sys::AKEYCODE_TV_INPUT_HDMI_3,
|
||||
TvInputHdmi4 = ndk_sys::AKEYCODE_TV_INPUT_HDMI_4,
|
||||
TvInputComposite1 = ndk_sys::AKEYCODE_TV_INPUT_COMPOSITE_1,
|
||||
TvInputComposite2 = ndk_sys::AKEYCODE_TV_INPUT_COMPOSITE_2,
|
||||
TvInputComponent1 = ndk_sys::AKEYCODE_TV_INPUT_COMPONENT_1,
|
||||
TvInputComponent2 = ndk_sys::AKEYCODE_TV_INPUT_COMPONENT_2,
|
||||
TvInputVga1 = ndk_sys::AKEYCODE_TV_INPUT_VGA_1,
|
||||
TvAudioDescription = ndk_sys::AKEYCODE_TV_AUDIO_DESCRIPTION,
|
||||
TvAudioDescriptionMixUp = ndk_sys::AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP,
|
||||
TvAudioDescriptionMixDown = ndk_sys::AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN,
|
||||
TvZoomMode = ndk_sys::AKEYCODE_TV_ZOOM_MODE,
|
||||
TvContentsMenu = ndk_sys::AKEYCODE_TV_CONTENTS_MENU,
|
||||
TvMediaContextMenu = ndk_sys::AKEYCODE_TV_MEDIA_CONTEXT_MENU,
|
||||
TvTimerProgramming = ndk_sys::AKEYCODE_TV_TIMER_PROGRAMMING,
|
||||
Help = ndk_sys::AKEYCODE_HELP,
|
||||
NavigatePrevious = ndk_sys::AKEYCODE_NAVIGATE_PREVIOUS,
|
||||
NavigateNext = ndk_sys::AKEYCODE_NAVIGATE_NEXT,
|
||||
NavigateIn = ndk_sys::AKEYCODE_NAVIGATE_IN,
|
||||
NavigateOut = ndk_sys::AKEYCODE_NAVIGATE_OUT,
|
||||
StemPrimary = ndk_sys::AKEYCODE_STEM_PRIMARY,
|
||||
Stem1 = ndk_sys::AKEYCODE_STEM_1,
|
||||
Stem2 = ndk_sys::AKEYCODE_STEM_2,
|
||||
Stem3 = ndk_sys::AKEYCODE_STEM_3,
|
||||
DpadUpLeft = ndk_sys::AKEYCODE_DPAD_UP_LEFT,
|
||||
DpadDownLeft = ndk_sys::AKEYCODE_DPAD_DOWN_LEFT,
|
||||
DpadUpRight = ndk_sys::AKEYCODE_DPAD_UP_RIGHT,
|
||||
DpadDownRight = ndk_sys::AKEYCODE_DPAD_DOWN_RIGHT,
|
||||
MediaSkipForward = ndk_sys::AKEYCODE_MEDIA_SKIP_FORWARD,
|
||||
MediaSkipBackward = ndk_sys::AKEYCODE_MEDIA_SKIP_BACKWARD,
|
||||
MediaStepForward = ndk_sys::AKEYCODE_MEDIA_STEP_FORWARD,
|
||||
MediaStepBackward = ndk_sys::AKEYCODE_MEDIA_STEP_BACKWARD,
|
||||
SoftSleep = ndk_sys::AKEYCODE_SOFT_SLEEP,
|
||||
Cut = ndk_sys::AKEYCODE_CUT,
|
||||
Copy = ndk_sys::AKEYCODE_COPY,
|
||||
Paste = ndk_sys::AKEYCODE_PASTE,
|
||||
SystemNavigationUp = ndk_sys::AKEYCODE_SYSTEM_NAVIGATION_UP,
|
||||
SystemNavigationDown = ndk_sys::AKEYCODE_SYSTEM_NAVIGATION_DOWN,
|
||||
SystemNavigationLeft = ndk_sys::AKEYCODE_SYSTEM_NAVIGATION_LEFT,
|
||||
SystemNavigationRight = ndk_sys::AKEYCODE_SYSTEM_NAVIGATION_RIGHT,
|
||||
AllApps = ndk_sys::AKEYCODE_ALL_APPS,
|
||||
Refresh = ndk_sys::AKEYCODE_REFRESH,
|
||||
ThumbsUp = ndk_sys::AKEYCODE_THUMBS_UP,
|
||||
ThumbsDown = ndk_sys::AKEYCODE_THUMBS_DOWN,
|
||||
ProfileSwitch = ndk_sys::AKEYCODE_PROFILE_SWITCH,
|
||||
|
||||
#[doc(hidden)]
|
||||
#[num_enum(catch_all)]
|
||||
__Unknown(u32),
|
||||
}
|
||||
|
||||
/// Flags associated with [`KeyEvent`].
|
||||
///
|
||||
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-28)
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct KeyEventFlags(pub u32);
|
||||
|
||||
impl KeyEventFlags {
|
||||
#[inline]
|
||||
pub fn cancelled(&self) -> bool {
|
||||
self.0 & ndk_sys::AKEY_EVENT_FLAG_CANCELED != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn cancelled_long_press(&self) -> bool {
|
||||
self.0 & ndk_sys::AKEY_EVENT_FLAG_CANCELED_LONG_PRESS != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn editor_action(&self) -> bool {
|
||||
self.0 & ndk_sys::AKEY_EVENT_FLAG_EDITOR_ACTION != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn fallback(&self) -> bool {
|
||||
self.0 & ndk_sys::AKEY_EVENT_FLAG_FALLBACK != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn from_system(&self) -> bool {
|
||||
self.0 & ndk_sys::AKEY_EVENT_FLAG_FROM_SYSTEM != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn keep_touch_mode(&self) -> bool {
|
||||
self.0 & ndk_sys::AKEY_EVENT_FLAG_KEEP_TOUCH_MODE != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn long_press(&self) -> bool {
|
||||
self.0 & ndk_sys::AKEY_EVENT_FLAG_LONG_PRESS != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn soft_keyboard(&self) -> bool {
|
||||
self.0 & ndk_sys::AKEY_EVENT_FLAG_SOFT_KEYBOARD != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn tracking(&self) -> bool {
|
||||
self.0 & ndk_sys::AKEY_EVENT_FLAG_TRACKING != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn virtual_hard_key(&self) -> bool {
|
||||
self.0 & ndk_sys::AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY != 0
|
||||
}
|
||||
#[inline]
|
||||
pub fn woke_here(&self) -> bool {
|
||||
self.0 & ndk_sys::AKEY_EVENT_FLAG_WOKE_HERE != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ndk::event::KeyEventFlags> for KeyEventFlags {
|
||||
fn from(value: ndk::event::KeyEventFlags) -> Self {
|
||||
Self(value.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// This struct holds a span within a region of text from `start` to `end`.
|
||||
///
|
||||
/// The `start` index may be greater than the `end` index (swapping `start` and `end` will represent the same span)
|
||||
@@ -78,6 +907,33 @@ pub struct TextInputState {
|
||||
pub compose_region: Option<TextSpan>,
|
||||
}
|
||||
|
||||
// Represents the action button on a soft keyboard.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
|
||||
#[non_exhaustive]
|
||||
#[repr(i32)]
|
||||
pub enum TextInputAction {
|
||||
/// Let receiver decide what logical action to perform
|
||||
Unspecified = 0,
|
||||
/// No action - receiver could instead interpret as an "enter" key that inserts a newline character
|
||||
None = 1,
|
||||
/// Navigate to the input location (such as a URL)
|
||||
Go = 2,
|
||||
/// Search based on the input text
|
||||
Search = 3,
|
||||
/// Send the input to the target
|
||||
Send = 4,
|
||||
/// Move to the next input field
|
||||
Next = 5,
|
||||
/// Indicate that input is done
|
||||
Done = 6,
|
||||
/// Move to the previous input field
|
||||
Previous = 7,
|
||||
|
||||
#[doc(hidden)]
|
||||
#[num_enum(catch_all)]
|
||||
__Unknown(i32),
|
||||
}
|
||||
|
||||
/// An exclusive, lending iterator for input events
|
||||
pub struct InputIterator<'a> {
|
||||
pub(crate) inner: crate::activity_impl::InputIteratorInner<'a>,
|
||||
|
||||
@@ -246,8 +246,10 @@ impl KeyCharacterMap {
|
||||
/// a [`AppError::JavaError`] in case there is a spurious JNI error or an exception
|
||||
/// is caught.
|
||||
pub fn get(&self, key_code: Keycode, meta_state: MetaState) -> Result<KeyMapChar, AppError> {
|
||||
let key_code = key_code.into();
|
||||
let meta_state = meta_state.0 as i32;
|
||||
let key_code: u32 = key_code.into();
|
||||
let key_code = key_code as jni_sys::jint;
|
||||
let meta_state: u32 = meta_state.0;
|
||||
let meta_state = meta_state as jni_sys::jint;
|
||||
|
||||
// Since we expect this API to be called from the `main` thread then we expect to already be
|
||||
// attached to the JVM
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use ndk::event::ButtonState;
|
||||
|
||||
use crate::input::{
|
||||
Axis, EdgeFlags, KeyAction, Keycode, MetaState, MotionAction, MotionEventFlags, Pointer,
|
||||
PointersIter, Source, ToolType,
|
||||
Axis, Button, ButtonState, EdgeFlags, KeyAction, Keycode, MetaState, MotionAction,
|
||||
MotionEventFlags, Pointer, PointersIter, Source, ToolType,
|
||||
};
|
||||
|
||||
/// A motion event
|
||||
@@ -32,7 +30,13 @@ impl MotionEvent<'_> {
|
||||
///
|
||||
#[inline]
|
||||
pub fn source(&self) -> Source {
|
||||
self.ndk_event.source()
|
||||
// XXX: we use `AInputEvent_getSource` directly (instead of calling
|
||||
// ndk_event.source()) since we have our own `Source` enum that we
|
||||
// share between backends, which may also capture unknown variants
|
||||
// added in new versions of Android.
|
||||
let source =
|
||||
unsafe { ndk_sys::AInputEvent_getSource(self.ndk_event.ptr().as_ptr()) as u32 };
|
||||
source.into()
|
||||
}
|
||||
|
||||
/// Get the device id associated with the event.
|
||||
@@ -47,7 +51,13 @@ impl MotionEvent<'_> {
|
||||
/// See [the MotionEvent docs](https://developer.android.com/reference/android/view/MotionEvent#getActionMasked())
|
||||
#[inline]
|
||||
pub fn action(&self) -> MotionAction {
|
||||
self.ndk_event.action()
|
||||
// XXX: we use `AMotionEvent_getAction` directly since we have our own
|
||||
// `MotionAction` enum that we share between backends, which may also
|
||||
// capture unknown variants added in new versions of Android.
|
||||
let action =
|
||||
unsafe { ndk_sys::AMotionEvent_getAction(self.ndk_event.ptr().as_ptr()) as u32 }
|
||||
& ndk_sys::AMOTION_EVENT_ACTION_MASK;
|
||||
action.into()
|
||||
}
|
||||
|
||||
/// Returns which button has been modified during a press or release action.
|
||||
@@ -57,11 +67,10 @@ impl MotionEvent<'_> {
|
||||
///
|
||||
/// See [the MotionEvent docs](https://developer.android.com/reference/android/view/MotionEvent#getActionButton())
|
||||
#[inline]
|
||||
#[cfg(feature = "api-level-33")]
|
||||
#[doc(alias = "AMotionEvent_getActionButton")]
|
||||
// TODO: Button enum to signify only one bitflag can be set?
|
||||
pub fn action_button(&self) -> ButtonState {
|
||||
self.ndk_event.action_button()
|
||||
pub fn action_button(&self) -> Button {
|
||||
let action_button =
|
||||
unsafe { ndk_sys::AMotionEvent_getActionButton(self.ndk_event.ptr().as_ptr()) as u32 };
|
||||
action_button.into()
|
||||
}
|
||||
|
||||
/// Returns the pointer index of an `Up` or `Down` event.
|
||||
@@ -145,7 +154,7 @@ impl MotionEvent<'_> {
|
||||
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getmetastate)
|
||||
#[inline]
|
||||
pub fn meta_state(&self) -> MetaState {
|
||||
self.ndk_event.meta_state()
|
||||
self.ndk_event.meta_state().into()
|
||||
}
|
||||
|
||||
/// Returns the button state during this event, as a bitfield.
|
||||
@@ -154,7 +163,7 @@ impl MotionEvent<'_> {
|
||||
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getbuttonstate)
|
||||
#[inline]
|
||||
pub fn button_state(&self) -> ButtonState {
|
||||
self.ndk_event.button_state()
|
||||
self.ndk_event.button_state().into()
|
||||
}
|
||||
|
||||
/// Returns the time of the start of this gesture, in the `java.lang.System.nanoTime()` time
|
||||
@@ -173,7 +182,7 @@ impl MotionEvent<'_> {
|
||||
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getedgeflags)
|
||||
#[inline]
|
||||
pub fn edge_flags(&self) -> EdgeFlags {
|
||||
self.ndk_event.edge_flags()
|
||||
self.ndk_event.edge_flags().into()
|
||||
}
|
||||
|
||||
/// Returns the time of this event, in the `java.lang.System.nanoTime()` time base
|
||||
@@ -191,7 +200,7 @@ impl MotionEvent<'_> {
|
||||
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getflags)
|
||||
#[inline]
|
||||
pub fn flags(&self) -> MotionEventFlags {
|
||||
self.ndk_event.flags()
|
||||
self.ndk_event.flags().into()
|
||||
}
|
||||
|
||||
/* Missing from GameActivity currently...
|
||||
@@ -252,7 +261,8 @@ impl PointerImpl<'_> {
|
||||
|
||||
#[inline]
|
||||
pub fn axis_value(&self, axis: Axis) -> f32 {
|
||||
let value: i32 = axis.into();
|
||||
let value: u32 = axis.into();
|
||||
let value = value as i32;
|
||||
self.ndk_pointer.axis_value(value.into())
|
||||
}
|
||||
|
||||
@@ -269,6 +279,7 @@ impl PointerImpl<'_> {
|
||||
#[inline]
|
||||
pub fn tool_type(&self) -> ToolType {
|
||||
let value: i32 = self.ndk_pointer.tool_type().into();
|
||||
let value = value as u32;
|
||||
value.into()
|
||||
}
|
||||
}
|
||||
@@ -320,9 +331,16 @@ impl KeyEvent<'_> {
|
||||
}
|
||||
|
||||
/// Get the source of the event.
|
||||
///
|
||||
#[inline]
|
||||
pub fn source(&self) -> Source {
|
||||
self.ndk_event.source()
|
||||
// XXX: we use `AInputEvent_getSource` directly (instead of calling
|
||||
// ndk_event.source()) since we have our own `Source` enum that we
|
||||
// share between backends, which may also capture unknown variants
|
||||
// added in new versions of Android.
|
||||
let source =
|
||||
unsafe { ndk_sys::AInputEvent_getSource(self.ndk_event.ptr().as_ptr()) as u32 };
|
||||
source.into()
|
||||
}
|
||||
|
||||
/// Get the device id associated with the event.
|
||||
@@ -337,7 +355,11 @@ impl KeyEvent<'_> {
|
||||
/// See [the KeyEvent docs](https://developer.android.com/reference/android/view/KeyEvent#getAction())
|
||||
#[inline]
|
||||
pub fn action(&self) -> KeyAction {
|
||||
self.ndk_event.action()
|
||||
// XXX: we use `AInputEvent_getAction` directly since we have our own
|
||||
// `KeyAction` enum that we share between backends, which may also
|
||||
// capture unknown variants added in new versions of Android.
|
||||
let action = unsafe { ndk_sys::AKeyEvent_getAction(self.ndk_event.ptr().as_ptr()) as u32 };
|
||||
action.into()
|
||||
}
|
||||
|
||||
/// Returns the last time the key was pressed. This is on the scale of
|
||||
@@ -366,7 +388,12 @@ impl KeyEvent<'_> {
|
||||
/// docs](https://developer.android.com/ndk/reference/group/input#akeyevent_getkeycode)
|
||||
#[inline]
|
||||
pub fn key_code(&self) -> Keycode {
|
||||
self.ndk_event.key_code()
|
||||
// XXX: we use `AInputEvent_getKeyCode` directly since we have our own
|
||||
// `Keycode` enum that we share between backends, which may also
|
||||
// capture unknown variants added in new versions of Android.
|
||||
let keycode =
|
||||
unsafe { ndk_sys::AKeyEvent_getKeyCode(self.ndk_event.ptr().as_ptr()) as u32 };
|
||||
keycode.into()
|
||||
}
|
||||
|
||||
/// Returns the number of repeats of a key.
|
||||
@@ -393,12 +420,13 @@ impl KeyEvent<'_> {
|
||||
/// docs](https://developer.android.com/ndk/reference/group/input#akeyevent_getmetastate)
|
||||
#[inline]
|
||||
pub fn meta_state(&self) -> MetaState {
|
||||
self.ndk_event.meta_state()
|
||||
self.ndk_event.meta_state().into()
|
||||
}
|
||||
}
|
||||
|
||||
// We use our own wrapper type for input events to have better consistency
|
||||
// with GameActivity
|
||||
// with GameActivity and ensure the enum can be extended without needing a
|
||||
// semver bump
|
||||
/// Enum of possible input events
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
@@ -406,4 +434,5 @@ pub enum InputEvent<'a> {
|
||||
MotionEvent(self::MotionEvent<'a>),
|
||||
KeyEvent(self::KeyEvent<'a>),
|
||||
TextEvent(crate::input::TextInputState),
|
||||
TextAction(crate::input::TextInputAction),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user