api-impl{-jni}: make view.onTouchEvent work, misc stuff to make input work for Unity games

onTouchEvent was previously incorrectly handled in GLSurfaceView; move it
to View so that it works properly with any of it's descendants.

This is done by reusing the existing setOnTouchListener implementation
and changing it to use GtkEventControllerLegacy which provides motion
events.

Technically some of the code is in WrapperWidget.c since every widget
calls wrapper_widget_set_jobject and we already have related code
there.
This commit is contained in:
Mis012
2023-10-17 21:33:59 +02:00
parent 58fa4b5590
commit 4a0755c6e0
14 changed files with 154 additions and 127 deletions

View File

@@ -210,10 +210,10 @@ JNIEXPORT jlong JNICALL Java_android_opengl_GLSurfaceView_native_1constructor
/*
* Class: android_opengl_GLSurfaceView
* Method: native_set_renderer
* Signature: (Landroid/opengl/GLSurfaceView/Renderer;Z)V
* Signature: (Landroid/opengl/GLSurfaceView/Renderer;)V
*/
JNIEXPORT void JNICALL Java_android_opengl_GLSurfaceView_native_1set_1renderer
(JNIEnv *, jobject, jobject, jboolean);
(JNIEnv *, jobject, jobject);
#ifdef __cplusplus
}

View File

