1 # This file is part of NIT (http://www.nitlanguage.org).
3 # Copyright 2012-2014 Alexis Laferrière <alexis.laf@xymus.net>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 # Pointer and hardware key events
24 #include <android/log.h>
25 #include <android_native_app_glue.h>
27 #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "mnit", __VA_ARGS__))
29 #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "mnit", __VA_ARGS__))
31 #define LOGI(...) (void)0
36 /* Handle inputs from the Android platform and sort them before
37 sending them in the Nit App */
38 static int32_t mnit_handle_input(struct android_app* app, AInputEvent* event) {
39 App nit_app = app->userData;
40 LOGI("handle input %i", (int)pthread_self());
41 if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) {
43 return App_native_input_key(nit_app, event);
45 else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {
47 return App_native_input_motion(nit_app, event);
54 extern class NativeAndroidMotionEvent `{AInputEvent *`}
56 private fun pointers_count: Int `{
57 return AMotionEvent_getPointerCount(recv
);
60 private fun just_went_down: Bool `{
61 return (AMotionEvent_getAction(recv
) & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_DOWN;
64 private fun edge: Int `{
65 return AMotionEvent_getEdgeFlags(recv
);
68 private fun index_down_pointer: Int `{
69 int a
= AMotionEvent_getAction(recv
);
70 if ((a
& AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_POINTER_DOWN)
71 return (a
& AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
75 private fun action: AMotionEventAction `{ return AMotionEvent_getAction(recv); `}
78 extern class AMotionEventAction `{ int32_t `}
79 protected fun action: Int `{ return recv & AMOTION_EVENT_ACTION_MASK; `}
80 fun is_down
: Bool do return action
== 0
81 fun is_up
: Bool do return action
== 1
82 fun is_move
: Bool do return action
== 2
83 fun is_cancel
: Bool do return action
== 3
84 fun is_outside
: Bool do return action
== 4
85 fun is_pointer_down
: Bool do return action
== 5
86 fun is_pointer_up
: Bool do return action
== 6
89 interface AndroidInputEvent
93 class AndroidMotionEvent
94 super AndroidInputEvent
97 private init(ie
: NativeAndroidMotionEvent) do native
= ie
98 private var native
: NativeAndroidMotionEvent
100 private var pointers_cache
: nullable Array[AndroidPointerEvent] = null
101 fun pointers
: Array[AndroidPointerEvent]
103 if pointers_cache
!= null then
104 return pointers_cache
.as(not null)
106 var pointers
= new Array[AndroidPointerEvent]
107 var pointers_count
= native
.pointers_count
108 for i
in [0 .. pointers_count
[do
109 var pointer_event
= new AndroidPointerEvent(self, i
)
110 pointers
.add
(pointer_event
)
112 pointers_cache
= pointers
117 redef fun just_went_down
: Bool do return native
.just_went_down
118 fun edge
: Int do return native
.edge
120 redef fun down_pointer
: nullable AndroidPointerEvent
122 var i
= native
.index_down_pointer
131 class AndroidPointerEvent
133 super AndroidInputEvent
135 protected var motion_event
: AndroidMotionEvent
136 protected var pointer_id
: Int
138 redef fun x
: Float do return native_x
(motion_event
.native
, pointer_id
)
140 private fun native_x
(motion_event
: NativeAndroidMotionEvent, pointer_id
: Int): Float `{
141 return AMotionEvent_getX(motion_event, pointer_id);
144 redef fun y
: Float do return native_y
(motion_event
.native
, pointer_id
)
146 private fun native_y
(motion_event
: NativeAndroidMotionEvent, pointer_id
: Int): Float `{
147 return AMotionEvent_getY(motion_event, pointer_id);
150 fun pressure
: Float do return native_pressure
(motion_event
.native
, pointer_id
)
152 private fun native_pressure
(motion_event
: NativeAndroidMotionEvent, pointer_id
: Int): Float `{
153 return AMotionEvent_getPressure(motion_event, pointer_id);
158 var action
= motion_event
.native
.action
159 return action
.is_down
or action
.is_move
162 redef fun depressed
do return not pressed
165 extern class AndroidKeyEvent `{AInputEvent *`}
167 super AndroidInputEvent
170 return AKeyEvent_getAction(recv
);
172 redef fun is_down: Bool do return action == 0
173 redef fun is_up: Bool do return action == 1
175 fun key_code: Int `{ return AKeyEvent_getKeyCode(recv); `}
178 int code = AKeyEvent_getKeyCode(recv);
179 if (code >= AKEYCODE_0 && code <= AKEYCODE_9)
180 return '0'+code-AKEYCODE_0;
181 if (code >= AKEYCODE_A && code <= AKEYCODE_Z)
182 return 'a'+code-AKEYCODE_A;
186 fun is_back_key
: Bool do return key_code
== 4
187 fun is_menu_key
: Bool do return key_code
== 82
188 fun is_search_key
: Bool do return key_code
== 84
190 fun is_volume_up
: Bool do return key_code
== 24
191 fun is_volume_down
: Bool do return key_code
== 25
196 redef fun init_window
198 set_as_input_handler native_app_glue
202 private fun set_as_input_handler
(app_glue
: NativeAppGlue)
203 import native_input_key
, native_input_motion
`{
204 app_glue->onInputEvent = mnit_handle_input;
207 # these are used as a callback from native to type incoming events
208 private fun native_input_key
(event
: AndroidKeyEvent): Bool is abstract
210 private fun native_input_motion
(event
: NativeAndroidMotionEvent): Bool is abstract