diff options
Diffstat (limited to 'java')
| -rw-r--r-- | java/org/gnu/emacs/EmacsView.java | 2 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsWindow.java | 435 |
2 files changed, 258 insertions, 179 deletions
diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java index bb4dace655a..12d8ff4da56 100644 --- a/java/org/gnu/emacs/EmacsView.java +++ b/java/org/gnu/emacs/EmacsView.java | |||
| @@ -475,7 +475,7 @@ public final class EmacsView extends ViewGroup | |||
| 475 | public boolean | 475 | public boolean |
| 476 | onGenericMotionEvent (MotionEvent motion) | 476 | onGenericMotionEvent (MotionEvent motion) |
| 477 | { | 477 | { |
| 478 | return window.onSomeKindOfMotionEvent (motion); | 478 | return window.onGenericMotionEvent (motion); |
| 479 | } | 479 | } |
| 480 | 480 | ||
| 481 | @Override | 481 | @Override |
diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java index 15d5fe8a175..6816f3e8e71 100644 --- a/java/org/gnu/emacs/EmacsWindow.java +++ b/java/org/gnu/emacs/EmacsWindow.java | |||
| @@ -66,11 +66,20 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 66 | /* Integral coordinate. */ | 66 | /* Integral coordinate. */ |
| 67 | int x, y; | 67 | int x, y; |
| 68 | 68 | ||
| 69 | /* Button associated with the coordinate, or 0 if it is a touch | ||
| 70 | event. */ | ||
| 71 | int button; | ||
| 72 | |||
| 73 | /* Pointer ID associated with the coordinate. */ | ||
| 74 | int id; | ||
| 75 | |||
| 69 | public | 76 | public |
| 70 | Coordinate (int x, int y) | 77 | Coordinate (int x, int y, int button, int id) |
| 71 | { | 78 | { |
| 72 | this.x = x; | 79 | this.x = x; |
| 73 | this.y = y; | 80 | this.y = y; |
| 81 | this.button = button; | ||
| 82 | this.id = id; | ||
| 74 | } | 83 | } |
| 75 | }; | 84 | }; |
| 76 | 85 | ||
| @@ -595,31 +604,6 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 595 | return state; | 604 | return state; |
| 596 | } | 605 | } |
| 597 | 606 | ||
| 598 | /* Return the modifier mask associated with the specified motion | ||
| 599 | EVENT. Replace bits corresponding to Left or Right keys with | ||
| 600 | their corresponding general modifier bits. */ | ||
| 601 | |||
| 602 | private int | ||
| 603 | motionEventModifiers (MotionEvent event) | ||
| 604 | { | ||
| 605 | int state; | ||
| 606 | |||
| 607 | state = event.getMetaState (); | ||
| 608 | |||
| 609 | /* Normalize the state by setting the generic modifier bit if | ||
| 610 | either a left or right modifier is pressed. */ | ||
| 611 | |||
| 612 | if ((state & KeyEvent.META_ALT_LEFT_ON) != 0 | ||
| 613 | || (state & KeyEvent.META_ALT_RIGHT_ON) != 0) | ||
| 614 | state |= KeyEvent.META_ALT_MASK; | ||
| 615 | |||
| 616 | if ((state & KeyEvent.META_CTRL_LEFT_ON) != 0 | ||
| 617 | || (state & KeyEvent.META_CTRL_RIGHT_ON) != 0) | ||
| 618 | state |= KeyEvent.META_CTRL_MASK; | ||
| 619 | |||
| 620 | return state; | ||
| 621 | } | ||
| 622 | |||
| 623 | /* event.getCharacters is used because older input methods still | 607 | /* event.getCharacters is used because older input methods still |
| 624 | require it. */ | 608 | require it. */ |
| 625 | @SuppressWarnings ("deprecation") | 609 | @SuppressWarnings ("deprecation") |
| @@ -710,6 +694,69 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 710 | EmacsNative.sendWindowAction (this.handle, 0); | 694 | EmacsNative.sendWindowAction (this.handle, 0); |
| 711 | } | 695 | } |
| 712 | 696 | ||
| 697 | |||
| 698 | |||
| 699 | /* Mouse and touch event handling. | ||
| 700 | |||
| 701 | Android does not conceptually distinguish between mouse events | ||
| 702 | (those coming from a device whose movement affects the on-screen | ||
| 703 | pointer image) and touch screen events. When a touch, click, or | ||
| 704 | pointer motion takes place, several kinds of event can be sent: | ||
| 705 | |||
| 706 | ACTION_DOWN or ACTION_POINTER_DOWN is sent with a new coordinate | ||
| 707 | and an associated ``pointer ID'' identifying the event when a | ||
| 708 | click or touch takes place. Emacs is responsible for recording | ||
| 709 | both the position of this click for the purpose of determining | ||
| 710 | future changes to the position of that touch. | ||
| 711 | |||
| 712 | ACTION_UP or ACTION_POINTER_UP is sent with a pointer ID when the | ||
| 713 | click associated with a previous ACTION_DOWN event is released. | ||
| 714 | |||
| 715 | ACTION_CANCEL (or ACTION_POINTER_UP with FLAG_CANCELED) is sent | ||
| 716 | if a similar situation transpires: the window system has chosen | ||
| 717 | to grab of the click, and future movement will no longer be | ||
| 718 | reported to Emacs. | ||
| 719 | |||
| 720 | ACTION_MOVE is sent if a coordinate tied to a click that has not | ||
| 721 | been released changes. Emacs processes this event by comparing | ||
| 722 | each of the coordinates within the event with its recollection of | ||
| 723 | those contained within prior ACTION_DOWN and ACTION_MOVE events; | ||
| 724 | the pointer ID of the difference is then reported within a touch | ||
| 725 | or pointer motion event along with its new position. | ||
| 726 | |||
| 727 | The events described above are all sent for both touch and mouse | ||
| 728 | click events. Determining whether an ACTION_DOWN event is | ||
| 729 | associated with a button event is performed by inspecting the | ||
| 730 | mouse button state associated with that event. If it contains | ||
| 731 | any mouse buttons that were not contained in the button state at | ||
| 732 | the time of the last ACTION_DOWN or ACTION_UP event, the | ||
| 733 | coordinate contained within is assumed to be a mouse click, | ||
| 734 | leading to it and associated motion or ACTION_UP events being | ||
| 735 | reported as mouse button or motion events. Otherwise, those | ||
| 736 | events are reported as touch screen events, with the touch ID set | ||
| 737 | to the pointer ID. | ||
| 738 | |||
| 739 | In addition to the events illustrated above, Android also sends | ||
| 740 | several other types of event upon select types of activity from a | ||
| 741 | mouse device: | ||
| 742 | |||
| 743 | ACTION_HOVER_MOVE is sent with the coordinate of the mouse | ||
| 744 | pointer if it moves above a frame prior to any click taking | ||
| 745 | place. Emacs sends a mouse motion event containing the | ||
| 746 | coordinate. | ||
| 747 | |||
| 748 | ACTION_HOVER_ENTER and ACTION_HOVER_LEAVE are respectively sent | ||
| 749 | when the mouse pointer enters and leaves a frame. | ||
| 750 | |||
| 751 | On Android 6.0 and later, ACTION_BUTTON_PRESS is sent with the | ||
| 752 | coordinate of the mouse pointer if a mouse click occurs, | ||
| 753 | alongside a ACTION_DOWN event. ACTION_BUTTON_RELEASE is sent | ||
| 754 | with the same information upon a mouse click being released, also | ||
| 755 | accompanying an ACTION_UP event. | ||
| 756 | |||
| 757 | However, both types of button events are implemented in a buggy | ||
| 758 | fashion and cannot be used to report button events. */ | ||
| 759 | |||
| 713 | /* Look through the button state to determine what button EVENT was | 760 | /* Look through the button state to determine what button EVENT was |
| 714 | generated from. DOWN is true if EVENT is a button press event, | 761 | generated from. DOWN is true if EVENT is a button press event, |
| 715 | false otherwise. Value is the X number of the button. */ | 762 | false otherwise. Value is the X number of the button. */ |
| @@ -719,16 +766,20 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 719 | { | 766 | { |
| 720 | int eventState, notIn; | 767 | int eventState, notIn; |
| 721 | 768 | ||
| 722 | if (Build.VERSION.SDK_INT | 769 | /* Obtain the new button state. */ |
| 723 | < Build.VERSION_CODES.ICE_CREAM_SANDWICH) | ||
| 724 | /* Earlier versions of Android only support one mouse | ||
| 725 | button. */ | ||
| 726 | return 1; | ||
| 727 | |||
| 728 | eventState = event.getButtonState (); | 770 | eventState = event.getButtonState (); |
| 771 | |||
| 772 | /* Compute which button is now set or no longer set. */ | ||
| 773 | |||
| 729 | notIn = (down ? eventState & ~lastButtonState | 774 | notIn = (down ? eventState & ~lastButtonState |
| 730 | : lastButtonState & ~eventState); | 775 | : lastButtonState & ~eventState); |
| 731 | 776 | ||
| 777 | if ((notIn & (MotionEvent.BUTTON_PRIMARY | ||
| 778 | | MotionEvent.BUTTON_SECONDARY | ||
| 779 | | MotionEvent.BUTTON_TERTIARY)) == 0) | ||
| 780 | /* No buttons have been pressed, so this is a touch event. */ | ||
| 781 | return 0; | ||
| 782 | |||
| 732 | if ((notIn & MotionEvent.BUTTON_PRIMARY) != 0) | 783 | if ((notIn & MotionEvent.BUTTON_PRIMARY) != 0) |
| 733 | return 1; | 784 | return 1; |
| 734 | 785 | ||
| @@ -742,53 +793,55 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 742 | return 4; | 793 | return 4; |
| 743 | } | 794 | } |
| 744 | 795 | ||
| 745 | /* Return the ID of the pointer which changed in EVENT. Value is -1 | 796 | /* Return the mouse button associated with the specified ACTION_DOWN |
| 746 | if it could not be determined, else the pointer that changed, or | 797 | or ACTION_POINTER_DOWN EVENT. |
| 747 | -2 if -1 would have been returned, but there is also a pointer | 798 | |
| 748 | that is a mouse. */ | 799 | Value is 0 if no mouse button was pressed, or the X number of |
| 800 | that mouse button. */ | ||
| 749 | 801 | ||
| 750 | private int | 802 | private int |
| 803 | buttonForEvent (MotionEvent event) | ||
| 804 | { | ||
| 805 | /* ICS and earlier don't support true mouse button events, so | ||
| 806 | treat all down events as touch screen events. */ | ||
| 807 | |||
| 808 | if (Build.VERSION.SDK_INT | ||
| 809 | < Build.VERSION_CODES.ICE_CREAM_SANDWICH) | ||
| 810 | return 0; | ||
| 811 | |||
| 812 | return whatButtonWasIt (event, true); | ||
| 813 | } | ||
| 814 | |||
| 815 | /* Return the coordinate object associated with the specified | ||
| 816 | EVENT, or null if it is not known. */ | ||
| 817 | |||
| 818 | private Coordinate | ||
| 751 | figureChange (MotionEvent event) | 819 | figureChange (MotionEvent event) |
| 752 | { | 820 | { |
| 753 | int pointerID, i, truncatedX, truncatedY, pointerIndex; | 821 | int i, truncatedX, truncatedY, pointerIndex, pointerID, count; |
| 754 | Coordinate coordinate; | 822 | Coordinate coordinate; |
| 755 | boolean mouseFlag; | ||
| 756 | 823 | ||
| 757 | /* pointerID is always initialized but the Java compiler is too | 824 | /* Initialize this variable now. */ |
| 758 | dumb to know that. */ | 825 | coordinate = null; |
| 759 | pointerID = -1; | ||
| 760 | mouseFlag = false; | ||
| 761 | 826 | ||
| 762 | switch (event.getActionMasked ()) | 827 | switch (event.getActionMasked ()) |
| 763 | { | 828 | { |
| 764 | case MotionEvent.ACTION_DOWN: | 829 | case MotionEvent.ACTION_DOWN: |
| 765 | /* Primary pointer pressed with index 0. */ | 830 | /* Primary pointer pressed with index 0. */ |
| 766 | 831 | ||
| 767 | /* Detect mice. If this is a mouse event, give it to | ||
| 768 | onSomeKindOfMotionEvent. */ | ||
| 769 | if ((Build.VERSION.SDK_INT | ||
| 770 | >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) | ||
| 771 | && event.getToolType (0) == MotionEvent.TOOL_TYPE_MOUSE) | ||
| 772 | return -2; | ||
| 773 | |||
| 774 | pointerID = event.getPointerId (0); | 832 | pointerID = event.getPointerId (0); |
| 775 | pointerMap.put (pointerID, | 833 | coordinate = new Coordinate ((int) event.getX (0), |
| 776 | new Coordinate ((int) event.getX (0), | 834 | (int) event.getY (0), |
| 777 | (int) event.getY (0))); | 835 | buttonForEvent (event), |
| 836 | pointerID); | ||
| 837 | pointerMap.put (pointerID, coordinate); | ||
| 778 | break; | 838 | break; |
| 779 | 839 | ||
| 780 | case MotionEvent.ACTION_UP: | 840 | case MotionEvent.ACTION_UP: |
| 781 | 841 | case MotionEvent.ACTION_CANCEL: | |
| 782 | /* Detect mice. If this is a mouse event, give it to | ||
| 783 | onSomeKindOfMotionEvent. */ | ||
| 784 | if ((Build.VERSION.SDK_INT | ||
| 785 | >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) | ||
| 786 | && event.getToolType (0) == MotionEvent.TOOL_TYPE_MOUSE) | ||
| 787 | return -2; | ||
| 788 | |||
| 789 | /* Primary pointer released with index 0. */ | 842 | /* Primary pointer released with index 0. */ |
| 790 | pointerID = event.getPointerId (0); | 843 | pointerID = event.getPointerId (0); |
| 791 | pointerMap.remove (pointerID); | 844 | coordinate = pointerMap.remove (pointerID); |
| 792 | break; | 845 | break; |
| 793 | 846 | ||
| 794 | case MotionEvent.ACTION_POINTER_DOWN: | 847 | case MotionEvent.ACTION_POINTER_DOWN: |
| @@ -796,22 +849,26 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 796 | it in the map. */ | 849 | it in the map. */ |
| 797 | pointerIndex = event.getActionIndex (); | 850 | pointerIndex = event.getActionIndex (); |
| 798 | pointerID = event.getPointerId (pointerIndex); | 851 | pointerID = event.getPointerId (pointerIndex); |
| 799 | pointerMap.put (pointerID, | 852 | coordinate = new Coordinate ((int) event.getX (0), |
| 800 | new Coordinate ((int) event.getX (pointerIndex), | 853 | (int) event.getY (0), |
| 801 | (int) event.getY (pointerIndex))); | 854 | buttonForEvent (event), |
| 855 | pointerID); | ||
| 856 | pointerMap.put (pointerID, coordinate); | ||
| 802 | break; | 857 | break; |
| 803 | 858 | ||
| 804 | case MotionEvent.ACTION_POINTER_UP: | 859 | case MotionEvent.ACTION_POINTER_UP: |
| 805 | /* Pointer removed. Remove it from the map. */ | 860 | /* Pointer removed. Remove it from the map. */ |
| 806 | pointerIndex = event.getActionIndex (); | 861 | pointerIndex = event.getActionIndex (); |
| 807 | pointerID = event.getPointerId (pointerIndex); | 862 | pointerID = event.getPointerId (pointerIndex); |
| 808 | pointerMap.remove (pointerID); | 863 | coordinate = pointerMap.remove (pointerID); |
| 809 | break; | 864 | break; |
| 810 | 865 | ||
| 811 | default: | 866 | default: |
| 812 | 867 | ||
| 813 | /* Loop through each pointer in the event. */ | 868 | /* Loop through each pointer in the event. */ |
| 814 | for (i = 0; i < event.getPointerCount (); ++i) | 869 | |
| 870 | count = event.getPointerCount (); | ||
| 871 | for (i = 0; i < count; ++i) | ||
| 815 | { | 872 | { |
| 816 | pointerID = event.getPointerId (i); | 873 | pointerID = event.getPointerId (i); |
| 817 | 874 | ||
| @@ -835,73 +892,152 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 835 | break; | 892 | break; |
| 836 | } | 893 | } |
| 837 | } | 894 | } |
| 838 | |||
| 839 | /* See if this is a mouse. If so, set the mouseFlag. */ | ||
| 840 | if ((Build.VERSION.SDK_INT | ||
| 841 | >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) | ||
| 842 | && event.getToolType (i) == MotionEvent.TOOL_TYPE_MOUSE) | ||
| 843 | mouseFlag = true; | ||
| 844 | } | 895 | } |
| 845 | 896 | ||
| 846 | /* Set the pointer ID to -1 if the loop failed to find any | 897 | /* Set coordinate to NULL if the loop failed to find any |
| 847 | changed pointer. If a mouse pointer was found, set it to | 898 | matching pointer. */ |
| 848 | -2. */ | 899 | |
| 849 | if (i == event.getPointerCount ()) | 900 | if (i == count) |
| 850 | pointerID = (mouseFlag ? -2 : -1); | 901 | coordinate = null; |
| 851 | } | 902 | } |
| 852 | 903 | ||
| 853 | /* Return the pointer ID. */ | 904 | /* Return the pointer ID. */ |
| 854 | return pointerID; | 905 | return coordinate; |
| 855 | } | 906 | } |
| 856 | 907 | ||
| 857 | public boolean | 908 | /* Return the modifier mask associated with the specified motion |
| 858 | onTouchEvent (MotionEvent event) | 909 | EVENT. Replace bits corresponding to Left or Right keys with |
| 910 | their corresponding general modifier bits. */ | ||
| 911 | |||
| 912 | private int | ||
| 913 | motionEventModifiers (MotionEvent event) | ||
| 914 | { | ||
| 915 | int state; | ||
| 916 | |||
| 917 | state = event.getMetaState (); | ||
| 918 | |||
| 919 | /* Normalize the state by setting the generic modifier bit if | ||
| 920 | either a left or right modifier is pressed. */ | ||
| 921 | |||
| 922 | if ((state & KeyEvent.META_ALT_LEFT_ON) != 0 | ||
| 923 | || (state & KeyEvent.META_ALT_RIGHT_ON) != 0) | ||
| 924 | state |= KeyEvent.META_ALT_MASK; | ||
| 925 | |||
| 926 | if ((state & KeyEvent.META_CTRL_LEFT_ON) != 0 | ||
| 927 | || (state & KeyEvent.META_CTRL_RIGHT_ON) != 0) | ||
| 928 | state |= KeyEvent.META_CTRL_MASK; | ||
| 929 | |||
| 930 | return state; | ||
| 931 | } | ||
| 932 | |||
| 933 | /* Process a single ACTION_DOWN, ACTION_POINTER_DOWN, ACTION_UP, | ||
| 934 | ACTION_POINTER_UP, ACTION_CANCEL, or ACTION_MOVE event. | ||
| 935 | |||
| 936 | Ascertain which coordinate changed and send an appropriate mouse | ||
| 937 | or touch screen event. */ | ||
| 938 | |||
| 939 | private void | ||
| 940 | motionEvent (MotionEvent event) | ||
| 859 | { | 941 | { |
| 860 | int pointerID, index; | 942 | Coordinate coordinate; |
| 943 | int modifiers; | ||
| 944 | long time; | ||
| 861 | 945 | ||
| 862 | /* Extract the ``touch ID'' (or in Android, the ``pointer | 946 | /* Find data associated with this event's pointer. Namely, its |
| 863 | ID''.) */ | 947 | current location, whether or not a change has taken place, and |
| 864 | pointerID = figureChange (event); | 948 | whether or not it is a button event. */ |
| 865 | 949 | ||
| 866 | if (pointerID < 0) | 950 | coordinate = figureChange (event); |
| 951 | |||
| 952 | if (coordinate == null) | ||
| 953 | return; | ||
| 954 | |||
| 955 | time = event.getEventTime (); | ||
| 956 | |||
| 957 | if (coordinate.button != 0) | ||
| 867 | { | 958 | { |
| 868 | /* If this is a mouse event, give it to | 959 | /* This event is tied to a mouse click, so report mouse motion |
| 869 | onSomeKindOfMotionEvent. */ | 960 | and button events. */ |
| 870 | if (pointerID == -2) | 961 | |
| 871 | return onSomeKindOfMotionEvent (event); | 962 | modifiers = motionEventModifiers (event); |
| 872 | 963 | ||
| 873 | return false; | 964 | switch (event.getAction ()) |
| 965 | { | ||
| 966 | case MotionEvent.ACTION_POINTER_DOWN: | ||
| 967 | case MotionEvent.ACTION_DOWN: | ||
| 968 | EmacsNative.sendButtonPress (this.handle, coordinate.x, | ||
| 969 | coordinate.y, time, modifiers, | ||
| 970 | coordinate.button); | ||
| 971 | break; | ||
| 972 | |||
| 973 | case MotionEvent.ACTION_POINTER_UP: | ||
| 974 | case MotionEvent.ACTION_UP: | ||
| 975 | case MotionEvent.ACTION_CANCEL: | ||
| 976 | EmacsNative.sendButtonRelease (this.handle, coordinate.x, | ||
| 977 | coordinate.y, time, modifiers, | ||
| 978 | coordinate.button); | ||
| 979 | break; | ||
| 980 | |||
| 981 | case MotionEvent.ACTION_MOVE: | ||
| 982 | EmacsNative.sendMotionNotify (this.handle, coordinate.x, | ||
| 983 | coordinate.y, time); | ||
| 984 | break; | ||
| 985 | } | ||
| 874 | } | 986 | } |
| 987 | else | ||
| 988 | { | ||
| 989 | /* This event is a touch event, and the touch ID is the | ||
| 990 | pointer ID. */ | ||
| 875 | 991 | ||
| 876 | /* Find the pointer index corresponding to the event. */ | 992 | switch (event.getActionMasked ()) |
| 877 | index = event.findPointerIndex (pointerID); | 993 | { |
| 994 | case MotionEvent.ACTION_DOWN: | ||
| 995 | case MotionEvent.ACTION_POINTER_DOWN: | ||
| 996 | /* Touch down event. */ | ||
| 997 | EmacsNative.sendTouchDown (this.handle, coordinate.x, | ||
| 998 | coordinate.y, time, | ||
| 999 | coordinate.id); | ||
| 1000 | break; | ||
| 1001 | |||
| 1002 | case MotionEvent.ACTION_UP: | ||
| 1003 | case MotionEvent.ACTION_POINTER_UP: | ||
| 1004 | case MotionEvent.ACTION_CANCEL: | ||
| 1005 | /* Touch up event. Android documentation says ACTION_CANCEL | ||
| 1006 | should be treated as more or less equivalent to ACTION_UP, | ||
| 1007 | so that is what is done here. */ | ||
| 1008 | EmacsNative.sendTouchUp (this.handle, coordinate.x, | ||
| 1009 | coordinate.y, time, coordinate.id); | ||
| 1010 | break; | ||
| 1011 | |||
| 1012 | case MotionEvent.ACTION_MOVE: | ||
| 1013 | /* Pointer motion event. */ | ||
| 1014 | EmacsNative.sendTouchMove (this.handle, coordinate.x, | ||
| 1015 | coordinate.y, time, coordinate.id); | ||
| 1016 | break; | ||
| 1017 | } | ||
| 1018 | } | ||
| 1019 | |||
| 1020 | if (Build.VERSION.SDK_INT | ||
| 1021 | < Build.VERSION_CODES.ICE_CREAM_SANDWICH) | ||
| 1022 | return; | ||
| 1023 | |||
| 1024 | /* Now update the button state. */ | ||
| 1025 | lastButtonState = event.getButtonState (); | ||
| 1026 | return; | ||
| 1027 | } | ||
| 878 | 1028 | ||
| 1029 | public boolean | ||
| 1030 | onTouchEvent (MotionEvent event) | ||
| 1031 | { | ||
| 879 | switch (event.getActionMasked ()) | 1032 | switch (event.getActionMasked ()) |
| 880 | { | 1033 | { |
| 881 | case MotionEvent.ACTION_DOWN: | 1034 | case MotionEvent.ACTION_DOWN: |
| 882 | case MotionEvent.ACTION_POINTER_DOWN: | 1035 | case MotionEvent.ACTION_POINTER_DOWN: |
| 883 | /* Touch down event. */ | ||
| 884 | EmacsNative.sendTouchDown (this.handle, (int) event.getX (index), | ||
| 885 | (int) event.getY (index), | ||
| 886 | event.getEventTime (), pointerID); | ||
| 887 | return true; | ||
| 888 | |||
| 889 | case MotionEvent.ACTION_UP: | 1036 | case MotionEvent.ACTION_UP: |
| 890 | case MotionEvent.ACTION_POINTER_UP: | 1037 | case MotionEvent.ACTION_POINTER_UP: |
| 891 | case MotionEvent.ACTION_CANCEL: | 1038 | case MotionEvent.ACTION_CANCEL: |
| 892 | /* Touch up event. Android documentation says ACTION_CANCEL | ||
| 893 | should be treated as more or less equivalent to ACTION_UP, | ||
| 894 | so that is what is done here. */ | ||
| 895 | EmacsNative.sendTouchUp (this.handle, (int) event.getX (index), | ||
| 896 | (int) event.getY (index), | ||
| 897 | event.getEventTime (), pointerID); | ||
| 898 | return true; | ||
| 899 | |||
| 900 | case MotionEvent.ACTION_MOVE: | 1039 | case MotionEvent.ACTION_MOVE: |
| 901 | /* Pointer motion event. */ | 1040 | motionEvent (event); |
| 902 | EmacsNative.sendTouchMove (this.handle, (int) event.getX (index), | ||
| 903 | (int) event.getY (index), | ||
| 904 | event.getEventTime (), pointerID); | ||
| 905 | return true; | 1041 | return true; |
| 906 | } | 1042 | } |
| 907 | 1043 | ||
| @@ -909,18 +1045,8 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 909 | } | 1045 | } |
| 910 | 1046 | ||
| 911 | public boolean | 1047 | public boolean |
| 912 | onSomeKindOfMotionEvent (MotionEvent event) | 1048 | onGenericMotionEvent (MotionEvent event) |
| 913 | { | 1049 | { |
| 914 | /* isFromSource is not available until API level 18. */ | ||
| 915 | |||
| 916 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) | ||
| 917 | { | ||
| 918 | if (!event.isFromSource (InputDevice.SOURCE_CLASS_POINTER)) | ||
| 919 | return false; | ||
| 920 | } | ||
| 921 | else if (event.getSource () != InputDevice.SOURCE_CLASS_POINTER) | ||
| 922 | return false; | ||
| 923 | |||
| 924 | switch (event.getAction ()) | 1050 | switch (event.getAction ()) |
| 925 | { | 1051 | { |
| 926 | case MotionEvent.ACTION_HOVER_ENTER: | 1052 | case MotionEvent.ACTION_HOVER_ENTER: |
| @@ -929,7 +1055,6 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 929 | event.getEventTime ()); | 1055 | event.getEventTime ()); |
| 930 | return true; | 1056 | return true; |
| 931 | 1057 | ||
| 932 | case MotionEvent.ACTION_MOVE: | ||
| 933 | case MotionEvent.ACTION_HOVER_MOVE: | 1058 | case MotionEvent.ACTION_HOVER_MOVE: |
| 934 | EmacsNative.sendMotionNotify (this.handle, (int) event.getX (), | 1059 | EmacsNative.sendMotionNotify (this.handle, (int) event.getX (), |
| 935 | (int) event.getY (), | 1060 | (int) event.getY (), |
| @@ -950,64 +1075,16 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 950 | 1075 | ||
| 951 | return true; | 1076 | return true; |
| 952 | 1077 | ||
| 953 | case MotionEvent.ACTION_BUTTON_PRESS: | ||
| 954 | /* Find the button which was pressed. */ | ||
| 955 | EmacsNative.sendButtonPress (this.handle, (int) event.getX (), | ||
| 956 | (int) event.getY (), | ||
| 957 | event.getEventTime (), | ||
| 958 | motionEventModifiers (event), | ||
| 959 | whatButtonWasIt (event, true)); | ||
| 960 | |||
| 961 | if (Build.VERSION.SDK_INT | ||
| 962 | < Build.VERSION_CODES.ICE_CREAM_SANDWICH) | ||
| 963 | return true; | ||
| 964 | |||
| 965 | lastButtonState = event.getButtonState (); | ||
| 966 | return true; | ||
| 967 | |||
| 968 | case MotionEvent.ACTION_BUTTON_RELEASE: | ||
| 969 | /* Find the button which was released. */ | ||
| 970 | EmacsNative.sendButtonRelease (this.handle, (int) event.getX (), | ||
| 971 | (int) event.getY (), | ||
| 972 | event.getEventTime (), | ||
| 973 | motionEventModifiers (event), | ||
| 974 | whatButtonWasIt (event, false)); | ||
| 975 | |||
| 976 | if (Build.VERSION.SDK_INT | ||
| 977 | < Build.VERSION_CODES.ICE_CREAM_SANDWICH) | ||
| 978 | return true; | ||
| 979 | |||
| 980 | lastButtonState = event.getButtonState (); | ||
| 981 | return true; | ||
| 982 | |||
| 983 | case MotionEvent.ACTION_DOWN: | 1078 | case MotionEvent.ACTION_DOWN: |
| 984 | /* Emacs must return true even though touch events are not | 1079 | case MotionEvent.ACTION_POINTER_DOWN: |
| 985 | handled here, because the value of this function is used by | ||
| 986 | the system to decide whether or not Emacs gets ACTION_MOVE | ||
| 987 | events. */ | ||
| 988 | return true; | ||
| 989 | |||
| 990 | case MotionEvent.ACTION_UP: | 1080 | case MotionEvent.ACTION_UP: |
| 991 | /* However, if ACTION_UP reports a different button state from | 1081 | case MotionEvent.ACTION_POINTER_UP: |
| 992 | the last known state, look up which button was released and | 1082 | case MotionEvent.ACTION_CANCEL: |
| 993 | send a ButtonRelease event; this is to work around a bug in | 1083 | case MotionEvent.ACTION_MOVE: |
| 994 | the framework where real ACTION_BUTTON_RELEASE events are | 1084 | /* MotionEvents may either be sent to onGenericMotionEvent or |
| 995 | not delivered. */ | 1085 | onTouchEvent depending on if Android thinks it is a mouse |
| 996 | 1086 | event or not, but we detect them ourselves. */ | |
| 997 | if (Build.VERSION.SDK_INT | 1087 | motionEvent (event); |
| 998 | < Build.VERSION_CODES.ICE_CREAM_SANDWICH) | ||
| 999 | return true; | ||
| 1000 | |||
| 1001 | if (event.getButtonState () == 0 && lastButtonState != 0) | ||
| 1002 | { | ||
| 1003 | EmacsNative.sendButtonRelease (this.handle, (int) event.getX (), | ||
| 1004 | (int) event.getY (), | ||
| 1005 | event.getEventTime (), | ||
| 1006 | motionEventModifiers (event), | ||
| 1007 | whatButtonWasIt (event, false)); | ||
| 1008 | lastButtonState = event.getButtonState (); | ||
| 1009 | } | ||
| 1010 | |||
| 1011 | return true; | 1088 | return true; |
| 1012 | 1089 | ||
| 1013 | case MotionEvent.ACTION_SCROLL: | 1090 | case MotionEvent.ACTION_SCROLL: |
| @@ -1024,6 +1101,8 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 1024 | return false; | 1101 | return false; |
| 1025 | } | 1102 | } |
| 1026 | 1103 | ||
| 1104 | |||
| 1105 | |||
| 1027 | public synchronized void | 1106 | public synchronized void |
| 1028 | reparentTo (final EmacsWindow otherWindow, int x, int y) | 1107 | reparentTo (final EmacsWindow otherWindow, int x, int y) |
| 1029 | { | 1108 | { |