@@ -421,14 +421,6 @@ JNIEXPORT jlong JNICALL Java_android_view_MotionEvent_nativeGetEventTimeNanos
JNIEXPORT jfloat JNICALL Java_android_view_MotionEvent_nativeGetRawAxisValue
(JNIEnv *, jclass, jint, jint, jint, jint);
/*
* Class: android_view_MotionEvent
* Method: nativeGetAxisValue
* Signature: (IIII)F
*/
JNIEXPORT jfloat JNICALL Java_android_view_MotionEvent_nativeGetAxisValue
(JNIEnv *, jclass, jint, jint, jint, jint);
/*
* Class: android_view_MotionEvent
* Method: nativeGetPointerCoords

View File

@@ -125,6 +125,7 @@ void set_up_handle_cache(JNIEnv *env)
handle_cache.view.getScrollX = _METHOD(handle_cache.view.class, "getScrollX", "()I");
handle_cache.view.getScrollY = _METHOD(handle_cache.view.class, "getScrollY", "()I");
handle_cache.view.performClick = _METHOD(handle_cache.view.class, "performClick", "()Z");
handle_cache.view.onTouchEvent = _METHOD(handle_cache.view.class, "onTouchEvent", "(Landroid/view/MotionEvent;)Z");
handle_cache.asset_manager.class = _REF((*env)->FindClass(env, "android/content/res/AssetManager"));
handle_cache.asset_manager.extractFromAPK = _STATIC_METHOD(handle_cache.asset_manager.class, "extractFromAPK", "(Ljava/lang/String;Ljava/lang/String;)V");

View File

@@ -81,6 +81,7 @@ struct handle_cache {
jmethodID getScrollX;
jmethodID getScrollY;
jmethodID performClick;
jmethodID onTouchEvent;
} view;
struct {
jclass class;

View File

@@ -7,33 +7,73 @@
#include "../generated_headers/android_view_View.h"
#define SOURCE_TOUCHSCREEN 4098
#define SOURCE_TOUCHSCREEN 0x1002
struct touch_callback_data { JavaVM *jvm; jobject this; jobject on_touch_listener; jclass on_touch_listener_class; };
struct touch_callback_data { JavaVM *jvm; jobject this; jobject on_touch_listener; jclass on_touch_listener_class; unsigned int num_clicks};
static void call_ontouch_callback(int action, float x, float y, struct touch_callback_data *d)
static void call_ontouch_callback(int action, double x, double y, struct touch_callback_data *d)
{
JNIEnv *env;
(*d->jvm)->GetEnv(d->jvm, (void**)&env, JNI_VERSION_1_6);
jobject motion_event = (*env)->NewObject(env, handle_cache.motion_event.class, handle_cache.motion_event.constructor, SOURCE_TOUCHSCREEN, action, x, y);
jobject motion_event = (*env)->NewObject(env, handle_cache.motion_event.class, handle_cache.motion_event.constructor, SOURCE_TOUCHSCREEN, action, (float)x, (float)y);
/* NULL listener means the callback was registered for onTouchEvent */
if(d->on_touch_listener)
(*env)->CallBooleanMethod(env, d->on_touch_listener, _METHOD(d->on_touch_listener_class, "onTouch", "(Landroid/view/View;Landroid/view/MotionEvent;)Z"), d->this, motion_event);
else
(*env)->CallBooleanMethod(env, d->this, _METHOD(d->on_touch_listener_class, "onTouchEvent", "(Landroid/view/MotionEvent;)Z"), motion_event);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
(*env)->DeleteLocalRef(env, motion_event);
}
static void on_press(GtkGestureClick *gesture, int n_press, double x, double y, struct touch_callback_data *d)
static void gdk_event_get_widget_relative_position(GdkEvent *event, GtkWidget *widget, double *x, double *y)
{
call_ontouch_callback(MOTION_EVENT_ACTION_DOWN, (float)x, (float)y, d);
double off_x;
double off_y;
gdk_event_get_position(event, x, y);
GtkWidget *window = GTK_WIDGET(gtk_widget_get_native(widget));
gtk_native_get_surface_transform(GTK_NATIVE(window), &off_x, &off_y);
gtk_widget_translate_coordinates(window, widget, *x - off_x, *y - off_y, x, y);
}
static void on_release(GtkGestureClick *gesture, int n_press, double x, double y, struct touch_callback_data *d)
// TODO: find a way to reconcile this with libandroid/input.c?
static gboolean on_event(GtkEventControllerLegacy *event_controller, GdkEvent *event, struct touch_callback_data *d)
{
call_ontouch_callback(MOTION_EVENT_ACTION_UP, (float)x, (float)y, d);
double x;
double y;
GtkWidget *widget = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(event_controller));
// TODO: this doesn't work for multitouch
switch(gdk_event_get_event_type(event)) {
case GDK_BUTTON_PRESS:
d->num_clicks = 1;
case GDK_TOUCH_BEGIN:
gdk_event_get_widget_relative_position(event, widget, &x, &y);
call_ontouch_callback(MOTION_EVENT_ACTION_DOWN, x, y, d);
break;
case GDK_BUTTON_RELEASE:
d->num_clicks = 0;
case GDK_TOUCH_END:
gdk_event_get_widget_relative_position(event, widget, &x, &y);
call_ontouch_callback(MOTION_EVENT_ACTION_UP, x, y, d);
break;
case GDK_MOTION_NOTIFY:
if(d->num_clicks == 0)
break;
case GDK_TOUCH_UPDATE:
printf("d->num_clicks: %u\n", d->num_clicks);
gdk_event_get_widget_relative_position(event, widget, &x, &y);
call_ontouch_callback(MOTION_EVENT_ACTION_MOVE, x, y, d);
break;
default:
break;
}
return true;
}
static void on_click(GtkGestureClick *gesture, int n_press, double x, double y, struct touch_callback_data *d)
@@ -47,26 +87,33 @@ static void on_click(GtkGestureClick *gesture, int n_press, double x, double y,
(*env)->ExceptionDescribe(env);
}
JNIEXPORT void JNICALL Java_android_view_View_setOnTouchListener(JNIEnv *env, jobject this, jobject on_touch_listener)
void _setOnTouchListener(JNIEnv *env, jobject this, GtkWidget *widget, jobject on_touch_listener)
{
GtkWidget *widget = GTK_WIDGET(_PTR(_GET_LONG_FIELD(this, "widget")));
JavaVM *jvm;
(*env)->GetJavaVM(env, &jvm);
struct touch_callback_data *callback_data = malloc(sizeof(struct touch_callback_data));
callback_data->jvm = jvm;
callback_data->this = _REF(this);
callback_data->on_touch_listener = _REF(on_touch_listener);
callback_data->on_touch_listener_class = _REF(_CLASS(callback_data->on_touch_listener));
callback_data->on_touch_listener = on_touch_listener ? _REF(on_touch_listener) : NULL;
callback_data->on_touch_listener_class = on_touch_listener ? _REF(_CLASS(callback_data->on_touch_listener)) : _REF(_CLASS(callback_data->this));
callback_data->num_clicks = 0;
GtkEventController *controller = GTK_EVENT_CONTROLLER(gtk_gesture_click_new());
GtkEventController *controller = GTK_EVENT_CONTROLLER(gtk_event_controller_legacy_new());
gtk_event_controller_set_name(controller, "the Java_android_view_View_setOnTouchListener one");
gtk_event_controller_set_propagation_phase(controller, GTK_PHASE_CAPTURE); // FIXME?
g_signal_connect(controller, "pressed", G_CALLBACK(on_press), callback_data);
g_signal_connect(controller, "released", G_CALLBACK(on_release), callback_data);
g_signal_connect(controller, "event", G_CALLBACK(on_event), callback_data);
gtk_widget_add_controller(widget, controller);
}
JNIEXPORT void JNICALL Java_android_view_View_setOnTouchListener(JNIEnv *env, jobject this, jobject on_touch_listener)
{
GtkWidget *widget = GTK_WIDGET(_PTR(_GET_LONG_FIELD(this, "widget")));
_setOnTouchListener(env, this, widget, on_touch_listener);
}
JNIEXPORT void JNICALL Java_android_view_View_setOnClickListener(JNIEnv *env, jobject this, jobject on_click_listener)
{
GtkWidget *widget = GTK_WIDGET(_PTR(_GET_LONG_FIELD(this, "widget")));
@@ -81,6 +128,7 @@ JNIEXPORT void JNICALL Java_android_view_View_setOnClickListener(JNIEnv *env, jo
callback_data->this = _REF(this);
callback_data->on_touch_listener = _REF(on_click_listener);
callback_data->on_touch_listener_class = _REF(_CLASS(callback_data->on_touch_listener));
callback_data->num_clicks = 0;
GtkEventController *controller = GTK_EVENT_CONTROLLER(gtk_gesture_click_new());
@@ -198,11 +246,12 @@ JNIEXPORT void JNICALL Java_android_view_View_setVisibility(JNIEnv *env, jobject
JNIEXPORT jlong JNICALL Java_android_view_View_native_1constructor(JNIEnv *env, jobject this, jobject context, jobject attrs)
{
GtkWidget *wrapper = g_object_ref(wrapper_widget_new());
GtkWidget *area = gtk_drawing_area_new();
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), area);
// FIXME: we don't really care all that much what this is, since drawing into empty widgets is done by WrapperWidget, but a drawing area is just confusing
GtkWidget *widget = gtk_drawing_area_new();
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), widget);
wrapper_widget_set_jobject(WRAPPER_WIDGET(wrapper), env, this);
return _INTPTR(area);
return _INTPTR(widget);
}
JNIEXPORT void JNICALL Java_android_view_View_nativeInvalidate(JNIEnv *env, jclass, jlong widget_ptr) {

View File

@@ -5,6 +5,8 @@
#include "../sk_area/sk_area.h"
#include "../generated_headers/android_view_View.h"
#include "WrapperWidget.h"
G_DEFINE_TYPE(WrapperWidget, wrapper_widget, GTK_TYPE_WIDGET)
@@ -122,4 +124,10 @@ void wrapper_widget_set_jobject(WrapperWidget *wrapper, JNIEnv *env, jobject job
// add a callback for when the widget is mapped, which will call onMeasure to figure out what size the widget wants to be
g_signal_connect(wrapper, "map", G_CALLBACK(on_mapped), NULL);
}
jmethodID ontouchevent_method = _METHOD(_CLASS(jobj), "onTouchEvent", "(Landroid/view/MotionEvent;)Z");
if (ontouchevent_method != handle_cache.view.onTouchEvent) {
/* use gtk_widget_get_first_child since the jobject may not have the "widget" variable set yet */
_setOnTouchListener(env, jobj, gtk_widget_get_first_child(wrapper), NULL);
}
}

