mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 603008 - Android widget multitouch implementation. r=blassey,kats
This commit is contained in:
parent
3627f3a4b8
commit
a02904d162
@ -148,6 +148,7 @@ MOZ_SPELLCHECK = @MOZ_SPELLCHECK@
|
|||||||
MOZ_ANDROID_HISTORY = @MOZ_ANDROID_HISTORY@
|
MOZ_ANDROID_HISTORY = @MOZ_ANDROID_HISTORY@
|
||||||
MOZ_WEBSMS_BACKEND = @MOZ_WEBSMS_BACKEND@
|
MOZ_WEBSMS_BACKEND = @MOZ_WEBSMS_BACKEND@
|
||||||
MOZ_JAVA_COMPOSITOR = @MOZ_JAVA_COMPOSITOR@
|
MOZ_JAVA_COMPOSITOR = @MOZ_JAVA_COMPOSITOR@
|
||||||
|
MOZ_ONLY_TOUCH_EVENTS = @MOZ_ONLY_TOUCH_EVENTS@
|
||||||
MOZ_TOUCH = @MOZ_TOUCH@
|
MOZ_TOUCH = @MOZ_TOUCH@
|
||||||
MOZ_PROFILELOCKING = @MOZ_PROFILELOCKING@
|
MOZ_PROFILELOCKING = @MOZ_PROFILELOCKING@
|
||||||
MOZ_FEEDS = @MOZ_FEEDS@
|
MOZ_FEEDS = @MOZ_FEEDS@
|
||||||
|
@ -1790,4 +1790,7 @@ public class GeckoAppShell
|
|||||||
public static void disableNetworkNotifications() {
|
public static void disableNetworkNotifications() {
|
||||||
GeckoNetworkManager.getInstance().disableNotifications();
|
GeckoNetworkManager.getInstance().disableNotifications();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is only used in Native Fennec.
|
||||||
|
public static void preventPanning() { }
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ import android.widget.*;
|
|||||||
import android.hardware.*;
|
import android.hardware.*;
|
||||||
import android.location.*;
|
import android.location.*;
|
||||||
import android.util.FloatMath;
|
import android.util.FloatMath;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@ -101,7 +102,12 @@ public class GeckoEvent {
|
|||||||
public int mType;
|
public int mType;
|
||||||
public int mAction;
|
public int mAction;
|
||||||
public long mTime;
|
public long mTime;
|
||||||
public Point mP0, mP1, mP2;
|
public Point[] mPoints;
|
||||||
|
public int[] mPointIndicies;
|
||||||
|
public int mPointerIndex;
|
||||||
|
public float[] mOrientations;
|
||||||
|
public float[] mPressures;
|
||||||
|
public Point[] mPointRadii;
|
||||||
public Rect mRect;
|
public Rect mRect;
|
||||||
public double mX, mY, mZ;
|
public double mX, mY, mZ;
|
||||||
public double mAlpha, mBeta, mGamma;
|
public double mAlpha, mBeta, mGamma;
|
||||||
@ -144,10 +150,76 @@ public class GeckoEvent {
|
|||||||
mAction = m.getAction();
|
mAction = m.getAction();
|
||||||
mTime = m.getEventTime();
|
mTime = m.getEventTime();
|
||||||
mMetaState = m.getMetaState();
|
mMetaState = m.getMetaState();
|
||||||
mP0 = new Point((int)m.getX(0), (int)m.getY(0));
|
|
||||||
|
switch (mAction & MotionEvent.ACTION_MASK) {
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
case MotionEvent.ACTION_POINTER_UP:
|
||||||
|
case MotionEvent.ACTION_POINTER_DOWN:
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
case MotionEvent.ACTION_MOVE: {
|
||||||
mCount = m.getPointerCount();
|
mCount = m.getPointerCount();
|
||||||
if (mCount > 1)
|
mPoints = new Point[mCount];
|
||||||
mP1 = new Point((int)m.getX(1), (int)m.getY(1));
|
mPointIndicies = new int[mCount];
|
||||||
|
mOrientations = new float[mCount];
|
||||||
|
mPressures = new float[mCount];
|
||||||
|
mPointRadii = new Point[mCount];
|
||||||
|
mPointerIndex = (mAction & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||||
|
for (int i = 0; i < mCount; i++) {
|
||||||
|
addMotionPoint(i, i, m);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
mCount = 0;
|
||||||
|
mPointerIndex = -1;
|
||||||
|
mPoints = new Point[mCount];
|
||||||
|
mPointIndicies = new int[mCount];
|
||||||
|
mOrientations = new float[mCount];
|
||||||
|
mPressures = new float[mCount];
|
||||||
|
mPointRadii = new Point[mCount];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMotionPoint(int index, int eventIndex, MotionEvent event) {
|
||||||
|
PointF geckoPoint = new PointF(event.getX(eventIndex), event.getY(eventIndex));
|
||||||
|
|
||||||
|
mPoints[index] = new Point((int)Math.round(geckoPoint.x), (int)Math.round(geckoPoint.y));
|
||||||
|
mPointIndicies[index] = event.getPointerId(eventIndex);
|
||||||
|
// getToolMajor, getToolMinor and getOrientation are API Level 9 features
|
||||||
|
if (Build.VERSION.SDK_INT >= 9) {
|
||||||
|
double radians = event.getOrientation(eventIndex);
|
||||||
|
mOrientations[index] = (float) Math.toDegrees(radians);
|
||||||
|
// w3c touchevents spec does not allow orientations == 90
|
||||||
|
// this shifts it to -90, which will be shifted to zero below
|
||||||
|
if (mOrientations[index] == 90)
|
||||||
|
mOrientations[index] = -90;
|
||||||
|
|
||||||
|
// w3c touchevent radius are given by an orientation between 0 and 90
|
||||||
|
// the radius is found by removing the orientation and measuring the x and y
|
||||||
|
// radius of the resulting ellipse
|
||||||
|
// for android orientations >= 0 and < 90, the major axis should correspond to
|
||||||
|
// just reporting the y radius as the major one, and x as minor
|
||||||
|
// however, for a radius < 0, we have to shift the orientation by adding 90, and
|
||||||
|
// reverse which radius is major and minor
|
||||||
|
if (mOrientations[index] < 0) {
|
||||||
|
mOrientations[index] += 90;
|
||||||
|
mPointRadii[index] = new Point((int)event.getToolMajor(eventIndex)/2,
|
||||||
|
(int)event.getToolMinor(eventIndex)/2);
|
||||||
|
} else {
|
||||||
|
mPointRadii[index] = new Point((int)event.getToolMinor(eventIndex)/2,
|
||||||
|
(int)event.getToolMajor(eventIndex)/2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
float size = event.getSize(eventIndex);
|
||||||
|
DisplayMetrics displaymetrics = new DisplayMetrics();
|
||||||
|
GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
|
||||||
|
size = size*Math.min(displaymetrics.heightPixels, displaymetrics.widthPixels);
|
||||||
|
mPointRadii[index] = new Point((int)size,(int)size);
|
||||||
|
mOrientations[index] = 0;
|
||||||
|
}
|
||||||
|
mPressures[index] = event.getPressure(eventIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeckoEvent(SensorEvent s) {
|
public GeckoEvent(SensorEvent s) {
|
||||||
@ -227,9 +299,10 @@ public class GeckoEvent {
|
|||||||
|
|
||||||
mType = etype;
|
mType = etype;
|
||||||
|
|
||||||
mP0 = new Point(w, h);
|
mPoints = new Point[3];
|
||||||
mP1 = new Point(screenw, screenh);
|
mPoints[0] = new Point(w, h);
|
||||||
mP2 = new Point(0, 0);
|
mPoints[1] = new Point(screenw, screenh);
|
||||||
|
mPoints[2] = new Point(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeckoEvent(String subject, String data) {
|
public GeckoEvent(String subject, String data) {
|
||||||
|
@ -503,6 +503,9 @@ public class GeckoAppShell
|
|||||||
|
|
||||||
layerController.setOnTouchListener(new View.OnTouchListener() {
|
layerController.setOnTouchListener(new View.OnTouchListener() {
|
||||||
public boolean onTouch(View view, MotionEvent event) {
|
public boolean onTouch(View view, MotionEvent event) {
|
||||||
|
if (event == null)
|
||||||
|
return true;
|
||||||
|
GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1117,6 +1120,15 @@ public class GeckoAppShell
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void preventPanning() {
|
||||||
|
getMainHandler().post(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
LayerController layerController = GeckoApp.mAppContext.getLayerController();
|
||||||
|
layerController.preventPanning(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isNetworkLinkUp() {
|
public static boolean isNetworkLinkUp() {
|
||||||
ConnectivityManager cm = (ConnectivityManager)
|
ConnectivityManager cm = (ConnectivityManager)
|
||||||
GeckoApp.mAppContext.getSystemService(Context.CONNECTIVITY_SERVICE);
|
GeckoApp.mAppContext.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
@ -48,6 +48,11 @@ import android.widget.*;
|
|||||||
import android.hardware.*;
|
import android.hardware.*;
|
||||||
import android.location.*;
|
import android.location.*;
|
||||||
import android.util.FloatMath;
|
import android.util.FloatMath;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.graphics.PointF;
|
||||||
|
import android.text.format.Time;
|
||||||
|
import android.os.SystemClock;
|
||||||
|
import java.lang.System;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@ -104,7 +109,12 @@ public class GeckoEvent {
|
|||||||
public int mType;
|
public int mType;
|
||||||
public int mAction;
|
public int mAction;
|
||||||
public long mTime;
|
public long mTime;
|
||||||
public Point mP0, mP1, mP2;
|
public Point[] mPoints;
|
||||||
|
public int[] mPointIndicies;
|
||||||
|
public int mPointerIndex; // index of the point that has changed
|
||||||
|
public float[] mOrientations;
|
||||||
|
public float[] mPressures;
|
||||||
|
public Point[] mPointRadii;
|
||||||
public Rect mRect;
|
public Rect mRect;
|
||||||
public double mX, mY, mZ;
|
public double mX, mY, mZ;
|
||||||
public double mAlpha, mBeta, mGamma;
|
public double mAlpha, mBeta, mGamma;
|
||||||
@ -145,12 +155,79 @@ public class GeckoEvent {
|
|||||||
public GeckoEvent(MotionEvent m) {
|
public GeckoEvent(MotionEvent m) {
|
||||||
mType = MOTION_EVENT;
|
mType = MOTION_EVENT;
|
||||||
mAction = m.getAction();
|
mAction = m.getAction();
|
||||||
mTime = m.getEventTime();
|
mTime = (System.currentTimeMillis() - SystemClock.elapsedRealtime()) + m.getEventTime();
|
||||||
mMetaState = m.getMetaState();
|
mMetaState = m.getMetaState();
|
||||||
mP0 = new Point((int)m.getX(0), (int)m.getY(0));
|
|
||||||
|
switch (mAction & MotionEvent.ACTION_MASK) {
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
case MotionEvent.ACTION_POINTER_UP:
|
||||||
|
case MotionEvent.ACTION_POINTER_DOWN:
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
case MotionEvent.ACTION_MOVE: {
|
||||||
mCount = m.getPointerCount();
|
mCount = m.getPointerCount();
|
||||||
if (mCount > 1)
|
mPoints = new Point[mCount];
|
||||||
mP1 = new Point((int)m.getX(1), (int)m.getY(1));
|
mPointIndicies = new int[mCount];
|
||||||
|
mOrientations = new float[mCount];
|
||||||
|
mPressures = new float[mCount];
|
||||||
|
mPointRadii = new Point[mCount];
|
||||||
|
mPointerIndex = (mAction & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||||
|
for (int i = 0; i < mCount; i++) {
|
||||||
|
addMotionPoint(i, i, m);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
mCount = 0;
|
||||||
|
mPointerIndex = -1;
|
||||||
|
mPoints = new Point[mCount];
|
||||||
|
mPointIndicies = new int[mCount];
|
||||||
|
mOrientations = new float[mCount];
|
||||||
|
mPressures = new float[mCount];
|
||||||
|
mPointRadii = new Point[mCount];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMotionPoint(int index, int eventIndex, MotionEvent event) {
|
||||||
|
PointF geckoPoint = new PointF(event.getX(eventIndex), event.getY(eventIndex));
|
||||||
|
geckoPoint = GeckoApp.mAppContext.getLayerController().convertViewPointToLayerPoint(geckoPoint);
|
||||||
|
|
||||||
|
mPoints[index] = new Point((int)Math.round(geckoPoint.x), (int)Math.round(geckoPoint.y));
|
||||||
|
mPointIndicies[index] = event.getPointerId(eventIndex);
|
||||||
|
// getToolMajor, getToolMinor and getOrientation are API Level 9 features
|
||||||
|
if (Build.VERSION.SDK_INT >= 9) {
|
||||||
|
double radians = event.getOrientation(eventIndex);
|
||||||
|
mOrientations[index] = (float) Math.toDegrees(radians);
|
||||||
|
// w3c touchevents spec does not allow orientations == 90
|
||||||
|
// this shifts it to -90, which will be shifted to zero below
|
||||||
|
if (mOrientations[index] == 90)
|
||||||
|
mOrientations[index] = -90;
|
||||||
|
|
||||||
|
// w3c touchevent radius are given by an orientation between 0 and 90
|
||||||
|
// the radius is found by removing the orientation and measuring the x and y
|
||||||
|
// radius of the resulting ellipse
|
||||||
|
// for android orientations >= 0 and < 90, the major axis should correspond to
|
||||||
|
// just reporting the y radius as the major one, and x as minor
|
||||||
|
// however, for a radius < 0, we have to shift the orientation by adding 90, and
|
||||||
|
// reverse which radius is major and minor
|
||||||
|
if (mOrientations[index] < 0) {
|
||||||
|
mOrientations[index] += 90;
|
||||||
|
mPointRadii[index] = new Point((int)event.getToolMajor(eventIndex)/2,
|
||||||
|
(int)event.getToolMinor(eventIndex)/2);
|
||||||
|
} else {
|
||||||
|
mPointRadii[index] = new Point((int)event.getToolMinor(eventIndex)/2,
|
||||||
|
(int)event.getToolMajor(eventIndex)/2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
float size = event.getSize(eventIndex);
|
||||||
|
DisplayMetrics displaymetrics = new DisplayMetrics();
|
||||||
|
GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
|
||||||
|
size = size*Math.min(displaymetrics.heightPixels, displaymetrics.widthPixels);
|
||||||
|
mPointRadii[index] = new Point((int)size,(int)size);
|
||||||
|
mOrientations[index] = 0;
|
||||||
|
}
|
||||||
|
mPressures[index] = event.getPressure(eventIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeckoEvent(SensorEvent s) {
|
public GeckoEvent(SensorEvent s) {
|
||||||
@ -230,9 +307,10 @@ public class GeckoEvent {
|
|||||||
|
|
||||||
mType = etype;
|
mType = etype;
|
||||||
|
|
||||||
mP0 = new Point(w, h);
|
mPoints = new Point[3];
|
||||||
mP1 = new Point(screenw, screenh);
|
mPoints[0] = new Point(w, h);
|
||||||
mP2 = new Point(tilew, tileh);
|
mPoints[1] = new Point(screenw, screenh);
|
||||||
|
mPoints[2] = new Point(tilew, tileh);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeckoEvent(String subject, String data) {
|
public GeckoEvent(String subject, String data) {
|
||||||
|
@ -45,10 +45,12 @@ import org.mozilla.gecko.gfx.LayerView;
|
|||||||
import org.mozilla.gecko.ui.PanZoomController;
|
import org.mozilla.gecko.ui.PanZoomController;
|
||||||
import org.mozilla.gecko.ui.SimpleScaleGestureDetector;
|
import org.mozilla.gecko.ui.SimpleScaleGestureDetector;
|
||||||
import org.mozilla.gecko.GeckoApp;
|
import org.mozilla.gecko.GeckoApp;
|
||||||
|
import org.mozilla.gecko.GeckoEvent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
@ -59,6 +61,8 @@ import android.view.GestureDetector;
|
|||||||
import android.view.ScaleGestureDetector;
|
import android.view.ScaleGestureDetector;
|
||||||
import android.view.View.OnTouchListener;
|
import android.view.View.OnTouchListener;
|
||||||
import java.lang.Math;
|
import java.lang.Math;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The layer controller manages a tile that represents the visible page. It does panning and
|
* The layer controller manages a tile that represents the visible page. It does panning and
|
||||||
@ -100,6 +104,14 @@ public class LayerController {
|
|||||||
private static final int DANGER_ZONE_X = 75;
|
private static final int DANGER_ZONE_X = 75;
|
||||||
private static final int DANGER_ZONE_Y = 150;
|
private static final int DANGER_ZONE_Y = 150;
|
||||||
|
|
||||||
|
/* The time limit for pages to respond with preventDefault on touchevents
|
||||||
|
* before we begin panning the page */
|
||||||
|
private static final int PREVENT_DEFAULT_TIMEOUT = 200;
|
||||||
|
|
||||||
|
private boolean allowDefaultActions = true;
|
||||||
|
private Timer allowDefaultTimer = null;
|
||||||
|
private boolean inTouchSession = false;
|
||||||
|
|
||||||
public LayerController(Context context) {
|
public LayerController(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
|
||||||
@ -149,6 +161,7 @@ public class LayerController {
|
|||||||
public Bitmap getBackgroundPattern() { return getDrawable("background"); }
|
public Bitmap getBackgroundPattern() { return getDrawable("background"); }
|
||||||
public Bitmap getShadowPattern() { return getDrawable("shadow"); }
|
public Bitmap getShadowPattern() { return getDrawable("shadow"); }
|
||||||
|
|
||||||
|
public PanZoomController getPanZoomController() { return mPanZoomController; }
|
||||||
public GestureDetector.OnGestureListener getGestureListener() { return mPanZoomController; }
|
public GestureDetector.OnGestureListener getGestureListener() { return mPanZoomController; }
|
||||||
public SimpleScaleGestureDetector.SimpleScaleGestureListener getScaleGestureListener() {
|
public SimpleScaleGestureDetector.SimpleScaleGestureListener getScaleGestureListener() {
|
||||||
return mPanZoomController;
|
return mPanZoomController;
|
||||||
@ -347,11 +360,58 @@ public class LayerController {
|
|||||||
* pan/zoom controller to do the dirty work.
|
* pan/zoom controller to do the dirty work.
|
||||||
*/
|
*/
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
if (mPanZoomController.onTouchEvent(event))
|
int action = event.getAction();
|
||||||
return true;
|
if ((action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
|
||||||
|
post(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
mView.clearEventQueue();
|
||||||
|
preventPanning(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (mOnTouchListener != null)
|
if (mOnTouchListener != null)
|
||||||
return mOnTouchListener.onTouch(mView, event);
|
mOnTouchListener.onTouch(mView, event);
|
||||||
return false;
|
|
||||||
|
switch (action & MotionEvent.ACTION_MASK) {
|
||||||
|
case MotionEvent.ACTION_MOVE: {
|
||||||
|
if (!inTouchSession && allowDefaultTimer == null) {
|
||||||
|
inTouchSession = true;
|
||||||
|
allowDefaultTimer = new Timer();
|
||||||
|
allowDefaultTimer.schedule(new TimerTask() {
|
||||||
|
public void run() {
|
||||||
|
post(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
preventPanning(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, PREVENT_DEFAULT_TIMEOUT);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
case MotionEvent.ACTION_UP: {
|
||||||
|
inTouchSession = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !allowDefaultActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void preventPanning(boolean aValue) {
|
||||||
|
if (allowDefaultTimer != null) {
|
||||||
|
allowDefaultTimer.cancel();
|
||||||
|
allowDefaultTimer.purge();
|
||||||
|
allowDefaultTimer = null;
|
||||||
|
}
|
||||||
|
allowDefaultActions = !aValue;
|
||||||
|
|
||||||
|
if (aValue) {
|
||||||
|
mView.clearEventQueue();
|
||||||
|
mPanZoomController.cancelTouch();
|
||||||
|
} else {
|
||||||
|
mView.processEventQueue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Retrieves the color that the checkerboard should be. */
|
/** Retrieves the color that the checkerboard should be. */
|
||||||
|
@ -48,6 +48,8 @@ import android.view.KeyEvent;
|
|||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.view.inputmethod.InputConnection;
|
import android.view.inputmethod.InputConnection;
|
||||||
|
import android.util.Log;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A view rendered by the layer compositor.
|
* A view rendered by the layer compositor.
|
||||||
@ -64,6 +66,10 @@ public class LayerView extends GLSurfaceView {
|
|||||||
private SimpleScaleGestureDetector mScaleGestureDetector;
|
private SimpleScaleGestureDetector mScaleGestureDetector;
|
||||||
private long mRenderTime;
|
private long mRenderTime;
|
||||||
private boolean mRenderTimeReset;
|
private boolean mRenderTimeReset;
|
||||||
|
private static String LOGTAG = "GeckoLayerView";
|
||||||
|
/* List of events to be processed if the page does not prevent them. Should only be touched on the main thread */
|
||||||
|
private LinkedList<MotionEvent> mEventQueue = new LinkedList<MotionEvent>();
|
||||||
|
|
||||||
|
|
||||||
public LayerView(Context context, LayerController controller) {
|
public LayerView(Context context, LayerController controller) {
|
||||||
super(context);
|
super(context);
|
||||||
@ -83,14 +89,40 @@ public class LayerView extends GLSurfaceView {
|
|||||||
setFocusableInTouchMode(true);
|
setFocusableInTouchMode(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addToEventQueue(MotionEvent event) {
|
||||||
|
MotionEvent copy = MotionEvent.obtain(event);
|
||||||
|
mEventQueue.add(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processEventQueue() {
|
||||||
|
MotionEvent event = mEventQueue.poll();
|
||||||
|
while(event != null) {
|
||||||
|
processEvent(event);
|
||||||
|
event = mEventQueue.poll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearEventQueue() {
|
||||||
|
mEventQueue.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
if (mController.onTouchEvent(event)) {
|
||||||
|
addToEventQueue(event);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return processEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean processEvent(MotionEvent event) {
|
||||||
if (mGestureDetector.onTouchEvent(event))
|
if (mGestureDetector.onTouchEvent(event))
|
||||||
return true;
|
return true;
|
||||||
mScaleGestureDetector.onTouchEvent(event);
|
mScaleGestureDetector.onTouchEvent(event);
|
||||||
if (mScaleGestureDetector.isInProgress())
|
if (mScaleGestureDetector.isInProgress())
|
||||||
return true;
|
return true;
|
||||||
return mController.onTouchEvent(event);
|
mController.getPanZoomController().onTouchEvent(event);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LayerController getController() { return mController; }
|
public LayerController getController() { return mController; }
|
||||||
|
@ -843,7 +843,7 @@ public class PanZoomController
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelTouch() {
|
public void cancelTouch() {
|
||||||
GeckoEvent e = new GeckoEvent("Gesture:CancelTouch", "");
|
GeckoEvent e = new GeckoEvent("Gesture:CancelTouch", "");
|
||||||
GeckoAppShell.sendEventToGecko(e);
|
GeckoAppShell.sendEventToGecko(e);
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,9 @@ MOZ_APP_COMPONENT_INCLUDE=nsBrowserComponents.h
|
|||||||
# use custom widget for html:select
|
# use custom widget for html:select
|
||||||
MOZ_USE_NATIVE_POPUP_WINDOWS=1
|
MOZ_USE_NATIVE_POPUP_WINDOWS=1
|
||||||
|
|
||||||
|
# dispatch only touch events (no mouse events)
|
||||||
|
MOZ_ONLY_TOUCH_EVENTS=1
|
||||||
|
|
||||||
MOZ_APP_ID={aa3c5121-dab2-40e2-81ca-7ea25febc110}
|
MOZ_APP_ID={aa3c5121-dab2-40e2-81ca-7ea25febc110}
|
||||||
|
|
||||||
MOZ_JAVA_COMPOSITOR=1
|
MOZ_JAVA_COMPOSITOR=1
|
||||||
|
@ -139,6 +139,7 @@ AndroidBridge::Init(JNIEnv *jEnv,
|
|||||||
jGetDpi = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getDpi", "()I");
|
jGetDpi = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getDpi", "()I");
|
||||||
jSetFullScreen = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "setFullScreen", "(Z)V");
|
jSetFullScreen = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "setFullScreen", "(Z)V");
|
||||||
jShowInputMethodPicker = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "showInputMethodPicker", "()V");
|
jShowInputMethodPicker = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "showInputMethodPicker", "()V");
|
||||||
|
jPreventPanning = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "preventPanning", "()V");
|
||||||
jHideProgressDialog = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "hideProgressDialog", "()V");
|
jHideProgressDialog = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "hideProgressDialog", "()V");
|
||||||
jPerformHapticFeedback = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "performHapticFeedback", "(Z)V");
|
jPerformHapticFeedback = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "performHapticFeedback", "(Z)V");
|
||||||
jVibrate1 = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "vibrate", "(J)V");
|
jVibrate1 = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "vibrate", "(J)V");
|
||||||
@ -1612,3 +1613,9 @@ NS_IMETHODIMP nsAndroidBridge::SetDrawMetadataProvider(nsIAndroidDrawMetadataPro
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AndroidBridge::PreventPanning() {
|
||||||
|
ALOG_BRIDGE("AndroidBridge::PreventPanning");
|
||||||
|
mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jPreventPanning);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -218,6 +218,8 @@ public:
|
|||||||
|
|
||||||
void ShowInputMethodPicker();
|
void ShowInputMethodPicker();
|
||||||
|
|
||||||
|
void PreventPanning();
|
||||||
|
|
||||||
void HideProgressDialogOnce();
|
void HideProgressDialogOnce();
|
||||||
|
|
||||||
bool IsNetworkLinkUp();
|
bool IsNetworkLinkUp();
|
||||||
@ -413,6 +415,7 @@ protected:
|
|||||||
jmethodID jGetDpi;
|
jmethodID jGetDpi;
|
||||||
jmethodID jSetFullScreen;
|
jmethodID jSetFullScreen;
|
||||||
jmethodID jShowInputMethodPicker;
|
jmethodID jShowInputMethodPicker;
|
||||||
|
jmethodID jPreventPanning;
|
||||||
jmethodID jHideProgressDialog;
|
jmethodID jHideProgressDialog;
|
||||||
jmethodID jPerformHapticFeedback;
|
jmethodID jPerformHapticFeedback;
|
||||||
jmethodID jVibrate1;
|
jmethodID jVibrate1;
|
||||||
|
@ -44,9 +44,11 @@ jclass AndroidGeckoEvent::jGeckoEventClass = 0;
|
|||||||
jfieldID AndroidGeckoEvent::jActionField = 0;
|
jfieldID AndroidGeckoEvent::jActionField = 0;
|
||||||
jfieldID AndroidGeckoEvent::jTypeField = 0;
|
jfieldID AndroidGeckoEvent::jTypeField = 0;
|
||||||
jfieldID AndroidGeckoEvent::jTimeField = 0;
|
jfieldID AndroidGeckoEvent::jTimeField = 0;
|
||||||
jfieldID AndroidGeckoEvent::jP0Field = 0;
|
jfieldID AndroidGeckoEvent::jPoints = 0;
|
||||||
jfieldID AndroidGeckoEvent::jP1Field = 0;
|
jfieldID AndroidGeckoEvent::jPointIndicies = 0;
|
||||||
jfieldID AndroidGeckoEvent::jP2Field = 0;
|
jfieldID AndroidGeckoEvent::jPressures = 0;
|
||||||
|
jfieldID AndroidGeckoEvent::jPointRadii = 0;
|
||||||
|
jfieldID AndroidGeckoEvent::jOrientations = 0;
|
||||||
jfieldID AndroidGeckoEvent::jAlphaField = 0;
|
jfieldID AndroidGeckoEvent::jAlphaField = 0;
|
||||||
jfieldID AndroidGeckoEvent::jBetaField = 0;
|
jfieldID AndroidGeckoEvent::jBetaField = 0;
|
||||||
jfieldID AndroidGeckoEvent::jGammaField = 0;
|
jfieldID AndroidGeckoEvent::jGammaField = 0;
|
||||||
@ -64,6 +66,7 @@ jfieldID AndroidGeckoEvent::jFlagsField = 0;
|
|||||||
jfieldID AndroidGeckoEvent::jUnicodeCharField = 0;
|
jfieldID AndroidGeckoEvent::jUnicodeCharField = 0;
|
||||||
jfieldID AndroidGeckoEvent::jOffsetField = 0;
|
jfieldID AndroidGeckoEvent::jOffsetField = 0;
|
||||||
jfieldID AndroidGeckoEvent::jCountField = 0;
|
jfieldID AndroidGeckoEvent::jCountField = 0;
|
||||||
|
jfieldID AndroidGeckoEvent::jPointerIndexField = 0;
|
||||||
jfieldID AndroidGeckoEvent::jRangeTypeField = 0;
|
jfieldID AndroidGeckoEvent::jRangeTypeField = 0;
|
||||||
jfieldID AndroidGeckoEvent::jRangeStylesField = 0;
|
jfieldID AndroidGeckoEvent::jRangeStylesField = 0;
|
||||||
jfieldID AndroidGeckoEvent::jRangeForeColorField = 0;
|
jfieldID AndroidGeckoEvent::jRangeForeColorField = 0;
|
||||||
@ -157,9 +160,11 @@ AndroidGeckoEvent::InitGeckoEventClass(JNIEnv *jEnv)
|
|||||||
jActionField = getField("mAction", "I");
|
jActionField = getField("mAction", "I");
|
||||||
jTypeField = getField("mType", "I");
|
jTypeField = getField("mType", "I");
|
||||||
jTimeField = getField("mTime", "J");
|
jTimeField = getField("mTime", "J");
|
||||||
jP0Field = getField("mP0", "Landroid/graphics/Point;");
|
jPoints = getField("mPoints", "[Landroid/graphics/Point;");
|
||||||
jP1Field = getField("mP1", "Landroid/graphics/Point;");
|
jPointIndicies = getField("mPointIndicies", "[I");
|
||||||
jP2Field = getField("mP2", "Landroid/graphics/Point;");
|
jOrientations = getField("mOrientations", "[F");
|
||||||
|
jPressures = getField("mPressures", "[F");
|
||||||
|
jPointRadii = getField("mPointRadii", "[Landroid/graphics/Point;");
|
||||||
jAlphaField = getField("mAlpha", "D");
|
jAlphaField = getField("mAlpha", "D");
|
||||||
jBetaField = getField("mBeta", "D");
|
jBetaField = getField("mBeta", "D");
|
||||||
jGammaField = getField("mGamma", "D");
|
jGammaField = getField("mGamma", "D");
|
||||||
@ -176,6 +181,7 @@ AndroidGeckoEvent::InitGeckoEventClass(JNIEnv *jEnv)
|
|||||||
jUnicodeCharField = getField("mUnicodeChar", "I");
|
jUnicodeCharField = getField("mUnicodeChar", "I");
|
||||||
jOffsetField = getField("mOffset", "I");
|
jOffsetField = getField("mOffset", "I");
|
||||||
jCountField = getField("mCount", "I");
|
jCountField = getField("mCount", "I");
|
||||||
|
jPointerIndexField = getField("mPointerIndex", "I");
|
||||||
jRangeTypeField = getField("mRangeType", "I");
|
jRangeTypeField = getField("mRangeType", "I");
|
||||||
jRangeStylesField = getField("mRangeStyles", "I");
|
jRangeStylesField = getField("mRangeStyles", "I");
|
||||||
jRangeForeColorField = getField("mRangeForeColor", "I");
|
jRangeForeColorField = getField("mRangeForeColor", "I");
|
||||||
@ -338,27 +344,47 @@ AndroidGeckoSoftwareLayerClient::InitGeckoSoftwareLayerClientClass(JNIEnv *jEnv)
|
|||||||
#undef getMethod
|
#undef getMethod
|
||||||
|
|
||||||
void
|
void
|
||||||
AndroidGeckoEvent::ReadP0Field(JNIEnv *jenv)
|
AndroidGeckoEvent::ReadPointArray(nsTArray<nsIntPoint> &points,
|
||||||
|
JNIEnv *jenv,
|
||||||
|
jfieldID field,
|
||||||
|
PRUint32 count)
|
||||||
{
|
{
|
||||||
AndroidPoint p0(jenv, jenv->GetObjectField(wrappedObject(), jP0Field));
|
jobjectArray jObjArray = (jobjectArray)jenv->GetObjectField(wrapped_obj, field);
|
||||||
mP0.x = p0.X();
|
for (PRInt32 i = 0; i < count; i++) {
|
||||||
mP0.y = p0.Y();
|
jobject jObj = jenv->GetObjectArrayElement(jObjArray, i);
|
||||||
|
AndroidPoint jpoint(jenv, jObj);
|
||||||
|
|
||||||
|
nsIntPoint p(jpoint.X(), jpoint.Y());
|
||||||
|
points.AppendElement(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AndroidGeckoEvent::ReadP1Field(JNIEnv *jenv)
|
AndroidGeckoEvent::ReadIntArray(nsTArray<int> &aVals,
|
||||||
|
JNIEnv *jenv,
|
||||||
|
jfieldID field,
|
||||||
|
PRUint32 count)
|
||||||
{
|
{
|
||||||
AndroidPoint p1(jenv, jenv->GetObjectField(wrappedObject(), jP1Field));
|
jintArray jIntArray = (jintArray)jenv->GetObjectField(wrapped_obj, field);
|
||||||
mP1.x = p1.X();
|
jint *vals = jenv->GetIntArrayElements(jIntArray, false);
|
||||||
mP1.y = p1.Y();
|
for (PRInt32 i = 0; i < count; i++) {
|
||||||
|
aVals.AppendElement(vals[i]);
|
||||||
|
}
|
||||||
|
jenv->ReleaseIntArrayElements(jIntArray, vals, JNI_ABORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AndroidGeckoEvent::ReadP2Field(JNIEnv *jenv)
|
AndroidGeckoEvent::ReadFloatArray(nsTArray<float> &aVals,
|
||||||
|
JNIEnv *jenv,
|
||||||
|
jfieldID field,
|
||||||
|
PRUint32 count)
|
||||||
{
|
{
|
||||||
AndroidPoint p2(jenv, jenv->GetObjectField(wrappedObject(), jP2Field));
|
jfloatArray jFloatArray = (jfloatArray)jenv->GetObjectField(wrapped_obj, field);
|
||||||
mP2.x = p2.X();
|
jfloat *vals = jenv->GetFloatArrayElements(jFloatArray, false);
|
||||||
mP2.y = p2.Y();
|
for (PRInt32 i = 0; i < count; i++) {
|
||||||
|
aVals.AppendElement(vals[i]);
|
||||||
|
}
|
||||||
|
jenv->ReleaseFloatArrayElements(jFloatArray, vals, JNI_ABORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -425,9 +451,7 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj)
|
|||||||
|
|
||||||
switch (mType) {
|
switch (mType) {
|
||||||
case SIZE_CHANGED:
|
case SIZE_CHANGED:
|
||||||
ReadP0Field(jenv);
|
ReadPointArray(mPoints, jenv, jPoints, 3);
|
||||||
ReadP1Field(jenv);
|
|
||||||
ReadP2Field(jenv);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_EVENT:
|
case KEY_EVENT:
|
||||||
@ -443,9 +467,14 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj)
|
|||||||
mTime = jenv->GetLongField(jobj, jTimeField);
|
mTime = jenv->GetLongField(jobj, jTimeField);
|
||||||
mMetaState = jenv->GetIntField(jobj, jMetaStateField);
|
mMetaState = jenv->GetIntField(jobj, jMetaStateField);
|
||||||
mCount = jenv->GetIntField(jobj, jCountField);
|
mCount = jenv->GetIntField(jobj, jCountField);
|
||||||
ReadP0Field(jenv);
|
mPointerIndex = jenv->GetIntField(jobj, jPointerIndexField);
|
||||||
if (mCount > 1)
|
|
||||||
ReadP1Field(jenv);
|
ReadPointArray(mPointRadii, jenv, jPointRadii, mCount);
|
||||||
|
ReadFloatArray(mOrientations, jenv, jOrientations, mCount);
|
||||||
|
ReadFloatArray(mPressures, jenv, jPressures, mCount);
|
||||||
|
ReadPointArray(mPoints, jenv, jPoints, mCount);
|
||||||
|
ReadIntArray(mPointIndicies, jenv, jPointIndicies, mCount);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IME_EVENT:
|
case IME_EVENT:
|
||||||
@ -544,10 +573,7 @@ AndroidGeckoEvent::Init(AndroidGeckoEvent *aResizeEvent)
|
|||||||
|
|
||||||
mType = FORCED_RESIZE;
|
mType = FORCED_RESIZE;
|
||||||
mTime = aResizeEvent->mTime;
|
mTime = aResizeEvent->mTime;
|
||||||
mP0.x = aResizeEvent->mP0.x;
|
mPoints = aResizeEvent->mPoints; // x,y coordinates
|
||||||
mP0.y = aResizeEvent->mP0.y;
|
|
||||||
mP1.x = aResizeEvent->mP1.x;
|
|
||||||
mP1.y = aResizeEvent->mP1.y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -434,9 +434,11 @@ public:
|
|||||||
int Action() { return mAction; }
|
int Action() { return mAction; }
|
||||||
int Type() { return mType; }
|
int Type() { return mType; }
|
||||||
int64_t Time() { return mTime; }
|
int64_t Time() { return mTime; }
|
||||||
const nsIntPoint& P0() { return mP0; }
|
nsTArray<nsIntPoint> Points() { return mPoints; }
|
||||||
const nsIntPoint& P1() { return mP1; }
|
nsTArray<int> PointIndicies() { return mPointIndicies; }
|
||||||
const nsIntPoint& P2() { return mP2; }
|
nsTArray<float> Pressures() { return mPressures; }
|
||||||
|
nsTArray<float> Orientations() { return mOrientations; }
|
||||||
|
nsTArray<nsIntPoint> PointRadii() { return mPointRadii; }
|
||||||
double Alpha() { return mAlpha; }
|
double Alpha() { return mAlpha; }
|
||||||
double Beta() { return mBeta; }
|
double Beta() { return mBeta; }
|
||||||
double Gamma() { return mGamma; }
|
double Gamma() { return mGamma; }
|
||||||
@ -452,6 +454,7 @@ public:
|
|||||||
int UnicodeChar() { return mUnicodeChar; }
|
int UnicodeChar() { return mUnicodeChar; }
|
||||||
int Offset() { return mOffset; }
|
int Offset() { return mOffset; }
|
||||||
int Count() { return mCount; }
|
int Count() { return mCount; }
|
||||||
|
int PointerIndex() { return mPointerIndex; }
|
||||||
int RangeType() { return mRangeType; }
|
int RangeType() { return mRangeType; }
|
||||||
int RangeStyles() { return mRangeStyles; }
|
int RangeStyles() { return mRangeStyles; }
|
||||||
int RangeForeColor() { return mRangeForeColor; }
|
int RangeForeColor() { return mRangeForeColor; }
|
||||||
@ -465,9 +468,11 @@ protected:
|
|||||||
int mAction;
|
int mAction;
|
||||||
int mType;
|
int mType;
|
||||||
int64_t mTime;
|
int64_t mTime;
|
||||||
nsIntPoint mP0;
|
nsTArray<nsIntPoint> mPoints;
|
||||||
nsIntPoint mP1;
|
nsTArray<nsIntPoint> mPointRadii;
|
||||||
nsIntPoint mP2;
|
nsTArray<int> mPointIndicies;
|
||||||
|
nsTArray<float> mOrientations;
|
||||||
|
nsTArray<float> mPressures;
|
||||||
nsIntRect mRect;
|
nsIntRect mRect;
|
||||||
int mFlags, mMetaState;
|
int mFlags, mMetaState;
|
||||||
int mKeyCode, mUnicodeChar;
|
int mKeyCode, mUnicodeChar;
|
||||||
@ -476,15 +481,25 @@ protected:
|
|||||||
int mRangeForeColor, mRangeBackColor;
|
int mRangeForeColor, mRangeBackColor;
|
||||||
double mAlpha, mBeta, mGamma;
|
double mAlpha, mBeta, mGamma;
|
||||||
double mX, mY, mZ;
|
double mX, mY, mZ;
|
||||||
|
int mPointerIndex;
|
||||||
nsString mCharacters, mCharactersExtra;
|
nsString mCharacters, mCharactersExtra;
|
||||||
nsRefPtr<nsGeoPosition> mGeoPosition;
|
nsRefPtr<nsGeoPosition> mGeoPosition;
|
||||||
nsRefPtr<nsGeoPositionAddress> mGeoAddress;
|
nsRefPtr<nsGeoPositionAddress> mGeoAddress;
|
||||||
double mBandwidth;
|
double mBandwidth;
|
||||||
bool mCanBeMetered;
|
bool mCanBeMetered;
|
||||||
|
|
||||||
void ReadP0Field(JNIEnv *jenv);
|
void ReadIntArray(nsTArray<int> &aVals,
|
||||||
void ReadP1Field(JNIEnv *jenv);
|
JNIEnv *jenv,
|
||||||
void ReadP2Field(JNIEnv *jenv);
|
jfieldID field,
|
||||||
|
PRUint32 count);
|
||||||
|
void ReadFloatArray(nsTArray<float> &aVals,
|
||||||
|
JNIEnv *jenv,
|
||||||
|
jfieldID field,
|
||||||
|
PRUint32 count);
|
||||||
|
void ReadPointArray(nsTArray<nsIntPoint> &mPoints,
|
||||||
|
JNIEnv *jenv,
|
||||||
|
jfieldID field,
|
||||||
|
PRUint32 count);
|
||||||
void ReadRectField(JNIEnv *jenv);
|
void ReadRectField(JNIEnv *jenv);
|
||||||
void ReadCharactersField(JNIEnv *jenv);
|
void ReadCharactersField(JNIEnv *jenv);
|
||||||
void ReadCharactersExtraField(JNIEnv *jenv);
|
void ReadCharactersExtraField(JNIEnv *jenv);
|
||||||
@ -493,9 +508,11 @@ protected:
|
|||||||
static jfieldID jActionField;
|
static jfieldID jActionField;
|
||||||
static jfieldID jTypeField;
|
static jfieldID jTypeField;
|
||||||
static jfieldID jTimeField;
|
static jfieldID jTimeField;
|
||||||
static jfieldID jP0Field;
|
static jfieldID jPoints;
|
||||||
static jfieldID jP1Field;
|
static jfieldID jPointIndicies;
|
||||||
static jfieldID jP2Field;
|
static jfieldID jOrientations;
|
||||||
|
static jfieldID jPressures;
|
||||||
|
static jfieldID jPointRadii;
|
||||||
static jfieldID jAlphaField;
|
static jfieldID jAlphaField;
|
||||||
static jfieldID jBetaField;
|
static jfieldID jBetaField;
|
||||||
static jfieldID jGammaField;
|
static jfieldID jGammaField;
|
||||||
@ -512,6 +529,7 @@ protected:
|
|||||||
static jfieldID jFlagsField;
|
static jfieldID jFlagsField;
|
||||||
static jfieldID jOffsetField;
|
static jfieldID jOffsetField;
|
||||||
static jfieldID jCountField;
|
static jfieldID jCountField;
|
||||||
|
static jfieldID jPointerIndexField;
|
||||||
static jfieldID jUnicodeCharField;
|
static jfieldID jUnicodeCharField;
|
||||||
static jfieldID jRangeTypeField;
|
static jfieldID jRangeTypeField;
|
||||||
static jfieldID jRangeStylesField;
|
static jfieldID jRangeStylesField;
|
||||||
|
@ -103,6 +103,7 @@ LOCAL_INCLUDES += \
|
|||||||
-I$(topsrcdir)/dom/system/android \
|
-I$(topsrcdir)/dom/system/android \
|
||||||
-I$(topsrcdir)/toolkit/components/places \
|
-I$(topsrcdir)/toolkit/components/places \
|
||||||
-I$(topsrcdir)/docshell/base \
|
-I$(topsrcdir)/docshell/base \
|
||||||
|
-I$(topsrcdir)/content/events/src \
|
||||||
-I$(srcdir) \
|
-I$(srcdir) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ using mozilla::unused;
|
|||||||
|
|
||||||
#include "nsRenderingContext.h"
|
#include "nsRenderingContext.h"
|
||||||
#include "nsIDOMSimpleGestureEvent.h"
|
#include "nsIDOMSimpleGestureEvent.h"
|
||||||
|
#include "nsDOMTouchEvent.h"
|
||||||
|
|
||||||
#include "nsGkAtoms.h"
|
#include "nsGkAtoms.h"
|
||||||
#include "nsWidgetsCID.h"
|
#include "nsWidgetsCID.h"
|
||||||
@ -895,8 +896,11 @@ nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
|
|||||||
win->mChildren[i]->mBounds.height = 0;
|
win->mChildren[i]->mBounds.height = 0;
|
||||||
}
|
}
|
||||||
case AndroidGeckoEvent::SIZE_CHANGED: {
|
case AndroidGeckoEvent::SIZE_CHANGED: {
|
||||||
int nw = ae->P0().x;
|
nsTArray<nsIntPoint> points = ae->Points();
|
||||||
int nh = ae->P0().y;
|
NS_ASSERTION(points.Length() != 3, "Size changed does not have enough coordinates");
|
||||||
|
|
||||||
|
int nw = points[0].x;
|
||||||
|
int nh = points[0].y;
|
||||||
|
|
||||||
if (ae->Type() == AndroidGeckoEvent::FORCED_RESIZE || nw != gAndroidBounds.width ||
|
if (ae->Type() == AndroidGeckoEvent::FORCED_RESIZE || nw != gAndroidBounds.width ||
|
||||||
nh != gAndroidBounds.height) {
|
nh != gAndroidBounds.height) {
|
||||||
@ -913,11 +917,11 @@ nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gAndroidTileSize.width = ae->P2().x;
|
gAndroidTileSize.width = points[2].x;
|
||||||
gAndroidTileSize.height = ae->P2().y;
|
gAndroidTileSize.height = points[2].y;
|
||||||
|
|
||||||
int newScreenWidth = ae->P1().x;
|
int newScreenWidth = points[1].x;
|
||||||
int newScreenHeight = ae->P1().y;
|
int newScreenHeight = points[1].y;
|
||||||
|
|
||||||
if (newScreenWidth == gAndroidScreenBounds.width &&
|
if (newScreenWidth == gAndroidScreenBounds.width &&
|
||||||
newScreenHeight == gAndroidScreenBounds.height)
|
newScreenHeight == gAndroidScreenBounds.height)
|
||||||
@ -951,29 +955,36 @@ nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
|
|||||||
else
|
else
|
||||||
obs->RemoveObserver(notifier, "ipc:content-created");
|
obs->RemoveObserver(notifier, "ipc:content-created");
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AndroidGeckoEvent::MOTION_EVENT: {
|
case AndroidGeckoEvent::MOTION_EVENT: {
|
||||||
win->UserActivity();
|
win->UserActivity();
|
||||||
if (!gTopLevelWindows.IsEmpty()) {
|
if (!gTopLevelWindows.IsEmpty()) {
|
||||||
nsIntPoint pt(ae->P0());
|
nsIntPoint pt(0,0);
|
||||||
|
nsTArray<nsIntPoint> points = ae->Points();
|
||||||
|
if (points.Length() > 0) {
|
||||||
|
pt = points[0];
|
||||||
|
}
|
||||||
pt.x = clamped(pt.x, 0, gAndroidBounds.width - 1);
|
pt.x = clamped(pt.x, 0, gAndroidBounds.width - 1);
|
||||||
pt.y = clamped(pt.y, 0, gAndroidBounds.height - 1);
|
pt.y = clamped(pt.y, 0, gAndroidBounds.height - 1);
|
||||||
nsWindow *target = win->FindWindowForPoint(pt);
|
nsWindow *target = win->FindWindowForPoint(pt);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
ALOG("MOTION_EVENT %f,%f -> %p (visible: %d children: %d)", ae->P0().x, ae->P0().y, (void*)target,
|
ALOG("MOTION_EVENT %f,%f -> %p (visible: %d children: %d)", pt.x, pt.y, (void*)target,
|
||||||
target ? target->mIsVisible : 0,
|
target ? target->mIsVisible : 0,
|
||||||
target ? target->mChildren.Length() : 0);
|
target ? target->mChildren.Length() : 0);
|
||||||
|
|
||||||
DumpWindows();
|
DumpWindows();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
if (ae->Count() > 1)
|
bool preventDefaultActions = target->OnMultitouchEvent(ae);
|
||||||
target->OnMultitouchEvent(ae);
|
if (!preventDefaultActions && ae->Count() == 2) {
|
||||||
else
|
target->OnGestureEvent(ae);
|
||||||
|
}
|
||||||
|
#ifndef MOZ_ONLY_TOUCH_EVENTS
|
||||||
|
if (!preventDefaultActions && ae->Count() < 2)
|
||||||
target->OnMotionEvent(ae);
|
target->OnMotionEvent(ae);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1470,30 +1481,11 @@ nsWindow::OnMotionEvent(AndroidGeckoEvent *ae)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<nsWindow> kungFuDeathGrip(this);
|
|
||||||
nsIntPoint pt(ae->P0());
|
|
||||||
nsIntPoint offset = WidgetToScreenOffset();
|
|
||||||
|
|
||||||
//ALOG("#### motion pt: %d %d offset: %d %d", pt.x, pt.y, offset.x, offset.y);
|
|
||||||
|
|
||||||
pt.x -= offset.x;
|
|
||||||
pt.y -= offset.y;
|
|
||||||
|
|
||||||
// XXX possibly bound the range of pt here. some code may get confused.
|
|
||||||
|
|
||||||
send_again:
|
send_again:
|
||||||
|
|
||||||
nsMouseEvent event(true,
|
nsMouseEvent event(true,
|
||||||
msg, this,
|
msg, this,
|
||||||
nsMouseEvent::eReal, nsMouseEvent::eNormal);
|
nsMouseEvent::eReal, nsMouseEvent::eNormal);
|
||||||
InitEvent(event, &pt);
|
|
||||||
|
|
||||||
event.time = ae->Time();
|
|
||||||
event.isShift = !!(ae->MetaState() & AndroidKeyEvent::META_SHIFT_ON);
|
|
||||||
event.isControl = false;
|
|
||||||
event.isMeta = false;
|
|
||||||
event.isAlt = !!(ae->MetaState() & AndroidKeyEvent::META_ALT_ON);
|
|
||||||
|
|
||||||
// XXX can we synthesize different buttons?
|
// XXX can we synthesize different buttons?
|
||||||
event.button = nsMouseEvent::eLeftButton;
|
event.button = nsMouseEvent::eLeftButton;
|
||||||
|
|
||||||
@ -1501,8 +1493,8 @@ send_again:
|
|||||||
event.clickCount = 1;
|
event.clickCount = 1;
|
||||||
|
|
||||||
// XXX add the double-click handling logic here
|
// XXX add the double-click handling logic here
|
||||||
|
if (ae->Points().Length() > 0)
|
||||||
DispatchEvent(&event);
|
DispatchMotionEvent(event, ae, ae->Points()[0]);
|
||||||
if (Destroyed())
|
if (Destroyed())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1520,16 +1512,87 @@ getDistance(const nsIntPoint &p1, const nsIntPoint &p2)
|
|||||||
return sqrt(deltaX*deltaX + deltaY*deltaY);
|
return sqrt(deltaX*deltaX + deltaY*deltaY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsWindow::OnMultitouchEvent(AndroidGeckoEvent *ae)
|
bool nsWindow::OnMultitouchEvent(AndroidGeckoEvent *ae)
|
||||||
|
{
|
||||||
|
switch (ae->Action() & AndroidMotionEvent::ACTION_MASK) {
|
||||||
|
case AndroidMotionEvent::ACTION_DOWN:
|
||||||
|
case AndroidMotionEvent::ACTION_POINTER_DOWN: {
|
||||||
|
nsTouchEvent event(PR_TRUE, NS_TOUCH_START, this);
|
||||||
|
return DispatchMultitouchEvent(event, ae);
|
||||||
|
}
|
||||||
|
case AndroidMotionEvent::ACTION_MOVE: {
|
||||||
|
nsTouchEvent event(PR_TRUE, NS_TOUCH_MOVE, this);
|
||||||
|
return DispatchMultitouchEvent(event, ae);
|
||||||
|
}
|
||||||
|
case AndroidMotionEvent::ACTION_UP:
|
||||||
|
case AndroidMotionEvent::ACTION_POINTER_UP: {
|
||||||
|
nsTouchEvent event(PR_TRUE, NS_TOUCH_END, this);
|
||||||
|
return DispatchMultitouchEvent(event, ae);
|
||||||
|
}
|
||||||
|
case AndroidMotionEvent::ACTION_OUTSIDE:
|
||||||
|
case AndroidMotionEvent::ACTION_CANCEL: {
|
||||||
|
nsTouchEvent event(PR_TRUE, NS_TOUCH_CANCEL, this);
|
||||||
|
return DispatchMultitouchEvent(event, ae);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsWindow::DispatchMultitouchEvent(nsTouchEvent &event, AndroidGeckoEvent *ae)
|
||||||
|
{
|
||||||
|
nsIntPoint offset = WidgetToScreenOffset();
|
||||||
|
|
||||||
|
event.isShift = false;
|
||||||
|
event.isControl = false;
|
||||||
|
event.isMeta = false;
|
||||||
|
event.isAlt = false;
|
||||||
|
event.time = ae->Time();
|
||||||
|
|
||||||
|
int action = ae->Action() & AndroidMotionEvent::ACTION_MASK;
|
||||||
|
if (action == AndroidMotionEvent::ACTION_UP ||
|
||||||
|
action == AndroidMotionEvent::ACTION_POINTER_UP) {
|
||||||
|
event.touches.SetCapacity(1);
|
||||||
|
int pointerIndex = ae->PointerIndex();
|
||||||
|
nsCOMPtr<nsIDOMTouch> t(new nsDOMTouch(ae->PointIndicies()[pointerIndex],
|
||||||
|
ae->Points()[pointerIndex] - offset,
|
||||||
|
ae->PointRadii()[pointerIndex],
|
||||||
|
ae->Orientations()[pointerIndex],
|
||||||
|
ae->Pressures()[pointerIndex]));
|
||||||
|
event.touches.AppendElement(t);
|
||||||
|
} else {
|
||||||
|
int count = ae->Count();
|
||||||
|
event.touches.SetCapacity(count);
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
nsCOMPtr<nsIDOMTouch> t(new nsDOMTouch(ae->PointIndicies()[i],
|
||||||
|
ae->Points()[i] - offset,
|
||||||
|
ae->PointRadii()[i],
|
||||||
|
ae->Orientations()[i],
|
||||||
|
ae->Pressures()[i]));
|
||||||
|
event.touches.AppendElement(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsEventStatus status;
|
||||||
|
DispatchEvent(&event, status);
|
||||||
|
if (status == nsEventStatus_eConsumeNoDefault) {
|
||||||
|
AndroidBridge::Bridge()->PreventPanning();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::OnGestureEvent(AndroidGeckoEvent *ae)
|
||||||
{
|
{
|
||||||
PRUint32 msg = 0;
|
PRUint32 msg = 0;
|
||||||
|
|
||||||
nsIntPoint midPoint;
|
nsIntPoint midPoint;
|
||||||
midPoint.x = ((ae->P0().x + ae->P1().x) / 2);
|
midPoint.x = ((ae->Points()[0].x + ae->Points()[1].x) / 2);
|
||||||
midPoint.y = ((ae->P0().y + ae->P1().y) / 2);
|
midPoint.y = ((ae->Points()[0].y + ae->Points()[1].y) / 2);
|
||||||
nsIntPoint refPoint = midPoint - WidgetToScreenOffset();
|
nsIntPoint refPoint = midPoint - WidgetToScreenOffset();
|
||||||
|
|
||||||
double pinchDist = getDistance(ae->P0(), ae->P1());
|
double pinchDist = getDistance(ae->Points()[0], ae->Points()[1]);
|
||||||
double pinchDelta = 0;
|
double pinchDelta = 0;
|
||||||
|
|
||||||
switch (ae->Action() & AndroidMotionEvent::ACTION_MASK) {
|
switch (ae->Action() & AndroidMotionEvent::ACTION_MASK) {
|
||||||
@ -1612,6 +1675,26 @@ nsWindow::DispatchGestureEvent(PRUint32 msg, PRUint32 direction, double delta,
|
|||||||
DispatchEvent(&event);
|
DispatchEvent(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::DispatchMotionEvent(nsInputEvent &event, AndroidGeckoEvent *ae,
|
||||||
|
const nsIntPoint &refPoint)
|
||||||
|
{
|
||||||
|
nsIntPoint offset = WidgetToScreenOffset();
|
||||||
|
|
||||||
|
event.isShift = PR_FALSE;
|
||||||
|
event.isControl = PR_FALSE;
|
||||||
|
event.isMeta = PR_FALSE;
|
||||||
|
event.isAlt = PR_FALSE;
|
||||||
|
event.time = ae->Time();
|
||||||
|
|
||||||
|
// XXX possibly bound the range of event.refPoint here.
|
||||||
|
// some code may get confused.
|
||||||
|
event.refPoint = refPoint - offset;
|
||||||
|
|
||||||
|
DispatchEvent(&event);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsWindow::InitKeyEvent(nsKeyEvent& event, AndroidGeckoEvent& key)
|
nsWindow::InitKeyEvent(nsKeyEvent& event, AndroidGeckoEvent& key)
|
||||||
{
|
{
|
||||||
|
@ -73,8 +73,9 @@ public:
|
|||||||
|
|
||||||
void OnAndroidEvent(mozilla::AndroidGeckoEvent *ae);
|
void OnAndroidEvent(mozilla::AndroidGeckoEvent *ae);
|
||||||
void OnDraw(mozilla::AndroidGeckoEvent *ae);
|
void OnDraw(mozilla::AndroidGeckoEvent *ae);
|
||||||
|
bool OnMultitouchEvent(mozilla::AndroidGeckoEvent *ae);
|
||||||
|
void OnGestureEvent(mozilla::AndroidGeckoEvent *ae);
|
||||||
void OnMotionEvent(mozilla::AndroidGeckoEvent *ae);
|
void OnMotionEvent(mozilla::AndroidGeckoEvent *ae);
|
||||||
void OnMultitouchEvent(mozilla::AndroidGeckoEvent *ae);
|
|
||||||
void OnKeyEvent(mozilla::AndroidGeckoEvent *ae);
|
void OnKeyEvent(mozilla::AndroidGeckoEvent *ae);
|
||||||
void OnIMEEvent(mozilla::AndroidGeckoEvent *ae);
|
void OnIMEEvent(mozilla::AndroidGeckoEvent *ae);
|
||||||
|
|
||||||
@ -221,7 +222,11 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void InitKeyEvent(nsKeyEvent& event, mozilla::AndroidGeckoEvent& key);
|
void InitKeyEvent(nsKeyEvent& event, mozilla::AndroidGeckoEvent& key);
|
||||||
void DispatchGestureEvent(mozilla::AndroidGeckoEvent *ae);
|
bool DispatchMultitouchEvent(nsTouchEvent &event,
|
||||||
|
mozilla::AndroidGeckoEvent *ae);
|
||||||
|
void DispatchMotionEvent(nsInputEvent &event,
|
||||||
|
mozilla::AndroidGeckoEvent *ae,
|
||||||
|
const nsIntPoint &refPoint);
|
||||||
void DispatchGestureEvent(PRUint32 msg, PRUint32 direction, double delta,
|
void DispatchGestureEvent(PRUint32 msg, PRUint32 direction, double delta,
|
||||||
const nsIntPoint &refPoint, PRUint64 time);
|
const nsIntPoint &refPoint, PRUint64 time);
|
||||||
void HandleSpecialKey(mozilla::AndroidGeckoEvent *ae);
|
void HandleSpecialKey(mozilla::AndroidGeckoEvent *ae);
|
||||||
|
Loading…
Reference in New Issue
Block a user