mirror of
https://github.com/godotengine/godot.git
synced 2024-11-27 09:16:35 +08:00
Merge pull request #37158 from thebestnom/android-click-support
Support mouse events on Android
This commit is contained in:
commit
41f66761fd
@ -31,130 +31,9 @@
|
||||
#ifndef ANDROID_KEYS_UTILS_H
|
||||
#define ANDROID_KEYS_UTILS_H
|
||||
|
||||
#include <android/input.h>
|
||||
#include <core/os/keyboard.h>
|
||||
|
||||
/*
|
||||
* Android Key codes.
|
||||
*/
|
||||
enum {
|
||||
AKEYCODE_UNKNOWN = 0,
|
||||
AKEYCODE_SOFT_LEFT = 1,
|
||||
AKEYCODE_SOFT_RIGHT = 2,
|
||||
AKEYCODE_HOME = 3,
|
||||
AKEYCODE_BACK = 4,
|
||||
AKEYCODE_CALL = 5,
|
||||
AKEYCODE_ENDCALL = 6,
|
||||
AKEYCODE_0 = 7,
|
||||
AKEYCODE_1 = 8,
|
||||
AKEYCODE_2 = 9,
|
||||
AKEYCODE_3 = 10,
|
||||
AKEYCODE_4 = 11,
|
||||
AKEYCODE_5 = 12,
|
||||
AKEYCODE_6 = 13,
|
||||
AKEYCODE_7 = 14,
|
||||
AKEYCODE_8 = 15,
|
||||
AKEYCODE_9 = 16,
|
||||
AKEYCODE_STAR = 17,
|
||||
AKEYCODE_POUND = 18,
|
||||
AKEYCODE_DPAD_UP = 19,
|
||||
AKEYCODE_DPAD_DOWN = 20,
|
||||
AKEYCODE_DPAD_LEFT = 21,
|
||||
AKEYCODE_DPAD_RIGHT = 22,
|
||||
AKEYCODE_DPAD_CENTER = 23,
|
||||
AKEYCODE_VOLUME_UP = 24,
|
||||
AKEYCODE_VOLUME_DOWN = 25,
|
||||
AKEYCODE_POWER = 26,
|
||||
AKEYCODE_CAMERA = 27,
|
||||
AKEYCODE_CLEAR = 28,
|
||||
AKEYCODE_A = 29,
|
||||
AKEYCODE_B = 30,
|
||||
AKEYCODE_C = 31,
|
||||
AKEYCODE_D = 32,
|
||||
AKEYCODE_E = 33,
|
||||
AKEYCODE_F = 34,
|
||||
AKEYCODE_G = 35,
|
||||
AKEYCODE_H = 36,
|
||||
AKEYCODE_I = 37,
|
||||
AKEYCODE_J = 38,
|
||||
AKEYCODE_K = 39,
|
||||
AKEYCODE_L = 40,
|
||||
AKEYCODE_M = 41,
|
||||
AKEYCODE_N = 42,
|
||||
AKEYCODE_O = 43,
|
||||
AKEYCODE_P = 44,
|
||||
AKEYCODE_Q = 45,
|
||||
AKEYCODE_R = 46,
|
||||
AKEYCODE_S = 47,
|
||||
AKEYCODE_T = 48,
|
||||
AKEYCODE_U = 49,
|
||||
AKEYCODE_V = 50,
|
||||
AKEYCODE_W = 51,
|
||||
AKEYCODE_X = 52,
|
||||
AKEYCODE_Y = 53,
|
||||
AKEYCODE_Z = 54,
|
||||
AKEYCODE_COMMA = 55,
|
||||
AKEYCODE_PERIOD = 56,
|
||||
AKEYCODE_ALT_LEFT = 57,
|
||||
AKEYCODE_ALT_RIGHT = 58,
|
||||
AKEYCODE_SHIFT_LEFT = 59,
|
||||
AKEYCODE_SHIFT_RIGHT = 60,
|
||||
AKEYCODE_TAB = 61,
|
||||
AKEYCODE_SPACE = 62,
|
||||
AKEYCODE_SYM = 63,
|
||||
AKEYCODE_EXPLORER = 64,
|
||||
AKEYCODE_ENVELOPE = 65,
|
||||
AKEYCODE_ENTER = 66,
|
||||
AKEYCODE_DEL = 67,
|
||||
AKEYCODE_GRAVE = 68,
|
||||
AKEYCODE_MINUS = 69,
|
||||
AKEYCODE_EQUALS = 70,
|
||||
AKEYCODE_LEFT_BRACKET = 71,
|
||||
AKEYCODE_RIGHT_BRACKET = 72,
|
||||
AKEYCODE_BACKSLASH = 73,
|
||||
AKEYCODE_SEMICOLON = 74,
|
||||
AKEYCODE_APOSTROPHE = 75,
|
||||
AKEYCODE_SLASH = 76,
|
||||
AKEYCODE_AT = 77,
|
||||
AKEYCODE_NUM = 78,
|
||||
AKEYCODE_HEADSETHOOK = 79,
|
||||
AKEYCODE_FOCUS = 80, // *Camera* focus
|
||||
AKEYCODE_PLUS = 81,
|
||||
AKEYCODE_MENU = 82,
|
||||
AKEYCODE_NOTIFICATION = 83,
|
||||
AKEYCODE_SEARCH = 84,
|
||||
AKEYCODE_MEDIA_PLAY_PAUSE = 85,
|
||||
AKEYCODE_MEDIA_STOP = 86,
|
||||
AKEYCODE_MEDIA_NEXT = 87,
|
||||
AKEYCODE_MEDIA_PREVIOUS = 88,
|
||||
AKEYCODE_MEDIA_REWIND = 89,
|
||||
AKEYCODE_MEDIA_FAST_FORWARD = 90,
|
||||
AKEYCODE_MUTE = 91,
|
||||
AKEYCODE_PAGE_UP = 92,
|
||||
AKEYCODE_PAGE_DOWN = 93,
|
||||
AKEYCODE_PICTSYMBOLS = 94,
|
||||
AKEYCODE_SWITCH_CHARSET = 95,
|
||||
AKEYCODE_BUTTON_A = 96,
|
||||
AKEYCODE_BUTTON_B = 97,
|
||||
AKEYCODE_BUTTON_C = 98,
|
||||
AKEYCODE_BUTTON_X = 99,
|
||||
AKEYCODE_BUTTON_Y = 100,
|
||||
AKEYCODE_BUTTON_Z = 101,
|
||||
AKEYCODE_BUTTON_L1 = 102,
|
||||
AKEYCODE_BUTTON_R1 = 103,
|
||||
AKEYCODE_BUTTON_L2 = 104,
|
||||
AKEYCODE_BUTTON_R2 = 105,
|
||||
AKEYCODE_BUTTON_THUMBL = 106,
|
||||
AKEYCODE_BUTTON_THUMBR = 107,
|
||||
AKEYCODE_BUTTON_START = 108,
|
||||
AKEYCODE_BUTTON_SELECT = 109,
|
||||
AKEYCODE_BUTTON_MODE = 110,
|
||||
AKEYCODE_CONTROL_LEFT = 113,
|
||||
AKEYCODE_CONTROL_RIGHT = 114,
|
||||
|
||||
// NOTE: If you add a new keycode here you must also add it to several other files.
|
||||
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
|
||||
};
|
||||
|
||||
struct _WinTranslatePair {
|
||||
unsigned int keysym;
|
||||
unsigned int keycode;
|
||||
@ -248,8 +127,8 @@ static _WinTranslatePair _ak_to_keycode[] = {
|
||||
{ KEY_BACKSLASH, AKEYCODE_BACKSLASH },
|
||||
{ KEY_BRACKETLEFT, AKEYCODE_LEFT_BRACKET },
|
||||
{ KEY_BRACKETRIGHT, AKEYCODE_RIGHT_BRACKET },
|
||||
{ KEY_CONTROL, AKEYCODE_CONTROL_LEFT },
|
||||
{ KEY_CONTROL, AKEYCODE_CONTROL_RIGHT },
|
||||
{ KEY_CONTROL, AKEYCODE_CTRL_LEFT },
|
||||
{ KEY_CONTROL, AKEYCODE_CTRL_RIGHT },
|
||||
{ KEY_UNKNOWN, 0 }
|
||||
};
|
||||
/*
|
||||
|
@ -36,6 +36,8 @@
|
||||
#include "java_godot_wrapper.h"
|
||||
#include "os_android.h"
|
||||
|
||||
#include <android/input.h>
|
||||
|
||||
#if defined(VULKAN_ENABLED)
|
||||
#include "drivers/vulkan/rendering_device_vulkan.h"
|
||||
#include "platform/android/vulkan/vulkan_context_android.h"
|
||||
@ -55,7 +57,7 @@ bool DisplayServerAndroid::has_feature(Feature p_feature) const {
|
||||
//case FEATURE_HIDPI:
|
||||
//case FEATURE_ICON:
|
||||
//case FEATURE_IME:
|
||||
//case FEATURE_MOUSE:
|
||||
case FEATURE_MOUSE:
|
||||
//case FEATURE_MOUSE_WARP:
|
||||
//case FEATURE_NATIVE_DIALOG:
|
||||
//case FEATURE_NATIVE_ICON:
|
||||
@ -343,7 +345,7 @@ void DisplayServerAndroid::alert(const String &p_alert, const String &p_title) {
|
||||
}
|
||||
|
||||
void DisplayServerAndroid::process_events() {
|
||||
// Nothing to do
|
||||
Input::get_singleton()->flush_accumulated_events();
|
||||
}
|
||||
|
||||
Vector<String> DisplayServerAndroid::get_rendering_drivers_func() {
|
||||
@ -398,6 +400,8 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis
|
||||
|
||||
keep_screen_on = GLOBAL_GET("display/window/energy_saving/keep_screen_on");
|
||||
|
||||
buttons_state = 0;
|
||||
|
||||
#if defined(OPENGL_ENABLED)
|
||||
if (rendering_driver == "opengl") {
|
||||
bool gl_initialization_error = false;
|
||||
@ -532,12 +536,12 @@ void DisplayServerAndroid::process_key_event(int p_keycode, int p_scancode, int
|
||||
OS_Android::get_singleton()->main_loop_request_go_back();
|
||||
}
|
||||
|
||||
Input::get_singleton()->parse_input_event(ev);
|
||||
Input::get_singleton()->accumulate_input_event(ev);
|
||||
}
|
||||
|
||||
void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector<DisplayServerAndroid::TouchPos> &p_points) {
|
||||
switch (p_what) {
|
||||
case 0: { //gesture begin
|
||||
void DisplayServerAndroid::process_touch(int p_event, int p_pointer, const Vector<DisplayServerAndroid::TouchPos> &p_points) {
|
||||
switch (p_event) {
|
||||
case AMOTION_EVENT_ACTION_DOWN: { //gesture begin
|
||||
if (touch.size()) {
|
||||
//end all if exist
|
||||
for (int i = 0; i < touch.size(); i++) {
|
||||
@ -546,7 +550,7 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector
|
||||
ev->set_index(touch[i].id);
|
||||
ev->set_pressed(false);
|
||||
ev->set_position(touch[i].pos);
|
||||
Input::get_singleton()->parse_input_event(ev);
|
||||
Input::get_singleton()->accumulate_input_event(ev);
|
||||
}
|
||||
}
|
||||
|
||||
@ -563,11 +567,11 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector
|
||||
ev->set_index(touch[i].id);
|
||||
ev->set_pressed(true);
|
||||
ev->set_position(touch[i].pos);
|
||||
Input::get_singleton()->parse_input_event(ev);
|
||||
Input::get_singleton()->accumulate_input_event(ev);
|
||||
}
|
||||
|
||||
} break;
|
||||
case 1: { //motion
|
||||
case AMOTION_EVENT_ACTION_MOVE: { //motion
|
||||
ERR_FAIL_COND(touch.size() != p_points.size());
|
||||
|
||||
for (int i = 0; i < touch.size(); i++) {
|
||||
@ -589,12 +593,13 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector
|
||||
ev->set_index(touch[i].id);
|
||||
ev->set_position(p_points[idx].pos);
|
||||
ev->set_relative(p_points[idx].pos - touch[i].pos);
|
||||
Input::get_singleton()->parse_input_event(ev);
|
||||
Input::get_singleton()->accumulate_input_event(ev);
|
||||
touch.write[i].pos = p_points[idx].pos;
|
||||
}
|
||||
|
||||
} break;
|
||||
case 2: { //release
|
||||
case AMOTION_EVENT_ACTION_CANCEL:
|
||||
case AMOTION_EVENT_ACTION_UP: { //release
|
||||
if (touch.size()) {
|
||||
//end all if exist
|
||||
for (int i = 0; i < touch.size(); i++) {
|
||||
@ -603,12 +608,12 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector
|
||||
ev->set_index(touch[i].id);
|
||||
ev->set_pressed(false);
|
||||
ev->set_position(touch[i].pos);
|
||||
Input::get_singleton()->parse_input_event(ev);
|
||||
Input::get_singleton()->accumulate_input_event(ev);
|
||||
}
|
||||
touch.clear();
|
||||
}
|
||||
} break;
|
||||
case 3: { // add touch
|
||||
case AMOTION_EVENT_ACTION_POINTER_DOWN: { // add touch
|
||||
for (int i = 0; i < p_points.size(); i++) {
|
||||
if (p_points[i].id == p_pointer) {
|
||||
TouchPos tp = p_points[i];
|
||||
@ -620,13 +625,13 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector
|
||||
ev->set_index(tp.id);
|
||||
ev->set_pressed(true);
|
||||
ev->set_position(tp.pos);
|
||||
Input::get_singleton()->parse_input_event(ev);
|
||||
Input::get_singleton()->accumulate_input_event(ev);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case 4: { // remove touch
|
||||
case AMOTION_EVENT_ACTION_POINTER_UP: { // remove touch
|
||||
for (int i = 0; i < touch.size(); i++) {
|
||||
if (touch[i].id == p_pointer) {
|
||||
Ref<InputEventScreenTouch> ev;
|
||||
@ -634,7 +639,7 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector
|
||||
ev->set_index(touch[i].id);
|
||||
ev->set_pressed(false);
|
||||
ev->set_position(touch[i].pos);
|
||||
Input::get_singleton()->parse_input_event(ev);
|
||||
Input::get_singleton()->accumulate_input_event(ev);
|
||||
touch.remove(i);
|
||||
|
||||
break;
|
||||
@ -647,30 +652,116 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector
|
||||
void DisplayServerAndroid::process_hover(int p_type, Point2 p_pos) {
|
||||
// https://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_ENTER
|
||||
switch (p_type) {
|
||||
case 7: // hover move
|
||||
case 9: // hover enter
|
||||
case 10: { // hover exit
|
||||
case AMOTION_EVENT_ACTION_HOVER_MOVE: // hover move
|
||||
case AMOTION_EVENT_ACTION_HOVER_ENTER: // hover enter
|
||||
case AMOTION_EVENT_ACTION_HOVER_EXIT: { // hover exit
|
||||
Ref<InputEventMouseMotion> ev;
|
||||
ev.instance();
|
||||
_set_key_modifier_state(ev);
|
||||
ev->set_position(p_pos);
|
||||
ev->set_global_position(p_pos);
|
||||
ev->set_relative(p_pos - hover_prev_pos);
|
||||
Input::get_singleton()->parse_input_event(ev);
|
||||
Input::get_singleton()->accumulate_input_event(ev);
|
||||
hover_prev_pos = p_pos;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServerAndroid::process_double_tap(Point2 p_pos) {
|
||||
void DisplayServerAndroid::process_mouse_event(int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor, float event_horizontal_factor) {
|
||||
int event_buttons_mask = _android_button_mask_to_godot_button_mask(event_android_buttons_mask);
|
||||
switch (event_action) {
|
||||
case AMOTION_EVENT_ACTION_BUTTON_PRESS:
|
||||
case AMOTION_EVENT_ACTION_BUTTON_RELEASE: {
|
||||
Ref<InputEventMouseButton> ev;
|
||||
ev.instance();
|
||||
_set_key_modifier_state(ev);
|
||||
ev->set_position(event_pos);
|
||||
ev->set_global_position(event_pos);
|
||||
ev->set_pressed(event_action == AMOTION_EVENT_ACTION_BUTTON_PRESS);
|
||||
int changed_button_mask = buttons_state ^ event_buttons_mask;
|
||||
|
||||
buttons_state = event_buttons_mask;
|
||||
|
||||
ev->set_button_index(_button_index_from_mask(changed_button_mask));
|
||||
ev->set_button_mask(event_buttons_mask);
|
||||
Input::get_singleton()->accumulate_input_event(ev);
|
||||
} break;
|
||||
|
||||
case AMOTION_EVENT_ACTION_MOVE: {
|
||||
Ref<InputEventMouseMotion> ev;
|
||||
ev.instance();
|
||||
_set_key_modifier_state(ev);
|
||||
ev->set_position(event_pos);
|
||||
ev->set_global_position(event_pos);
|
||||
ev->set_relative(event_pos - hover_prev_pos);
|
||||
ev->set_button_mask(event_buttons_mask);
|
||||
Input::get_singleton()->accumulate_input_event(ev);
|
||||
hover_prev_pos = event_pos;
|
||||
} break;
|
||||
case AMOTION_EVENT_ACTION_SCROLL: {
|
||||
Ref<InputEventMouseButton> ev;
|
||||
ev.instance();
|
||||
ev->set_position(event_pos);
|
||||
ev->set_global_position(event_pos);
|
||||
ev->set_pressed(true);
|
||||
buttons_state = event_buttons_mask;
|
||||
if (event_vertical_factor > 0) {
|
||||
_wheel_button_click(event_buttons_mask, ev, BUTTON_WHEEL_UP, event_vertical_factor);
|
||||
} else if (event_vertical_factor < 0) {
|
||||
_wheel_button_click(event_buttons_mask, ev, BUTTON_WHEEL_DOWN, -event_vertical_factor);
|
||||
}
|
||||
|
||||
if (event_horizontal_factor > 0) {
|
||||
_wheel_button_click(event_buttons_mask, ev, BUTTON_WHEEL_RIGHT, event_horizontal_factor);
|
||||
} else if (event_horizontal_factor < 0) {
|
||||
_wheel_button_click(event_buttons_mask, ev, BUTTON_WHEEL_LEFT, -event_horizontal_factor);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServerAndroid::_wheel_button_click(int event_buttons_mask, const Ref<InputEventMouseButton> &ev, int wheel_button, float factor) {
|
||||
Ref<InputEventMouseButton> evd = ev->duplicate();
|
||||
_set_key_modifier_state(evd);
|
||||
evd->set_button_index(wheel_button);
|
||||
evd->set_button_mask(event_buttons_mask ^ (1 << (wheel_button - 1)));
|
||||
evd->set_factor(factor);
|
||||
Input::get_singleton()->accumulate_input_event(evd);
|
||||
Ref<InputEventMouseButton> evdd = evd->duplicate();
|
||||
evdd->set_pressed(false);
|
||||
evdd->set_button_mask(event_buttons_mask);
|
||||
Input::get_singleton()->accumulate_input_event(evdd);
|
||||
}
|
||||
|
||||
void DisplayServerAndroid::process_double_tap(int event_android_button_mask, Point2 p_pos) {
|
||||
int event_button_mask = _android_button_mask_to_godot_button_mask(event_android_button_mask);
|
||||
Ref<InputEventMouseButton> ev;
|
||||
ev.instance();
|
||||
_set_key_modifier_state(ev);
|
||||
ev->set_position(p_pos);
|
||||
ev->set_global_position(p_pos);
|
||||
ev->set_pressed(false);
|
||||
ev->set_pressed(event_button_mask != 0);
|
||||
ev->set_button_index(_button_index_from_mask(event_button_mask));
|
||||
ev->set_button_mask(event_button_mask);
|
||||
ev->set_doubleclick(true);
|
||||
Input::get_singleton()->parse_input_event(ev);
|
||||
Input::get_singleton()->accumulate_input_event(ev);
|
||||
}
|
||||
|
||||
int DisplayServerAndroid::_button_index_from_mask(int button_mask) {
|
||||
switch (button_mask) {
|
||||
case BUTTON_MASK_LEFT:
|
||||
return BUTTON_LEFT;
|
||||
case BUTTON_MASK_RIGHT:
|
||||
return BUTTON_RIGHT;
|
||||
case BUTTON_MASK_MIDDLE:
|
||||
return BUTTON_MIDDLE;
|
||||
case BUTTON_MASK_XBUTTON1:
|
||||
return BUTTON_XBUTTON1;
|
||||
case BUTTON_MASK_XBUTTON2:
|
||||
return BUTTON_XBUTTON2;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServerAndroid::process_scroll(Point2 p_pos) {
|
||||
@ -679,7 +770,7 @@ void DisplayServerAndroid::process_scroll(Point2 p_pos) {
|
||||
_set_key_modifier_state(ev);
|
||||
ev->set_position(p_pos);
|
||||
ev->set_delta(p_pos - scroll_prev_pos);
|
||||
Input::get_singleton()->parse_input_event(ev);
|
||||
Input::get_singleton()->accumulate_input_event(ev);
|
||||
scroll_prev_pos = p_pos;
|
||||
}
|
||||
|
||||
@ -698,3 +789,32 @@ void DisplayServerAndroid::process_magnetometer(const Vector3 &p_magnetometer) {
|
||||
void DisplayServerAndroid::process_gyroscope(const Vector3 &p_gyroscope) {
|
||||
Input::get_singleton()->set_gyroscope(p_gyroscope);
|
||||
}
|
||||
|
||||
Point2i DisplayServerAndroid::mouse_get_position() const {
|
||||
return hover_prev_pos;
|
||||
}
|
||||
|
||||
int DisplayServerAndroid::mouse_get_button_state() const {
|
||||
return buttons_state;
|
||||
}
|
||||
|
||||
int DisplayServerAndroid::_android_button_mask_to_godot_button_mask(int android_button_mask) {
|
||||
int godot_button_mask = 0;
|
||||
if (android_button_mask & AMOTION_EVENT_BUTTON_PRIMARY) {
|
||||
godot_button_mask |= BUTTON_MASK_LEFT;
|
||||
}
|
||||
if (android_button_mask & AMOTION_EVENT_BUTTON_SECONDARY) {
|
||||
godot_button_mask |= BUTTON_MASK_RIGHT;
|
||||
}
|
||||
if (android_button_mask & AMOTION_EVENT_BUTTON_TERTIARY) {
|
||||
godot_button_mask |= BUTTON_MASK_MIDDLE;
|
||||
}
|
||||
if (android_button_mask & AMOTION_EVENT_BUTTON_BACK) {
|
||||
godot_button_mask |= BUTTON_MASK_XBUTTON1;
|
||||
}
|
||||
if (android_button_mask & AMOTION_EVENT_BUTTON_SECONDARY) {
|
||||
godot_button_mask |= BUTTON_MASK_XBUTTON2;
|
||||
}
|
||||
|
||||
return godot_button_mask;
|
||||
}
|
||||
|
@ -68,6 +68,8 @@ private:
|
||||
bool control_mem = false;
|
||||
bool meta_mem = false;
|
||||
|
||||
int buttons_state;
|
||||
|
||||
bool keep_screen_on;
|
||||
|
||||
Vector<TouchPos> touch;
|
||||
@ -91,6 +93,12 @@ private:
|
||||
|
||||
void _set_key_modifier_state(Ref<InputEventWithModifiers> ev);
|
||||
|
||||
static int _button_index_from_mask(int button_mask);
|
||||
|
||||
static int _android_button_mask_to_godot_button_mask(int android_button_mask);
|
||||
|
||||
void _wheel_button_click(int event_buttons_mask, const Ref<InputEventMouseButton> &ev, int wheel_button, float factor);
|
||||
|
||||
public:
|
||||
static DisplayServerAndroid *get_singleton();
|
||||
|
||||
@ -162,9 +170,10 @@ public:
|
||||
void process_gravity(const Vector3 &p_gravity);
|
||||
void process_magnetometer(const Vector3 &p_magnetometer);
|
||||
void process_gyroscope(const Vector3 &p_gyroscope);
|
||||
void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points);
|
||||
void process_touch(int p_event, int p_pointer, const Vector<TouchPos> &p_points);
|
||||
void process_hover(int p_type, Point2 p_pos);
|
||||
void process_double_tap(Point2 p_pos);
|
||||
void process_mouse_event(int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor = 0, float event_horizontal_factor = 0);
|
||||
void process_double_tap(int event_android_button_mask, Point2 p_pos);
|
||||
void process_scroll(Point2 p_pos);
|
||||
void process_joy_event(JoypadEvent p_event);
|
||||
void process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed);
|
||||
@ -175,6 +184,9 @@ public:
|
||||
|
||||
void reset_window();
|
||||
|
||||
virtual Point2i mouse_get_position() const;
|
||||
virtual int mouse_get_button_state() const;
|
||||
|
||||
DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
|
||||
~DisplayServerAndroid();
|
||||
};
|
||||
|
@ -70,6 +70,7 @@ import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.view.Display;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
@ -854,63 +855,6 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
|
||||
}
|
||||
}
|
||||
|
||||
public boolean gotTouchEvent(final MotionEvent event) {
|
||||
final int evcount = event.getPointerCount();
|
||||
if (evcount == 0)
|
||||
return true;
|
||||
|
||||
if (mRenderView != null) {
|
||||
final int[] arr = new int[event.getPointerCount() * 3];
|
||||
|
||||
for (int i = 0; i < event.getPointerCount(); i++) {
|
||||
arr[i * 3 + 0] = (int)event.getPointerId(i);
|
||||
arr[i * 3 + 1] = (int)event.getX(i);
|
||||
arr[i * 3 + 2] = (int)event.getY(i);
|
||||
}
|
||||
final int pointer_idx = event.getPointerId(event.getActionIndex());
|
||||
|
||||
//System.out.printf("gaction: %d\n",event.getAction());
|
||||
final int action = event.getAction() & MotionEvent.ACTION_MASK;
|
||||
mRenderView.queueOnRenderThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
GodotLib.touch(0, 0, evcount, arr);
|
||||
//System.out.printf("action down at: %f,%f\n", event.getX(),event.getY());
|
||||
} break;
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
GodotLib.touch(1, 0, evcount, arr);
|
||||
/*
|
||||
for(int i=0;i<event.getPointerCount();i++) {
|
||||
System.out.printf("%d - moved to: %f,%f\n",i, event.getX(i),event.getY(i));
|
||||
}
|
||||
*/
|
||||
} break;
|
||||
case MotionEvent.ACTION_POINTER_UP: {
|
||||
GodotLib.touch(4, pointer_idx, evcount, arr);
|
||||
//System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
|
||||
} break;
|
||||
case MotionEvent.ACTION_POINTER_DOWN: {
|
||||
GodotLib.touch(3, pointer_idx, evcount, arr);
|
||||
//System.out.printf("%d - s.down at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
|
||||
} break;
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP: {
|
||||
GodotLib.touch(2, 0, evcount, arr);
|
||||
/*
|
||||
for(int i=0;i<event.getPointerCount();i++) {
|
||||
System.out.printf("%d - up! %f,%f\n",i, event.getX(i),event.getY(i));
|
||||
}
|
||||
*/
|
||||
} break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) {
|
||||
String s = event.getCharacters();
|
||||
if (s == null || s.length() == 0)
|
||||
|
@ -29,7 +29,6 @@
|
||||
/*************************************************************************/
|
||||
|
||||
package org.godotengine.godot;
|
||||
|
||||
import org.godotengine.godot.input.GodotGestureHandler;
|
||||
import org.godotengine.godot.input.GodotInputHandler;
|
||||
import org.godotengine.godot.utils.GLUtils;
|
||||
@ -127,7 +126,7 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
super.onTouchEvent(event);
|
||||
this.detector.onTouchEvent(event);
|
||||
return godot.gotTouchEvent(event);
|
||||
return inputHandler.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -94,17 +94,19 @@ public class GodotLib {
|
||||
/**
|
||||
* Forward touch events from the main thread to the GL thread.
|
||||
*/
|
||||
public static native void touch(int what, int pointer, int howmany, int[] arr);
|
||||
public static native void touch(int inputDevice, int event, int pointer, int pointerCount, float[] positions);
|
||||
public static native void touch(int inputDevice, int event, int pointer, int pointerCount, float[] positions, int buttonsMask);
|
||||
public static native void touch(int inputDevice, int event, int pointer, int pointerCount, float[] positions, int buttonsMask, float verticalFactor, float horizontalFactor);
|
||||
|
||||
/**
|
||||
* Forward hover events from the main thread to the GL thread.
|
||||
*/
|
||||
public static native void hover(int type, int x, int y);
|
||||
public static native void hover(int type, float x, float y);
|
||||
|
||||
/**
|
||||
* Forward double_tap events from the main thread to the GL thread.
|
||||
*/
|
||||
public static native void doubletap(int x, int y);
|
||||
public static native void doubleTap(int buttonMask, int x, int y);
|
||||
|
||||
/**
|
||||
* Forward scroll events from the main thread to the GL thread.
|
||||
|
@ -38,6 +38,7 @@ import org.godotengine.godot.vulkan.VkSurfaceView;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceView;
|
||||
@ -100,22 +101,22 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
super.onTouchEvent(event);
|
||||
mGestureDetector.onTouchEvent(event);
|
||||
return godot.gotTouchEvent(event);
|
||||
return mInputHandler.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(final int keyCode, KeyEvent event) {
|
||||
return mInputHandler.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
|
||||
return mInputHandler.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(final int keyCode, KeyEvent event) {
|
||||
return mInputHandler.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
|
||||
return mInputHandler.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onGenericMotionEvent(MotionEvent event) {
|
||||
return mInputHandler.onGenericMotionEvent(event) || super.onGenericMotionEvent(event);
|
||||
return mInputHandler.onGenericMotionEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -33,7 +33,6 @@ package org.godotengine.godot.input;
|
||||
import org.godotengine.godot.GodotLib;
|
||||
import org.godotengine.godot.GodotRenderView;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
@ -75,10 +74,11 @@ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener
|
||||
//Log.i("GodotGesture", "onDoubleTap");
|
||||
final int x = Math.round(event.getX());
|
||||
final int y = Math.round(event.getY());
|
||||
final int buttonMask = event.getButtonState();
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GodotLib.doubletap(x, y);
|
||||
GodotLib.doubleTap(buttonMask, x, y);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
|
@ -36,6 +36,7 @@ import org.godotengine.godot.GodotLib;
|
||||
import org.godotengine.godot.GodotRenderView;
|
||||
import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener;
|
||||
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.InputDevice.MotionRange;
|
||||
@ -156,6 +157,53 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(final MotionEvent event) {
|
||||
// Mouse drag (mouse pressed and move) doesn't fire onGenericMotionEvent so this is needed
|
||||
if (event.isFromSource(InputDevice.SOURCE_MOUSE)) {
|
||||
if (event.getAction() != MotionEvent.ACTION_MOVE) {
|
||||
// we return true because every time a mouse event is fired, the event is already handled
|
||||
// in onGenericMotionEvent, so by touch event we can say that the event is also handled
|
||||
return true;
|
||||
}
|
||||
return handleMouseEvent(event);
|
||||
}
|
||||
|
||||
final int evcount = event.getPointerCount();
|
||||
if (evcount == 0)
|
||||
return true;
|
||||
|
||||
if (mRenderView != null) {
|
||||
final float[] arr = new float[event.getPointerCount() * 3]; // pointerId1, x1, y1, pointerId2, etc...
|
||||
|
||||
for (int i = 0; i < event.getPointerCount(); i++) {
|
||||
arr[i * 3 + 0] = event.getPointerId(i);
|
||||
arr[i * 3 + 1] = event.getX(i);
|
||||
arr[i * 3 + 2] = event.getY(i);
|
||||
}
|
||||
final int action = event.getActionMasked();
|
||||
|
||||
mRenderView.queueOnRenderThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
GodotLib.touch(event.getSource(), action, 0, evcount, arr);
|
||||
} break;
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
case MotionEvent.ACTION_POINTER_DOWN: {
|
||||
int pointer_idx = event.getPointerId(event.getActionIndex());
|
||||
GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onGenericMotionEvent(MotionEvent event) {
|
||||
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
final int device_id = findJoystickDevice(event.getDeviceId());
|
||||
@ -189,8 +237,8 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
return true;
|
||||
}
|
||||
} else if ((event.getSource() & InputDevice.SOURCE_STYLUS) == InputDevice.SOURCE_STYLUS) {
|
||||
final int x = Math.round(event.getX());
|
||||
final int y = Math.round(event.getY());
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
final int type = event.getAction();
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
@ -199,6 +247,10 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
}
|
||||
});
|
||||
return true;
|
||||
} else if ((event.getSource() & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
return handleMouseEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -366,4 +418,53 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private boolean handleMouseEvent(final MotionEvent event) {
|
||||
switch (event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_HOVER_ENTER:
|
||||
case MotionEvent.ACTION_HOVER_MOVE:
|
||||
case MotionEvent.ACTION_HOVER_EXIT: {
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
final int type = event.getAction();
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GodotLib.hover(type, x, y);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
case MotionEvent.ACTION_BUTTON_PRESS:
|
||||
case MotionEvent.ACTION_BUTTON_RELEASE:
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
final int buttonsMask = event.getButtonState();
|
||||
final int action = event.getAction();
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
case MotionEvent.ACTION_SCROLL: {
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
final int buttonsMask = event.getButtonState();
|
||||
final int action = event.getAction();
|
||||
final float verticalFactor = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
|
||||
final float horizontalFactor = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask, verticalFactor, horizontalFactor);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "string_android.h"
|
||||
#include "thread_jandroid.h"
|
||||
|
||||
#include <android/input.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <android/native_window_jni.h>
|
||||
@ -237,40 +238,51 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint count, jintArray positions) {
|
||||
void touch_preprocessing(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask, jfloat vertical_factor, jfloat horizontal_factor) {
|
||||
if (step == 0)
|
||||
return;
|
||||
|
||||
Vector<DisplayServerAndroid::TouchPos> points;
|
||||
for (int i = 0; i < count; i++) {
|
||||
jint p[3];
|
||||
env->GetIntArrayRegion(positions, i * 3, 3, p);
|
||||
for (int i = 0; i < pointer_count; i++) {
|
||||
jfloat p[3];
|
||||
env->GetFloatArrayRegion(positions, i * 3, 3, p);
|
||||
DisplayServerAndroid::TouchPos tp;
|
||||
tp.pos = Point2(p[1], p[2]);
|
||||
tp.id = p[0];
|
||||
tp.id = (int)p[0];
|
||||
points.push_back(tp);
|
||||
}
|
||||
|
||||
DisplayServerAndroid::get_singleton()->process_touch(ev, pointer, points);
|
||||
|
||||
/*
|
||||
if (os_android)
|
||||
os_android->process_touch(ev,pointer,points);
|
||||
*/
|
||||
if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE) {
|
||||
DisplayServerAndroid::get_singleton()->process_mouse_event(ev, buttons_mask, points[0].pos, vertical_factor, horizontal_factor);
|
||||
} else {
|
||||
DisplayServerAndroid::get_singleton()->process_touch(ev, pointer, points);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jclass clazz, jint p_type, jint p_x, jint p_y) {
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3F(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray position) {
|
||||
touch_preprocessing(env, clazz, input_device, ev, pointer, pointer_count, position);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FI(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray position, jint buttons_mask) {
|
||||
touch_preprocessing(env, clazz, input_device, ev, pointer, pointer_count, position, buttons_mask);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FIFF(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray position, jint buttons_mask, jfloat vertical_factor, jfloat horizontal_factor) {
|
||||
touch_preprocessing(env, clazz, input_device, ev, pointer, pointer_count, position, buttons_mask, vertical_factor, horizontal_factor);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jclass clazz, jint p_type, jfloat p_x, jfloat p_y) {
|
||||
if (step == 0)
|
||||
return;
|
||||
|
||||
DisplayServerAndroid::get_singleton()->process_hover(p_type, Point2(p_x, p_y));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubletap(JNIEnv *env, jclass clazz, jint p_x, jint p_y) {
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubleTap(JNIEnv *env, jclass clazz, jint p_button_mask, jint p_x, jint p_y) {
|
||||
if (step == 0)
|
||||
return;
|
||||
|
||||
DisplayServerAndroid::get_singleton()->process_double_tap(Point2(p_x, p_y));
|
||||
DisplayServerAndroid::get_singleton()->process_double_tap(p_button_mask, Point2(p_x, p_y));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y) {
|
||||
|
@ -44,9 +44,12 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, j
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface, jboolean p_32_bits);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jclass clazz);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jclass clazz);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint count, jintArray positions);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jclass clazz, jint p_type, jint p_x, jint p_y);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubletap(JNIEnv *env, jclass clazz, jint p_x, jint p_y);
|
||||
void touch_preprocessing(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask = 0, jfloat vertical_factor = 0, jfloat horizontal_factor = 0);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3F(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FI(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FIFF(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask, jfloat vertical_factor, jfloat horizontal_factor);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jclass clazz, jint p_type, jfloat p_x, jfloat p_y);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubleTap(JNIEnv *env, jclass clazz, jint p_button_mask, jint p_x, jint p_y);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_scancode, jint p_unicode_char, jboolean p_pressed);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed);
|
||||
|
@ -153,6 +153,7 @@ void OS_Android::main_loop_begin() {
|
||||
bool OS_Android::main_loop_iterate() {
|
||||
if (!main_loop)
|
||||
return false;
|
||||
DisplayServerAndroid::get_singleton()->process_events();
|
||||
return Main::iteration();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user