View File

@@ -62,6 +62,7 @@ JNIEXPORT jlong JNICALL Java_android_opengl_GLSurfaceView_native_1constructor(JN
gtk_widget_set_vexpand(wrapper, TRUE);
GtkWidget *gl_area = gtk_gl_area_new();
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), gl_area);
wrapper_widget_set_jobject(WRAPPER_WIDGET(wrapper), env, this);
return _INTPTR(gl_area);
}
@@ -460,54 +461,9 @@ check_gl_error();
return TRUE;
}
struct jni_callback_data { JavaVM *jvm; jobject this; jclass this_class; };
static void call_ontouch_callback(GtkEventControllerLegacy* event_controller, int action, double x, double y, struct jni_callback_data *d)
{
JNIEnv *env;
(*d->jvm)->GetEnv(d->jvm, (void**)&env, JNI_VERSION_1_6);
// execute the Java callback function
jobject motion_event = (*env)->NewObject(env, handle_cache.motion_event.class, handle_cache.motion_event.constructor, SOURCE_TOUCHSCREEN, action, (float)x, (float)y);
(*env)->CallBooleanMethod(env, d->this, handle_cache.gl_surface_view.onTouchEvent, motion_event);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
(*env)->DeleteLocalRef(env, motion_event);
}
// TODO: find a way to reconcile this with libandroid/input.c
static gboolean on_event(GtkEventControllerLegacy* self, GdkEvent* event, struct jni_callback_data *d)
{
double x;
double y;
// TODO: this doesn't work for multitouch
switch(gdk_event_get_event_type(event)) {
case GDK_BUTTON_PRESS:
case GDK_TOUCH_BEGIN:
gdk_event_get_position(event, &x, &y);
call_ontouch_callback(self, MOTION_EVENT_ACTION_DOWN, x, y, d);
break;
case GDK_BUTTON_RELEASE:
case GDK_TOUCH_END:
gdk_event_get_position(event, &x, &y);
call_ontouch_callback(self, MOTION_EVENT_ACTION_UP, x, y, d);
break;
case GDK_MOTION_NOTIFY:
case GDK_TOUCH_UPDATE:
gdk_event_get_position(event, &x, &y);
call_ontouch_callback(self, MOTION_EVENT_ACTION_MOVE, x, y, d);
break;
}
}
extern gboolean tick_callback(GtkWidget* widget, GdkFrameClock* frame_clock, gpointer user_data);
JNIEXPORT void JNICALL Java_android_opengl_GLSurfaceView_native_1set_1renderer(JNIEnv *env, jobject this, jobject renderer, jboolean implements_onTouchEvent)
JNIEXPORT void JNICALL Java_android_opengl_GLSurfaceView_native_1set_1renderer(JNIEnv *env, jobject this, jobject renderer)
{
GtkWidget *gl_area = GTK_WIDGET(_PTR(_GET_LONG_FIELD(this, "widget")));
@@ -535,21 +491,6 @@ JNIEXPORT void JNICALL Java_android_opengl_GLSurfaceView_native_1set_1renderer(J
g_signal_connect(gl_area, "render", G_CALLBACK(render), gl_callback_data);
g_signal_connect(gl_area, "realize", G_CALLBACK(on_realize), gl_callback_data);
if(implements_onTouchEvent) {
struct jni_callback_data *callback_data = malloc(sizeof(struct jni_callback_data));
callback_data->jvm = jvm;
callback_data->this = _REF(this);
callback_data->this_class = _REF(_CLASS(this));
printf("callback_data->jvm: %p\n", callback_data->jvm);
GtkEventController *controller = gtk_event_controller_legacy_new();
gtk_widget_add_controller(gl_area, controller);
g_signal_connect(controller, "event", G_CALLBACK(on_event), callback_data);
printf("GREP FOR MEEEE -- //FIXME\n");
}
gtk_widget_add_tick_callback(gl_area, tick_callback, NULL, NULL);
//FIXME

View File

@@ -78,6 +78,7 @@ JNIEXPORT jlong JNICALL Java_android_widget_FrameLayout_native_1constructor(JNIE
GtkWidget *wrapper = g_object_ref(wrapper_widget_new());
GtkWidget *frame_layout = frame_layout_widget_new();
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), frame_layout);
wrapper_widget_set_jobject(WRAPPER_WIDGET(wrapper), env, this);
gtk_widget_set_name(GTK_WIDGET(frame_layout), "FrameLayout");
return _INTPTR(frame_layout);
}

