summaryrefslogtreecommitdiffstats
path: root/awt/java/awt/MouseDispatcher.java
diff options
context:
space:
mode:
Diffstat (limited to 'awt/java/awt/MouseDispatcher.java')
-rw-r--r--awt/java/awt/MouseDispatcher.java418
1 files changed, 418 insertions, 0 deletions
diff --git a/awt/java/awt/MouseDispatcher.java b/awt/java/awt/MouseDispatcher.java
new file mode 100644
index 0000000..df48f9d
--- /dev/null
+++ b/awt/java/awt/MouseDispatcher.java
@@ -0,0 +1,418 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev, Michael Danilov, Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.Dispatcher.MouseGrabManager;
+import java.util.EventListener;
+
+import org.apache.harmony.awt.wtk.NativeEvent;
+import org.apache.harmony.awt.wtk.NativeWindow;
+
+
+class MouseDispatcher {
+
+ // Fields for synthetic mouse click events generation
+ private static final int clickDelta = 5;
+ private final long[] lastPressTime = new long[] {0l, 0l, 0l};
+ private final Point[] lastPressPos = new Point[] {null, null, null};
+ private final boolean[] buttonPressed = new boolean[] {false, false, false};
+ private final int[] clickCount = new int[] {0, 0, 0};
+
+ // Fields for mouse entered/exited support
+ private Component lastUnderPointer = null;
+ private final Point lastScreenPos = new Point(-1, -1);
+
+ // Fields for redundant mouse moved/dragged filtering
+ private Component lastUnderMotion = null;
+ private Point lastLocalPos = new Point(-1, -1);
+
+ private final MouseGrabManager mouseGrabManager;
+ private final Toolkit toolkit;
+
+ static Point convertPoint(Component src, int x, int y, Component dest) {
+ Point srcPoint = getAbsLocation(src);
+ Point destPoint = getAbsLocation(dest);
+
+ return new Point(x + (srcPoint.x - destPoint.x),
+ y + (srcPoint.y - destPoint.y));
+ }
+
+ static Point convertPoint(Component src, Point p, Component dst) {
+ return convertPoint(src, p.x, p.y, dst);
+ }
+
+ private static Point getAbsLocation(Component comp) {
+ Point location = new Point(0, 0);
+// BEGIN android-changed: AWT components not supported
+// for (Component parent = comp; parent != null; parent = parent.parent) {
+// Point parentPos = (parent instanceof EmbeddedWindow ?
+// parent.getNativeWindow().getScreenPos() :
+// parent.getLocation());
+//
+// location.translate(parentPos.x, parentPos.y);
+//
+// if (parent instanceof Window) {
+// break;
+// }
+// }
+// END android-changed
+
+ return location;
+ }
+
+ MouseDispatcher(MouseGrabManager mouseGrabManager,
+ Toolkit toolkit) {
+ this.mouseGrabManager = mouseGrabManager;
+ this.toolkit = toolkit;
+ }
+
+ Point getPointerPos() {
+ return lastScreenPos;
+ }
+
+ boolean dispatch(Component src, NativeEvent event) {
+ int id = event.getEventId();
+
+ lastScreenPos.setLocation(event.getScreenPos());
+ checkMouseEnterExit(event.getInputModifiers(), event.getTime());
+
+ if (id == MouseEvent.MOUSE_WHEEL) {
+// BEGIN android-changed: AWT components not supported
+// dispatchWheelEvent(src, event);
+// END android-changed
+ } else if ((id != MouseEvent.MOUSE_ENTERED) &&
+ (id != MouseEvent.MOUSE_EXITED)) {
+ PointerInfo info = new PointerInfo(src, event.getLocalPos());
+
+ mouseGrabManager.preprocessEvent(event);
+ findEventSource(info);
+ if ((id == MouseEvent.MOUSE_PRESSED) ||
+ (id == MouseEvent.MOUSE_RELEASED)) {
+
+ dispatchButtonEvent(info, event);
+ } else if ((id == MouseEvent.MOUSE_MOVED) ||
+ (id == MouseEvent.MOUSE_DRAGGED)) {
+
+ dispatchMotionEvent(info, event);
+ }
+ }
+
+ return false;
+ }
+
+ private void checkMouseEnterExit(int modifiers, long when) {
+// BEGIN android-changed: AWT components not supported
+// PointerInfo info = findComponentUnderPointer();
+// Component curUnderPointer =
+// propagateEvent(info, AWTEvent.MOUSE_EVENT_MASK,
+// MouseListener.class, false).src;
+//
+// if (curUnderPointer != lastUnderPointer) {
+// Point pos = info.position;
+// if ((lastUnderPointer != null) &&
+// lastUnderPointer.isMouseExitedExpected()) {
+//
+// Point exitPos = convertPoint(null, lastScreenPos.x,
+// lastScreenPos.y, lastUnderPointer);
+//
+// postMouseEnterExit(MouseEvent.MOUSE_EXITED, modifiers, when,
+// exitPos.x, exitPos.y, lastUnderPointer);
+// }
+// setCursor(curUnderPointer);
+// if (curUnderPointer != null) {
+// postMouseEnterExit(MouseEvent.MOUSE_ENTERED, modifiers, when,
+// pos.x, pos.y, curUnderPointer);
+// }
+// lastUnderPointer = curUnderPointer;
+// }
+// END android-changed
+ }
+
+ private void setCursor(Component comp) {
+ if (comp == null) {
+ return;
+ }
+ Component grabOwner = mouseGrabManager.getSyntheticGrabOwner();
+ Component cursorComp = ((grabOwner != null) &&
+ grabOwner.isShowing() ? grabOwner : comp);
+ cursorComp.setCursor();
+ }
+
+ private void postMouseEnterExit(int id, int mod, long when,
+ int x, int y, Component comp) {
+ if (comp.isIndirectlyEnabled()) {
+ toolkit.getSystemEventQueueImpl().postEvent(
+ new MouseEvent(comp, id, when, mod, x, y, 0, false));
+ comp.setMouseExitedExpected(id == MouseEvent.MOUSE_ENTERED);
+ } else {
+ comp.setMouseExitedExpected(false);
+ }
+ }
+
+ // BEGIN android-changed: AWT components not supported
+// private PointerInfo findComponentUnderPointer() {
+// NativeWindow nativeWindow = toolkit.getWindowFactory().
+// getWindowFromPoint(lastScreenPos);
+//
+// if (nativeWindow != null) {
+// Component comp = toolkit.getComponentById(nativeWindow.getId());
+//
+// if (comp != null) {
+// Window window = comp.getWindowAncestor();
+// Point pointerPos = convertPoint(null, lastScreenPos.x,
+// lastScreenPos.y, window);
+//
+// if (window.getClient().contains(pointerPos)) {
+// PointerInfo info = new PointerInfo(window, pointerPos);
+//
+// fall2Child(info);
+//
+// return info;
+// }
+// }
+// }
+//
+// return new PointerInfo(null, null);
+// }
+// END android-changed
+
+ private void findEventSource(PointerInfo info) {
+ Component grabOwner = mouseGrabManager.getSyntheticGrabOwner();
+
+ if (grabOwner != null && grabOwner.isShowing()) {
+ info.position = convertPoint(info.src, info.position, grabOwner);
+ info.src = grabOwner;
+ } else {
+ //???AWT: rise2TopLevel(info);
+ //???AWT: fall2Child(info);
+ }
+ }
+
+ // BEGIN android-changed: AWT components not supported
+// private void rise2TopLevel(PointerInfo info) {
+// while (!(info.src instanceof Window)) {
+// info.position.translate(info.src.x, info.src.y);
+// info.src = info.src.parent;
+// }
+// }
+//
+// private void fall2Child(PointerInfo info) {
+// Insets insets = info.src.getInsets();
+//
+// final Point pos = info.position;
+// final int x = pos.x;
+// final int y = pos.y;
+// if ((x >= insets.left) && (y >= insets.top) &&
+// (x < (info.src.w - insets.right)) &&
+// (y < (info.src.h - insets.bottom)))
+// {
+// Component[] children = ((Container) info.src).getComponents();
+//
+// for (Component child : children) {
+// if (child.isShowing()) {
+// if (child.contains(x - child.getX(),
+// y - child.getY()))
+// {
+// info.src = child;
+// pos.translate(-child.x, -child.y);
+//
+// if (child instanceof Container) {
+// fall2Child(info);
+// }
+//
+// return;
+// }
+// }
+// }
+// }
+// }
+// END android-changed
+
+ private void dispatchButtonEvent(PointerInfo info, NativeEvent event) {
+ int button = event.getMouseButton();
+ long time = event.getTime();
+ int id = event.getEventId();
+ int index = button - 1;
+ boolean clickRequired = false;
+
+ propagateEvent(info, AWTEvent.MOUSE_EVENT_MASK,
+ MouseListener.class, false);
+ if (id == MouseEvent.MOUSE_PRESSED) {
+ int clickInterval = toolkit.dispatcher.clickInterval;
+ mouseGrabManager.onMousePressed(info.src);
+ buttonPressed[index] = true;
+ clickCount[index] = (!deltaExceeded(index, info) &&
+ ((time - lastPressTime[index]) <= clickInterval)) ?
+ clickCount[index] + 1 : 1;
+ lastPressTime[index] = time;
+ lastPressPos[index] = info.position;
+ } else {
+ mouseGrabManager.onMouseReleased(info.src);
+ // set cursor back on synthetic mouse grab end:
+// BEGIN android-changed: AWT components not supported
+// setCursor(findComponentUnderPointer().src);
+// END android-changed
+ if (buttonPressed[index]) {
+ buttonPressed[index] = false;
+ clickRequired = !deltaExceeded(index, info);
+ } else {
+ clickCount[index] = 0;
+ }
+ }
+ if (info.src.isIndirectlyEnabled()) {
+ final Point pos = info.position;
+ final int mod = event.getInputModifiers();
+ toolkit.getSystemEventQueueImpl().postEvent(
+ new MouseEvent(info.src, id, time, mod, pos.x,
+ pos.y, clickCount[index],
+ event.getTrigger(), button));
+ if (clickRequired) {
+ toolkit.getSystemEventQueueImpl().postEvent(
+ new MouseEvent(info.src,
+ MouseEvent.MOUSE_CLICKED,
+ time, mod, pos.x, pos.y,
+ clickCount[index], false,
+ button));
+ }
+ }
+ }
+
+ private boolean deltaExceeded(int index, PointerInfo info) {
+ final Point lastPos = lastPressPos[index];
+ if (lastPos == null) {
+ return true;
+ }
+ return ((Math.abs(lastPos.x - info.position.x) > clickDelta) ||
+ (Math.abs(lastPos.y - info.position.y) > clickDelta));
+ }
+
+ private void dispatchMotionEvent(PointerInfo info, NativeEvent event) {
+ propagateEvent(info, AWTEvent.MOUSE_MOTION_EVENT_MASK,
+ MouseMotionListener.class, false);
+ final Point pos = info.position;
+ if ((lastUnderMotion != info.src) ||
+ !lastLocalPos.equals(pos)) {
+
+ lastUnderMotion = info.src;
+ lastLocalPos = pos;
+
+ if (info.src.isIndirectlyEnabled()) {
+ toolkit.getSystemEventQueueImpl().postEvent(
+ new MouseEvent(info.src, event.getEventId(),
+ event.getTime(),
+ event.getInputModifiers(),
+ pos.x, pos.y, 0, false));
+ }
+ }
+ }
+
+ MouseWheelEvent createWheelEvent(Component src, NativeEvent event,
+ Point where) {
+
+ Integer scrollAmountProperty =
+ (Integer)toolkit.getDesktopProperty("awt.wheelScrollingSize"); //$NON-NLS-1$
+ int amount = 1;
+ int type = MouseWheelEvent.WHEEL_UNIT_SCROLL;
+
+ if (scrollAmountProperty != null) {
+ amount = scrollAmountProperty.intValue();
+ if (amount == -1) {
+ type = MouseWheelEvent.WHEEL_BLOCK_SCROLL;
+ amount = 1;
+ }
+ }
+ return new MouseWheelEvent(src, event.getEventId(),
+ event.getTime(), event.getInputModifiers(),
+ where.x, where.y, 0, false, type, amount,
+ event.getWheelRotation());
+ }
+
+// BEGIN android-changed: AWT components not supported
+// private void dispatchWheelEvent(Component src, NativeEvent event) {
+// PointerInfo info = findComponentUnderPointer();
+//
+// if (info.src == null) {
+// info.src = src;
+// info.position = event.getLocalPos();
+// }
+//
+// propagateEvent(info, AWTEvent.MOUSE_WHEEL_EVENT_MASK,
+// MouseWheelListener.class, true);
+// if ((info.src != null) && info.src.isIndirectlyEnabled()) {
+// toolkit.getSystemEventQueueImpl().postEvent(
+// createWheelEvent(info.src, event, info.position));
+// }
+// }
+// END android-changed
+
+ private PointerInfo propagateEvent(PointerInfo info, long mask,
+ Class<? extends EventListener> type, boolean pierceHW) {
+ Component src = info.src;
+ while ((src != null) &&
+ (src.isLightweight() || pierceHW) &&
+ !(src.isMouseEventEnabled(mask) ||
+ (src.getListeners(type).length > 0))) {
+
+ info.position.translate(src.x, src.y);
+// BEGIN android-changed: AWT components not supported
+// src = src.parent;
+// END android-changed
+ info.src = src;
+ }
+
+ return info;
+ }
+
+// BEGIN android-changed: AWT components not supported
+// Window findWindowAt(Point p) {
+// NativeWindow nativeWindow =
+// toolkit.getWindowFactory().getWindowFromPoint(p);
+//
+// Window window = null;
+// if (nativeWindow != null) {
+// Component comp = toolkit.getComponentById(nativeWindow.getId());
+//
+// if (comp != null) {
+// window = comp.getWindowAncestor();
+// }
+// }
+// return window;
+// }
+// END android-changed
+
+ private class PointerInfo {
+
+ Component src;
+ Point position;
+
+ PointerInfo(Component src, Point position) {
+ this.src = src;
+ this.position = position;
+ }
+
+ }
+
+}