View File

@@ -362,6 +362,11 @@ public class Context extends Object {
public boolean bindService(Intent intent, ServiceConnection serviceConnection, int dummy3) {
try {
if(intent.getComponent() == null) {
Slog.w(TAG, "Context.bindService: intent.getComponent() is null");
return false; // maybe?
}
Class<? extends Service> cls = Class.forName(intent.getComponent().getClassName()).asSubclass(Service.class);
if (!runningServices.containsKey(cls)) {
Service service = cls.getConstructor().newInstance();

View File

@@ -32,6 +32,7 @@ import android.os.Environment;
import android.os.UserHandle;
import android.util.AndroidException;
import android.util.DisplayMetrics;
import android.util.Slog;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -57,6 +58,8 @@ class Drawable {}
*/
public class PackageManager {
private final static String TAG = "PackageManager";
/**
* This exception is thrown when a given package, application, or component
* name cannot be found.
@@ -2131,6 +2134,7 @@ public class PackageManager {
* false.
*/
public boolean hasSystemFeature(String name) {
Slog.e(TAG, "!!!!!!! hasSystemFeature: case >" + name + "< is not implemented yet");
return false; // FIXME
}

View File

@@ -42,10 +42,6 @@ public class GLSurfaceView extends View implements SurfaceHolder.Callback { // T
// TODO: make use of this
public void onResume() {}
public boolean onTouchEvent(MotionEvent event) {
return true;
}
public void setEGLConfigChooser(EGLConfigChooser chooser) {
config_chooser = chooser;
}
@@ -74,22 +70,12 @@ public class GLSurfaceView extends View implements SurfaceHolder.Callback { // T
return false;
}
private native void native_set_renderer(Renderer renderer, boolean implements_onTouchEvent);
private native void native_set_renderer(Renderer renderer);
public void setRenderer(Renderer renderer) {
System.out.println("setRenderer(" + renderer + ") called");
boolean implements_onTouchEvent;
try {
Class[] cArg = new Class[1];
cArg[0] = MotionEvent.class;
implements_onTouchEvent = !(this.getClass().getMethod("onTouchEvent", cArg).getDeclaringClass() == View.class);
} catch (NoSuchMethodException e) {
implements_onTouchEvent = false;
}
native_set_renderer(renderer, implements_onTouchEvent);
native_set_renderer(renderer);
/* checkRenderThreadState();
if (mEGLConfigChooser == null) {
mEGLConfigChooser = new SimpleEGLConfigChooser(true);

View File

@@ -6,9 +6,11 @@ import java.util.ArrayList;
public class InputDevice {
public static final int SOURCE_CLASS_BUTTON = 0x00000001;
public static final int SOURCE_CLASS_POINTER = 0x00000002;
public static final int SOURCE_CLASS_JOYSTICK = 0x00000010;
public static final int SOURCE_CLASS_GAMEPAD = 0x00000400 | SOURCE_CLASS_BUTTON;
public static final int SOURCE_KEYBOARD = 0x00000100 | SOURCE_CLASS_BUTTON;
public static final int SOURCE_TOUCHSCREEN = 0x00001000 | SOURCE_CLASS_POINTER;
public static int[] getDeviceIds() {
@@ -19,8 +21,32 @@ public class InputDevice {
return new InputDevice();
}
public int getId() {
return 0; // might work?
}
public int getProductId() {
return 0x69;
}
public int getVendorId() {
return 0x420;
}
public String getName() {
return "FIXME-name";
}
public String getDescriptor() {
return "FIXME-descriptor";
}
public boolean isVirtual() {
return false;
}
public int getSources() {
return 0; // FIXME
return 2 | 4098 /* SOURCE_CLASS_POINTER | SOURCE_TOUCHSCREEN */; // FIXME
}
/*

View File

@@ -1353,8 +1353,10 @@ public final class MotionEvent extends InputEvent {
private static native long nativeGetEventTimeNanos(int nativePtr, int historyPos);
private static native float nativeGetRawAxisValue(int nativePtr,
int axis, int pointerIndex, int historyPos);
private static native float nativeGetAxisValue(int nativePtr,
int axis, int pointerIndex, int historyPos);
private static /*native*/ float nativeGetAxisValue(int nativePtr, int axis, int pointerIndex, int historyPos) {
try { throw new Exception(); } catch(Exception e) { e.printStackTrace(); System.exit(69); }
return 0;
}
private static native void nativeGetPointerCoords(int nativePtr,
int pointerIndex, int historyPos, PointerCoords outPointerCoords);
private static native void nativeGetPointerProperties(int nativePtr,
@@ -1620,6 +1622,7 @@ public final class MotionEvent extends InputEvent {
}
MotionEvent ev = obtain();
ev.source = other.source;
ev.action = other.action;
ev.coord_x = other.coord_x;
ev.coord_y = other.coord_y;
@@ -1739,7 +1742,7 @@ public final class MotionEvent extends InputEvent {
* @return The index associated with the action.
*/
public final int getActionIndex() {
return 1;
return 0; // FIXME
}
/**
@@ -1810,7 +1813,7 @@ public final class MotionEvent extends InputEvent {
*/
@Override
public final long getEventTime() {
return nativeGetEventTimeNanos(mNativePtr, HISTORY_CURRENT) / NS_PER_MS;
return System.currentTimeMillis();
}
/**
@@ -1829,7 +1832,7 @@ public final class MotionEvent extends InputEvent {
*/
@Override
public final long getEventTimeNano() {
return nativeGetEventTimeNanos(mNativePtr, HISTORY_CURRENT);
return System.currentTimeMillis() * 1000; // FIXME
}
/**
@@ -1975,7 +1978,8 @@ public final class MotionEvent extends InputEvent {
* @see #TOOL_TYPE_MOUSE
*/
public final int getToolType(int pointerIndex) {
return nativeGetToolType(mNativePtr, pointerIndex);
return 0x1; // TOOL_TYPE_FINGER
// return nativeGetToolType(mNativePtr, pointerIndex);
}
/**
@@ -2053,7 +2057,8 @@ public final class MotionEvent extends InputEvent {
* @see #AXIS_SIZE
*/
public final float getSize(int pointerIndex) {
return nativeGetAxisValue(mNativePtr, AXIS_SIZE, pointerIndex, HISTORY_CURRENT);
return 1; // arbitrary
// return nativeGetAxisValue(mNativePtr, AXIS_SIZE, pointerIndex, HISTORY_CURRENT);
}
/**
@@ -2067,7 +2072,8 @@ public final class MotionEvent extends InputEvent {
* @see #AXIS_TOUCH_MAJOR
*/
public final float getTouchMajor(int pointerIndex) {
return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MAJOR, pointerIndex, HISTORY_CURRENT);
return 2.5f; // arbitrary
// return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MAJOR, pointerIndex, HISTORY_CURRENT);
}
/**
@@ -2081,7 +2087,8 @@ public final class MotionEvent extends InputEvent {
* @see #AXIS_TOUCH_MINOR
*/
public final float getTouchMinor(int pointerIndex) {
return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MINOR, pointerIndex, HISTORY_CURRENT);
return 2.5f; // arbitrary
// return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MINOR, pointerIndex, HISTORY_CURRENT);
}
/**
@@ -2132,7 +2139,8 @@ public final class MotionEvent extends InputEvent {
* @see #AXIS_ORIENTATION
*/
public final float getOrientation(int pointerIndex) {
return nativeGetAxisValue(mNativePtr, AXIS_ORIENTATION, pointerIndex, HISTORY_CURRENT);
return 0; // arbitrary
// return nativeGetAxisValue(mNativePtr, AXIS_ORIENTATION, pointerIndex, HISTORY_CURRENT);
}
/**
@@ -2268,7 +2276,8 @@ public final class MotionEvent extends InputEvent {
* @return Returns the number of historical points in the event.
*/
public final int getHistorySize() {
return nativeGetHistorySize(mNativePtr);
return 0;
// return nativeGetHistorySize(mNativePtr);
}
/**
@@ -3008,17 +3017,17 @@ public final class MotionEvent extends InputEvent {
msg.append(", id[").append(i).append("]=").append(getPointerId(i));
msg.append(", x[").append(i).append("]=").append(getX(i));
msg.append(", y[").append(i).append("]=").append(getY(i));
msg.append(", toolType[").append(i).append("]=").append(toolTypeToString(getToolType(i)));
msg.append(", toolType[").append(i).append("]=").append(/*toolTypeToString(getToolType(i))*/ "FIXME");
}
msg.append(", buttonState=").append(MotionEvent.buttonStateToString(getButtonState()));
msg.append(", buttonState=").append(/*MotionEvent.buttonStateToString(getButtonState())*/ "FIXME");
msg.append(", metaState=").append(/*KeyEvent.metaStateToString(getMetaState())*/ "FIXME");
msg.append(", flags=0x").append(Integer.toHexString(getFlags()));
msg.append(", edgeFlags=0x").append(Integer.toHexString(getEdgeFlags()));
msg.append(", flags=0x").append(/*Integer.toHexString(getFlags())*/ "FIXME");
msg.append(", edgeFlags=0x").append(/*Integer.toHexString(getEdgeFlags())*/ "FIXME");
msg.append(", pointerCount=").append(pointerCount);
msg.append(", historySize=").append(getHistorySize());
msg.append(", eventTime=").append(getEventTime());
msg.append(", downTime=").append(getDownTime());
msg.append(", historySize=").append(/*getHistorySize()*/ "FIXME");
msg.append(", eventTime=").append(/*getEventTime()*/ "FIXME");
msg.append(", downTime=").append(/*getDownTime()*/ "FIXME");
msg.append(", deviceId=").append(getDeviceId());
msg.append(", source=0x").append(Integer.toHexString(getSource()));
msg.append(" }");

View File

@@ -874,6 +874,10 @@ public class View extends Object {
this.gravity = gravity;
}
public boolean onTouchEvent(MotionEvent event) {
return true;
}
public native void setOnTouchListener(OnTouchListener l);
public native void setOnClickListener(OnClickListener l);
public /*native*/ void setOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener l) {}