Merge "Joystick tweaks. (DO NOT MERGE)" into honeycomb-mr1
This commit is contained in:
@ -218115,6 +218115,28 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</field>
|
</field>
|
||||||
|
<field name="AXIS_BRAKE"
|
||||||
|
type="int"
|
||||||
|
transient="false"
|
||||||
|
volatile="false"
|
||||||
|
value="23"
|
||||||
|
static="true"
|
||||||
|
final="true"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
</field>
|
||||||
|
<field name="AXIS_GAS"
|
||||||
|
type="int"
|
||||||
|
transient="false"
|
||||||
|
volatile="false"
|
||||||
|
value="22"
|
||||||
|
static="true"
|
||||||
|
final="true"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
</field>
|
||||||
<field name="AXIS_GENERIC_1"
|
<field name="AXIS_GENERIC_1"
|
||||||
type="int"
|
type="int"
|
||||||
transient="false"
|
transient="false"
|
||||||
@ -218368,6 +218390,17 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</field>
|
</field>
|
||||||
|
<field name="AXIS_RUDDER"
|
||||||
|
type="int"
|
||||||
|
transient="false"
|
||||||
|
volatile="false"
|
||||||
|
value="20"
|
||||||
|
static="true"
|
||||||
|
final="true"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
</field>
|
||||||
<field name="AXIS_RX"
|
<field name="AXIS_RX"
|
||||||
type="int"
|
type="int"
|
||||||
transient="false"
|
transient="false"
|
||||||
@ -218412,6 +218445,17 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</field>
|
</field>
|
||||||
|
<field name="AXIS_THROTTLE"
|
||||||
|
type="int"
|
||||||
|
transient="false"
|
||||||
|
volatile="false"
|
||||||
|
value="19"
|
||||||
|
static="true"
|
||||||
|
final="true"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
</field>
|
||||||
<field name="AXIS_TOOL_MAJOR"
|
<field name="AXIS_TOOL_MAJOR"
|
||||||
type="int"
|
type="int"
|
||||||
transient="false"
|
transient="false"
|
||||||
@ -218467,6 +218511,17 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</field>
|
</field>
|
||||||
|
<field name="AXIS_WHEEL"
|
||||||
|
type="int"
|
||||||
|
transient="false"
|
||||||
|
volatile="false"
|
||||||
|
value="21"
|
||||||
|
static="true"
|
||||||
|
final="true"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
</field>
|
||||||
<field name="AXIS_X"
|
<field name="AXIS_X"
|
||||||
type="int"
|
type="int"
|
||||||
transient="false"
|
transient="false"
|
||||||
|
@ -674,6 +674,87 @@ public final class MotionEvent extends InputEvent implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public static final int AXIS_RTRIGGER = 18;
|
public static final int AXIS_RTRIGGER = 18;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant used to identify the Throttle axis of a motion event.
|
||||||
|
* <p>
|
||||||
|
* <ul>
|
||||||
|
* <li>For a joystick, reports the absolute position of the throttle control.
|
||||||
|
* The value is normalized to a range from 0.0 (fully open) to 1.0 (fully closed).
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @see #getAxisValue(int, int)
|
||||||
|
* @see #getHistoricalAxisValue(int, int, int)
|
||||||
|
* @see MotionEvent.PointerCoords#getAxisValue(int)
|
||||||
|
* @see InputDevice#getMotionRange
|
||||||
|
*/
|
||||||
|
public static final int AXIS_THROTTLE = 19;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant used to identify the Rudder axis of a motion event.
|
||||||
|
* <p>
|
||||||
|
* <ul>
|
||||||
|
* <li>For a joystick, reports the absolute position of the rudder control.
|
||||||
|
* The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right).
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @see #getAxisValue(int, int)
|
||||||
|
* @see #getHistoricalAxisValue(int, int, int)
|
||||||
|
* @see MotionEvent.PointerCoords#getAxisValue(int)
|
||||||
|
* @see InputDevice#getMotionRange
|
||||||
|
*/
|
||||||
|
public static final int AXIS_RUDDER = 20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant used to identify the Wheel axis of a motion event.
|
||||||
|
* <p>
|
||||||
|
* <ul>
|
||||||
|
* <li>For a joystick, reports the absolute position of the steering wheel control.
|
||||||
|
* The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right).
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @see #getAxisValue(int, int)
|
||||||
|
* @see #getHistoricalAxisValue(int, int, int)
|
||||||
|
* @see MotionEvent.PointerCoords#getAxisValue(int)
|
||||||
|
* @see InputDevice#getMotionRange
|
||||||
|
*/
|
||||||
|
public static final int AXIS_WHEEL = 21;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant used to identify the Gas axis of a motion event.
|
||||||
|
* <p>
|
||||||
|
* <ul>
|
||||||
|
* <li>For a joystick, reports the absolute position of the gas (accelerator) control.
|
||||||
|
* The value is normalized to a range from 0.0 (no acceleration)
|
||||||
|
* to 1.0 (maximum acceleration).
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @see #getAxisValue(int, int)
|
||||||
|
* @see #getHistoricalAxisValue(int, int, int)
|
||||||
|
* @see MotionEvent.PointerCoords#getAxisValue(int)
|
||||||
|
* @see InputDevice#getMotionRange
|
||||||
|
*/
|
||||||
|
public static final int AXIS_GAS = 22;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant used to identify the Brake axis of a motion event.
|
||||||
|
* <p>
|
||||||
|
* <ul>
|
||||||
|
* <li>For a joystick, reports the absolute position of the brake control.
|
||||||
|
* The value is normalized to a range from 0.0 (no braking) to 1.0 (maximum braking).
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @see #getAxisValue(int, int)
|
||||||
|
* @see #getHistoricalAxisValue(int, int, int)
|
||||||
|
* @see MotionEvent.PointerCoords#getAxisValue(int)
|
||||||
|
* @see InputDevice#getMotionRange
|
||||||
|
*/
|
||||||
|
public static final int AXIS_BRAKE = 23;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constant used to identify the Generic 1 axis of a motion event.
|
* Constant used to identify the Generic 1 axis of a motion event.
|
||||||
* The interpretation of a generic axis is device-specific.
|
* The interpretation of a generic axis is device-specific.
|
||||||
@ -877,6 +958,11 @@ public final class MotionEvent extends InputEvent implements Parcelable {
|
|||||||
names.append(AXIS_HAT_Y, "AXIS_HAT_Y");
|
names.append(AXIS_HAT_Y, "AXIS_HAT_Y");
|
||||||
names.append(AXIS_LTRIGGER, "AXIS_LTRIGGER");
|
names.append(AXIS_LTRIGGER, "AXIS_LTRIGGER");
|
||||||
names.append(AXIS_RTRIGGER, "AXIS_RTRIGGER");
|
names.append(AXIS_RTRIGGER, "AXIS_RTRIGGER");
|
||||||
|
names.append(AXIS_THROTTLE, "AXIS_THROTTLE");
|
||||||
|
names.append(AXIS_RUDDER, "AXIS_RUDDER");
|
||||||
|
names.append(AXIS_WHEEL, "AXIS_WHEEL");
|
||||||
|
names.append(AXIS_GAS, "AXIS_GAS");
|
||||||
|
names.append(AXIS_BRAKE, "AXIS_BRAKE");
|
||||||
names.append(AXIS_GENERIC_1, "AXIS_GENERIC_1");
|
names.append(AXIS_GENERIC_1, "AXIS_GENERIC_1");
|
||||||
names.append(AXIS_GENERIC_2, "AXIS_GENERIC_2");
|
names.append(AXIS_GENERIC_2, "AXIS_GENERIC_2");
|
||||||
names.append(AXIS_GENERIC_3, "AXIS_GENERIC_3");
|
names.append(AXIS_GENERIC_3, "AXIS_GENERIC_3");
|
||||||
|
@ -409,6 +409,10 @@ axis 0x02 Z
|
|||||||
axis 0x03 RX
|
axis 0x03 RX
|
||||||
axis 0x04 RY
|
axis 0x04 RY
|
||||||
axis 0x05 RZ
|
axis 0x05 RZ
|
||||||
|
axis 0x06 THROTTLE
|
||||||
|
axis 0x07 RUDDER
|
||||||
|
axis 0x08 WHEEL
|
||||||
|
axis 0x09 GAS
|
||||||
|
axis 0x0a BRAKE
|
||||||
axis 0x10 HAT_X
|
axis 0x10 HAT_X
|
||||||
axis 0x11 HAT_Y
|
axis 0x11 HAT_Y
|
||||||
|
|
46
data/keyboards/Vendor_045e_Product_028e.kl
Normal file
46
data/keyboards/Vendor_045e_Product_028e.kl
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Copyright (C) 2011 The Android Open Source Project
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
|
||||||
|
#
|
||||||
|
# XBox 360 USB Controller
|
||||||
|
#
|
||||||
|
|
||||||
|
key 304 BUTTON_A
|
||||||
|
key 305 BUTTON_B
|
||||||
|
key 307 BUTTON_X
|
||||||
|
key 308 BUTTON_Y
|
||||||
|
key 310 BUTTON_L1
|
||||||
|
key 311 BUTTON_R1
|
||||||
|
key 314 BUTTON_SELECT
|
||||||
|
key 315 BUTTON_START
|
||||||
|
key 316 BUTTON_MODE
|
||||||
|
key 317 BUTTON_THUMBL
|
||||||
|
key 318 BUTTON_THUMBR
|
||||||
|
|
||||||
|
# Left and right stick.
|
||||||
|
# The reported value for flat is 128 out of a range from -32767 to 32768, which is absurd.
|
||||||
|
# This confuses applications that rely on the flat value because the joystick actually
|
||||||
|
# settles in a flat range of +/- 4096 or so.
|
||||||
|
axis 0x00 X flat 4096
|
||||||
|
axis 0x01 Y flat 4096
|
||||||
|
axis 0x03 Z flat 4096
|
||||||
|
axis 0x04 RZ flat 4096
|
||||||
|
|
||||||
|
# Triggers.
|
||||||
|
axis 0x02 LTRIGGER
|
||||||
|
axis 0x05 RTRIGGER
|
||||||
|
|
||||||
|
# Hat.
|
||||||
|
axis 0x10 HAT_X
|
||||||
|
axis 0x11 HAT_Y
|
53
data/keyboards/Vendor_046d_Product_c294.kl
Normal file
53
data/keyboards/Vendor_046d_Product_c294.kl
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# Copyright (C) 2011 The Android Open Source Project
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Logitech G25 Racing Wheel (in Compatibility Mode)
|
||||||
|
#
|
||||||
|
|
||||||
|
# 4 way buttons above hat
|
||||||
|
key 0x121 BUTTON_A
|
||||||
|
key 0x123 BUTTON_B
|
||||||
|
key 0x120 BUTTON_X
|
||||||
|
key 0x122 BUTTON_Y
|
||||||
|
|
||||||
|
# Row of buttons under hat
|
||||||
|
key 0x12b BUTTON_1
|
||||||
|
key 0x128 BUTTON_2
|
||||||
|
key 0x129 BUTTON_3
|
||||||
|
key 0x12a BUTTON_4
|
||||||
|
|
||||||
|
# Gear shift positions
|
||||||
|
# 0x12a top-left gear (aliased as BUTTON_4)
|
||||||
|
# 0x12b bottom-left gear (aliased as BUTTON_1)
|
||||||
|
|
||||||
|
# Buttons on wheel
|
||||||
|
key 0x127 BUTTON_L1
|
||||||
|
key 0x126 BUTTON_R1
|
||||||
|
|
||||||
|
# Toggles under wheel
|
||||||
|
key 0x125 BUTTON_L2
|
||||||
|
key 0x124 BUTTON_R2
|
||||||
|
|
||||||
|
# Hat
|
||||||
|
axis 0x10 HAT_X
|
||||||
|
axis 0x11 HAT_Y
|
||||||
|
|
||||||
|
# Steering Wheel
|
||||||
|
axis 0x00 WHEEL
|
||||||
|
|
||||||
|
# Accelerator / Brake
|
||||||
|
# 00..7e : accelerator
|
||||||
|
# 80..ff : brake
|
||||||
|
axis 0x01 split 0x7f GAS BRAKE
|
62
data/keyboards/Vendor_046d_Product_c299.kl
Normal file
62
data/keyboards/Vendor_046d_Product_c299.kl
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
# Copyright (C) 2011 The Android Open Source Project
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Logitech G25 Racing Wheel (in Native Mode)
|
||||||
|
#
|
||||||
|
|
||||||
|
# 4 way buttons above hat
|
||||||
|
key 0x121 BUTTON_A
|
||||||
|
key 0x123 BUTTON_B
|
||||||
|
key 0x120 BUTTON_X
|
||||||
|
key 0x122 BUTTON_Y
|
||||||
|
|
||||||
|
# Row of buttons under hat
|
||||||
|
key 0x12b BUTTON_1
|
||||||
|
key 0x128 BUTTON_2
|
||||||
|
key 0x129 BUTTON_3
|
||||||
|
key 0x12a BUTTON_4
|
||||||
|
|
||||||
|
# Gear shift positions
|
||||||
|
key 0x12c BUTTON_5
|
||||||
|
key 0x12d BUTTON_6
|
||||||
|
key 0x12e BUTTON_7
|
||||||
|
key 0x12f BUTTON_8
|
||||||
|
key 0x2d0 BUTTON_9
|
||||||
|
key 0x2d1 BUTTON_10
|
||||||
|
key 0x2d2 BUTTON_11
|
||||||
|
|
||||||
|
# Buttons on wheel
|
||||||
|
key 0x127 BUTTON_L1
|
||||||
|
key 0x126 BUTTON_R1
|
||||||
|
|
||||||
|
# Toggles under wheel
|
||||||
|
key 0x125 BUTTON_L2
|
||||||
|
key 0x124 BUTTON_R2
|
||||||
|
|
||||||
|
# Hat
|
||||||
|
axis 0x10 HAT_X
|
||||||
|
axis 0x11 HAT_Y
|
||||||
|
|
||||||
|
# Steering Wheel
|
||||||
|
axis 0x00 WHEEL
|
||||||
|
|
||||||
|
# Clutch
|
||||||
|
axis 0x01 invert GENERIC_1
|
||||||
|
|
||||||
|
# Accelerator
|
||||||
|
axis 0x02 invert GAS
|
||||||
|
|
||||||
|
# Brake
|
||||||
|
axis 0x05 invert BRAKE
|
@ -19,7 +19,10 @@ keylayouts := \
|
|||||||
Generic.kl \
|
Generic.kl \
|
||||||
AVRCP.kl \
|
AVRCP.kl \
|
||||||
qwerty.kl \
|
qwerty.kl \
|
||||||
|
Vendor_045e_Product_028e.kl \
|
||||||
Vendor_046d_Product_c216.kl \
|
Vendor_046d_Product_c216.kl \
|
||||||
|
Vendor_046d_Product_c294.kl \
|
||||||
|
Vendor_046d_Product_c299.kl \
|
||||||
Vendor_046d_Product_c532.kl \
|
Vendor_046d_Product_c532.kl \
|
||||||
Vendor_054c_Product_0268.kl \
|
Vendor_054c_Product_0268.kl \
|
||||||
Vendor_05ac_Product_0239.kl \
|
Vendor_05ac_Product_0239.kl \
|
||||||
|
@ -24,6 +24,36 @@
|
|||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
|
struct AxisInfo {
|
||||||
|
enum Mode {
|
||||||
|
// Axis value is reported directly.
|
||||||
|
MODE_NORMAL = 0,
|
||||||
|
// Axis value should be inverted before reporting.
|
||||||
|
MODE_INVERT = 1,
|
||||||
|
// Axis value should be split into two axes
|
||||||
|
MODE_SPLIT = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Axis mode.
|
||||||
|
Mode mode;
|
||||||
|
|
||||||
|
// Axis id.
|
||||||
|
// When split, this is the axis used for values smaller than the split position.
|
||||||
|
int32_t axis;
|
||||||
|
|
||||||
|
// When split, this is the axis used for values after higher than the split position.
|
||||||
|
int32_t highAxis;
|
||||||
|
|
||||||
|
// The split value, or 0 if not split.
|
||||||
|
int32_t splitValue;
|
||||||
|
|
||||||
|
// The flat value, or -1 if none.
|
||||||
|
int32_t flatOverride;
|
||||||
|
|
||||||
|
AxisInfo() : mode(MODE_NORMAL), axis(-1), highAxis(-1), splitValue(0), flatOverride(-1) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes a mapping from keyboard scan codes and joystick axes to Android key codes and axes.
|
* Describes a mapping from keyboard scan codes and joystick axes to Android key codes and axes.
|
||||||
*/
|
*/
|
||||||
@ -36,7 +66,7 @@ public:
|
|||||||
status_t mapKey(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const;
|
status_t mapKey(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const;
|
||||||
status_t findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const;
|
status_t findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const;
|
||||||
|
|
||||||
status_t mapAxis(int32_t scanCode, int32_t* axis) const;
|
status_t mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Key {
|
struct Key {
|
||||||
@ -45,7 +75,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
KeyedVector<int32_t, Key> mKeys;
|
KeyedVector<int32_t, Key> mKeys;
|
||||||
KeyedVector<int32_t, int32_t> mAxes;
|
KeyedVector<int32_t, AxisInfo> mAxes;
|
||||||
|
|
||||||
KeyLayoutMap();
|
KeyLayoutMap();
|
||||||
|
|
||||||
|
@ -270,6 +270,11 @@ static const KeycodeLabel AXES[] = {
|
|||||||
{ "HAT_Y", 16 },
|
{ "HAT_Y", 16 },
|
||||||
{ "LTRIGGER", 17 },
|
{ "LTRIGGER", 17 },
|
||||||
{ "RTRIGGER", 18 },
|
{ "RTRIGGER", 18 },
|
||||||
|
{ "THROTTLE", 19 },
|
||||||
|
{ "RUDDER", 20 },
|
||||||
|
{ "WHEEL", 21 },
|
||||||
|
{ "GAS", 22 },
|
||||||
|
{ "BRAKE", 23 },
|
||||||
{ "GENERIC_1", 32 },
|
{ "GENERIC_1", 32 },
|
||||||
{ "GENERIC_2", 33 },
|
{ "GENERIC_2", 33 },
|
||||||
{ "GENERIC_3", 34 },
|
{ "GENERIC_3", 34 },
|
||||||
|
@ -113,20 +113,23 @@ status_t KeyLayoutMap::findScanCodesForKey(int32_t keyCode, Vector<int32_t>* out
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t KeyLayoutMap::mapAxis(int32_t scanCode, int32_t* axis) const {
|
status_t KeyLayoutMap::mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const {
|
||||||
ssize_t index = mAxes.indexOfKey(scanCode);
|
ssize_t index = mAxes.indexOfKey(scanCode);
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
#if DEBUG_MAPPING
|
#if DEBUG_MAPPING
|
||||||
LOGD("mapAxis: scanCode=%d ~ Failed.", scanCode);
|
LOGD("mapAxis: scanCode=%d ~ Failed.", scanCode);
|
||||||
#endif
|
#endif
|
||||||
*axis = -1;
|
|
||||||
return NAME_NOT_FOUND;
|
return NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
*axis = mAxes.valueAt(index);
|
*outAxisInfo = mAxes.valueAt(index);
|
||||||
|
|
||||||
#if DEBUG_MAPPING
|
#if DEBUG_MAPPING
|
||||||
LOGD("mapAxis: scanCode=%d ~ Result axis=%d.", scanCode, *axis);
|
LOGD("mapAxis: scanCode=%d ~ Result mode=%d, axis=%d, highAxis=%d, "
|
||||||
|
"splitValue=%d, flatOverride=%d.",
|
||||||
|
scanCode,
|
||||||
|
outAxisInfo->mode, outAxisInfo->axis, outAxisInfo->highAxis,
|
||||||
|
outAxisInfo->splitValue, outAxisInfo->flatOverride);
|
||||||
#endif
|
#endif
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
@ -249,19 +252,89 @@ status_t KeyLayoutMap::Parser::parseAxis() {
|
|||||||
return BAD_VALUE;
|
return BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AxisInfo axisInfo;
|
||||||
|
|
||||||
|
mTokenizer->skipDelimiters(WHITESPACE);
|
||||||
|
String8 token = mTokenizer->nextToken(WHITESPACE);
|
||||||
|
if (token == "invert") {
|
||||||
|
axisInfo.mode = AxisInfo::MODE_INVERT;
|
||||||
|
|
||||||
mTokenizer->skipDelimiters(WHITESPACE);
|
mTokenizer->skipDelimiters(WHITESPACE);
|
||||||
String8 axisToken = mTokenizer->nextToken(WHITESPACE);
|
String8 axisToken = mTokenizer->nextToken(WHITESPACE);
|
||||||
int32_t axis = getAxisByLabel(axisToken.string());
|
axisInfo.axis = getAxisByLabel(axisToken.string());
|
||||||
if (axis < 0) {
|
if (axisInfo.axis < 0) {
|
||||||
LOGE("%s: Expected axis label, got '%s'.", mTokenizer->getLocation().string(),
|
LOGE("%s: Expected inverted axis label, got '%s'.",
|
||||||
axisToken.string());
|
mTokenizer->getLocation().string(), axisToken.string());
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
|
} else if (token == "split") {
|
||||||
|
axisInfo.mode = AxisInfo::MODE_SPLIT;
|
||||||
|
|
||||||
|
mTokenizer->skipDelimiters(WHITESPACE);
|
||||||
|
String8 splitToken = mTokenizer->nextToken(WHITESPACE);
|
||||||
|
axisInfo.splitValue = int32_t(strtol(splitToken.string(), &end, 0));
|
||||||
|
if (*end) {
|
||||||
|
LOGE("%s: Expected split value, got '%s'.",
|
||||||
|
mTokenizer->getLocation().string(), splitToken.string());
|
||||||
return BAD_VALUE;
|
return BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mTokenizer->skipDelimiters(WHITESPACE);
|
||||||
|
String8 lowAxisToken = mTokenizer->nextToken(WHITESPACE);
|
||||||
|
axisInfo.axis = getAxisByLabel(lowAxisToken.string());
|
||||||
|
if (axisInfo.axis < 0) {
|
||||||
|
LOGE("%s: Expected low axis label, got '%s'.",
|
||||||
|
mTokenizer->getLocation().string(), lowAxisToken.string());
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mTokenizer->skipDelimiters(WHITESPACE);
|
||||||
|
String8 highAxisToken = mTokenizer->nextToken(WHITESPACE);
|
||||||
|
axisInfo.highAxis = getAxisByLabel(highAxisToken.string());
|
||||||
|
if (axisInfo.highAxis < 0) {
|
||||||
|
LOGE("%s: Expected high axis label, got '%s'.",
|
||||||
|
mTokenizer->getLocation().string(), highAxisToken.string());
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
axisInfo.axis = getAxisByLabel(token.string());
|
||||||
|
if (axisInfo.axis < 0) {
|
||||||
|
LOGE("%s: Expected axis label, 'split' or 'invert', got '%s'.",
|
||||||
|
mTokenizer->getLocation().string(), token.string());
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
mTokenizer->skipDelimiters(WHITESPACE);
|
||||||
|
if (mTokenizer->isEol()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
|
||||||
|
if (keywordToken == "flat") {
|
||||||
|
mTokenizer->skipDelimiters(WHITESPACE);
|
||||||
|
String8 flatToken = mTokenizer->nextToken(WHITESPACE);
|
||||||
|
axisInfo.flatOverride = int32_t(strtol(flatToken.string(), &end, 0));
|
||||||
|
if (*end) {
|
||||||
|
LOGE("%s: Expected flat value, got '%s'.",
|
||||||
|
mTokenizer->getLocation().string(), flatToken.string());
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOGE("%s: Expected keyword 'flat', got '%s'.",
|
||||||
|
mTokenizer->getLocation().string(), keywordToken.string());
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if DEBUG_PARSER
|
#if DEBUG_PARSER
|
||||||
LOGD("Parsed axis: scanCode=%d, axis=%d.", scanCode, axis);
|
LOGD("Parsed axis: scanCode=%d, mode=%d, axis=%d, highAxis=%d, "
|
||||||
|
"splitValue=%d, flatOverride=%d.",
|
||||||
|
scanCode,
|
||||||
|
axisInfo.mode, axisInfo.axis, axisInfo.highAxis,
|
||||||
|
axisInfo.splitValue, axisInfo.flatOverride);
|
||||||
#endif
|
#endif
|
||||||
mMap->mAxes.add(scanCode, axis);
|
mMap->mAxes.add(scanCode, axisInfo);
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,6 +359,11 @@ enum {
|
|||||||
AMOTION_EVENT_AXIS_HAT_Y = 16,
|
AMOTION_EVENT_AXIS_HAT_Y = 16,
|
||||||
AMOTION_EVENT_AXIS_LTRIGGER = 17,
|
AMOTION_EVENT_AXIS_LTRIGGER = 17,
|
||||||
AMOTION_EVENT_AXIS_RTRIGGER = 18,
|
AMOTION_EVENT_AXIS_RTRIGGER = 18,
|
||||||
|
AMOTION_EVENT_AXIS_THROTTLE = 19,
|
||||||
|
AMOTION_EVENT_AXIS_RUDDER = 20,
|
||||||
|
AMOTION_EVENT_AXIS_WHEEL = 21,
|
||||||
|
AMOTION_EVENT_AXIS_GAS = 22,
|
||||||
|
AMOTION_EVENT_AXIS_BRAKE = 23,
|
||||||
AMOTION_EVENT_AXIS_GENERIC_1 = 32,
|
AMOTION_EVENT_AXIS_GENERIC_1 = 32,
|
||||||
AMOTION_EVENT_AXIS_GENERIC_2 = 33,
|
AMOTION_EVENT_AXIS_GENERIC_2 = 33,
|
||||||
AMOTION_EVENT_AXIS_GENERIC_3 = 34,
|
AMOTION_EVENT_AXIS_GENERIC_3 = 34,
|
||||||
|
@ -352,14 +352,13 @@ status_t EventHub::mapKey(int32_t deviceId, int scancode,
|
|||||||
return NAME_NOT_FOUND;
|
return NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t EventHub::mapAxis(int32_t deviceId, int scancode,
|
status_t EventHub::mapAxis(int32_t deviceId, int scancode, AxisInfo* outAxisInfo) const
|
||||||
int32_t* outAxis) const
|
|
||||||
{
|
{
|
||||||
AutoMutex _l(mLock);
|
AutoMutex _l(mLock);
|
||||||
Device* device = getDeviceLocked(deviceId);
|
Device* device = getDeviceLocked(deviceId);
|
||||||
|
|
||||||
if (device && device->keyMap.haveKeyLayout()) {
|
if (device && device->keyMap.haveKeyLayout()) {
|
||||||
status_t err = device->keyMap.keyLayoutMap->mapAxis(scancode, outAxis);
|
status_t err = device->keyMap.keyLayoutMap->mapAxis(scancode, outAxisInfo);
|
||||||
if (err == NO_ERROR) {
|
if (err == NO_ERROR) {
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
@ -369,14 +368,13 @@ status_t EventHub::mapAxis(int32_t deviceId, int scancode,
|
|||||||
device = getDeviceLocked(mBuiltInKeyboardId);
|
device = getDeviceLocked(mBuiltInKeyboardId);
|
||||||
|
|
||||||
if (device && device->keyMap.haveKeyLayout()) {
|
if (device && device->keyMap.haveKeyLayout()) {
|
||||||
status_t err = device->keyMap.keyLayoutMap->mapAxis(scancode, outAxis);
|
status_t err = device->keyMap.keyLayoutMap->mapAxis(scancode, outAxisInfo);
|
||||||
if (err == NO_ERROR) {
|
if (err == NO_ERROR) {
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*outAxis = -1;
|
|
||||||
return NAME_NOT_FOUND;
|
return NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ public:
|
|||||||
int32_t* outKeycode, uint32_t* outFlags) const = 0;
|
int32_t* outKeycode, uint32_t* outFlags) const = 0;
|
||||||
|
|
||||||
virtual status_t mapAxis(int32_t deviceId, int scancode,
|
virtual status_t mapAxis(int32_t deviceId, int scancode,
|
||||||
int32_t* outAxis) const = 0;
|
AxisInfo* outAxisInfo) const = 0;
|
||||||
|
|
||||||
// exclude a particular device from opening
|
// exclude a particular device from opening
|
||||||
// this can be used to ignore input devices for sensors
|
// this can be used to ignore input devices for sensors
|
||||||
@ -235,7 +235,7 @@ public:
|
|||||||
int32_t* outKeycode, uint32_t* outFlags) const;
|
int32_t* outKeycode, uint32_t* outFlags) const;
|
||||||
|
|
||||||
virtual status_t mapAxis(int32_t deviceId, int scancode,
|
virtual status_t mapAxis(int32_t deviceId, int scancode,
|
||||||
int32_t* outAxis) const;
|
AxisInfo* outAxisInfo) const;
|
||||||
|
|
||||||
virtual void addExcludedDevice(const char* deviceName);
|
virtual void addExcludedDevice(const char* deviceName);
|
||||||
|
|
||||||
|
@ -3854,7 +3854,10 @@ void JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
|
|||||||
|
|
||||||
for (size_t i = 0; i < mAxes.size(); i++) {
|
for (size_t i = 0; i < mAxes.size(); i++) {
|
||||||
const Axis& axis = mAxes.valueAt(i);
|
const Axis& axis = mAxes.valueAt(i);
|
||||||
info->addMotionRange(axis.axis, axis.min, axis.max, axis.flat, axis.fuzz);
|
info->addMotionRange(axis.axisInfo.axis, axis.min, axis.max, axis.flat, axis.fuzz);
|
||||||
|
if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
|
||||||
|
info->addMotionRange(axis.axisInfo.highAxis, axis.min, axis.max, axis.flat, axis.fuzz);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3865,18 +3868,29 @@ void JoystickInputMapper::dump(String8& dump) {
|
|||||||
size_t numAxes = mAxes.size();
|
size_t numAxes = mAxes.size();
|
||||||
for (size_t i = 0; i < numAxes; i++) {
|
for (size_t i = 0; i < numAxes; i++) {
|
||||||
const Axis& axis = mAxes.valueAt(i);
|
const Axis& axis = mAxes.valueAt(i);
|
||||||
const char* label = getAxisLabel(axis.axis);
|
const char* label = getAxisLabel(axis.axisInfo.axis);
|
||||||
char name[32];
|
|
||||||
if (label) {
|
if (label) {
|
||||||
strncpy(name, label, sizeof(name));
|
dump.appendFormat(INDENT4 "%s", label);
|
||||||
name[sizeof(name) - 1] = '\0';
|
|
||||||
} else {
|
} else {
|
||||||
snprintf(name, sizeof(name), "%d", axis.axis);
|
dump.appendFormat(INDENT4 "%d", axis.axisInfo.axis);
|
||||||
}
|
}
|
||||||
dump.appendFormat(INDENT4 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, "
|
if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
|
||||||
"scale=%0.3f, offset=%0.3f\n",
|
label = getAxisLabel(axis.axisInfo.highAxis);
|
||||||
name, axis.min, axis.max, axis.flat, axis.fuzz,
|
if (label) {
|
||||||
axis.scale, axis.offset);
|
dump.appendFormat(" / %s (split at %d)", label, axis.axisInfo.splitValue);
|
||||||
|
} else {
|
||||||
|
dump.appendFormat(" / %d (split at %d)", axis.axisInfo.highAxis,
|
||||||
|
axis.axisInfo.splitValue);
|
||||||
|
}
|
||||||
|
} else if (axis.axisInfo.mode == AxisInfo::MODE_INVERT) {
|
||||||
|
dump.append(" (invert)");
|
||||||
|
}
|
||||||
|
|
||||||
|
dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f\n",
|
||||||
|
axis.min, axis.max, axis.flat, axis.fuzz);
|
||||||
|
dump.appendFormat(INDENT4 " scale=%0.5f, offset=%0.5f, "
|
||||||
|
"highScale=%0.5f, highOffset=%0.5f\n",
|
||||||
|
axis.scale, axis.offset, axis.highScale, axis.highOffset);
|
||||||
dump.appendFormat(INDENT4 " rawAxis=%d, rawMin=%d, rawMax=%d, rawFlat=%d, rawFuzz=%d\n",
|
dump.appendFormat(INDENT4 " rawAxis=%d, rawMin=%d, rawMax=%d, rawFlat=%d, rawFuzz=%d\n",
|
||||||
mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
|
mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
|
||||||
axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz);
|
axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz);
|
||||||
@ -3891,25 +3905,38 @@ void JoystickInputMapper::configure() {
|
|||||||
RawAbsoluteAxisInfo rawAxisInfo;
|
RawAbsoluteAxisInfo rawAxisInfo;
|
||||||
getEventHub()->getAbsoluteAxisInfo(getDeviceId(), abs, &rawAxisInfo);
|
getEventHub()->getAbsoluteAxisInfo(getDeviceId(), abs, &rawAxisInfo);
|
||||||
if (rawAxisInfo.valid) {
|
if (rawAxisInfo.valid) {
|
||||||
int32_t axisId;
|
// Map axis.
|
||||||
bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisId);
|
AxisInfo axisInfo;
|
||||||
|
bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
|
||||||
if (!explicitlyMapped) {
|
if (!explicitlyMapped) {
|
||||||
// Axis is not explicitly mapped, will choose a generic axis later.
|
// Axis is not explicitly mapped, will choose a generic axis later.
|
||||||
axisId = -1;
|
axisInfo.mode = AxisInfo::MODE_NORMAL;
|
||||||
|
axisInfo.axis = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply flat override.
|
||||||
|
int32_t rawFlat = axisInfo.flatOverride < 0
|
||||||
|
? rawAxisInfo.flat : axisInfo.flatOverride;
|
||||||
|
|
||||||
|
// Calculate scaling factors and limits.
|
||||||
Axis axis;
|
Axis axis;
|
||||||
if (isCenteredAxis(axisId)) {
|
if (axisInfo.mode == AxisInfo::MODE_SPLIT) {
|
||||||
|
float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue);
|
||||||
|
float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue);
|
||||||
|
axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
|
||||||
|
scale, 0.0f, highScale, 0.0f,
|
||||||
|
0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
|
||||||
|
} else if (isCenteredAxis(axisInfo.axis)) {
|
||||||
float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
|
float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
|
||||||
float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
|
float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
|
||||||
axis.initialize(rawAxisInfo, axisId, explicitlyMapped,
|
axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
|
||||||
scale, offset, -1.0f, 1.0f,
|
scale, offset, scale, offset,
|
||||||
rawAxisInfo.flat * scale, rawAxisInfo.fuzz * scale);
|
-1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
|
||||||
} else {
|
} else {
|
||||||
float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
|
float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
|
||||||
axis.initialize(rawAxisInfo, axisId, explicitlyMapped,
|
axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
|
||||||
scale, 0.0f, 0.0f, 1.0f,
|
scale, 0.0f, scale, 0.0f,
|
||||||
rawAxisInfo.flat * scale, rawAxisInfo.fuzz * scale);
|
0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
// To eliminate noise while the joystick is at rest, filter out small variations
|
// To eliminate noise while the joystick is at rest, filter out small variations
|
||||||
@ -3934,14 +3961,14 @@ void JoystickInputMapper::configure() {
|
|||||||
size_t numAxes = mAxes.size();
|
size_t numAxes = mAxes.size();
|
||||||
for (size_t i = 0; i < numAxes; i++) {
|
for (size_t i = 0; i < numAxes; i++) {
|
||||||
Axis& axis = mAxes.editValueAt(i);
|
Axis& axis = mAxes.editValueAt(i);
|
||||||
if (axis.axis < 0) {
|
if (axis.axisInfo.axis < 0) {
|
||||||
while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
|
while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
|
||||||
&& haveAxis(nextGenericAxisId)) {
|
&& haveAxis(nextGenericAxisId)) {
|
||||||
nextGenericAxisId += 1;
|
nextGenericAxisId += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
|
if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
|
||||||
axis.axis = nextGenericAxisId;
|
axis.axisInfo.axis = nextGenericAxisId;
|
||||||
nextGenericAxisId += 1;
|
nextGenericAxisId += 1;
|
||||||
} else {
|
} else {
|
||||||
LOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
|
LOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
|
||||||
@ -3954,10 +3981,13 @@ void JoystickInputMapper::configure() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JoystickInputMapper::haveAxis(int32_t axis) {
|
bool JoystickInputMapper::haveAxis(int32_t axisId) {
|
||||||
size_t numAxes = mAxes.size();
|
size_t numAxes = mAxes.size();
|
||||||
for (size_t i = 0; i < numAxes; i++) {
|
for (size_t i = 0; i < numAxes; i++) {
|
||||||
if (mAxes.valueAt(i).axis == axis) {
|
const Axis& axis = mAxes.valueAt(i);
|
||||||
|
if (axis.axisInfo.axis == axisId
|
||||||
|
|| (axis.axisInfo.mode == AxisInfo::MODE_SPLIT
|
||||||
|
&& axis.axisInfo.highAxis == axisId)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3987,6 +4017,8 @@ bool JoystickInputMapper::isCenteredAxis(int32_t axis) {
|
|||||||
case AMOTION_EVENT_AXIS_HAT_X:
|
case AMOTION_EVENT_AXIS_HAT_X:
|
||||||
case AMOTION_EVENT_AXIS_HAT_Y:
|
case AMOTION_EVENT_AXIS_HAT_Y:
|
||||||
case AMOTION_EVENT_AXIS_ORIENTATION:
|
case AMOTION_EVENT_AXIS_ORIENTATION:
|
||||||
|
case AMOTION_EVENT_AXIS_RUDDER:
|
||||||
|
case AMOTION_EVENT_AXIS_WHEEL:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@ -4000,7 +4032,7 @@ void JoystickInputMapper::reset() {
|
|||||||
size_t numAxes = mAxes.size();
|
size_t numAxes = mAxes.size();
|
||||||
for (size_t i = 0; i < numAxes; i++) {
|
for (size_t i = 0; i < numAxes; i++) {
|
||||||
Axis& axis = mAxes.editValueAt(i);
|
Axis& axis = mAxes.editValueAt(i);
|
||||||
axis.newValue = 0;
|
axis.resetValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
sync(when, true /*force*/);
|
sync(when, true /*force*/);
|
||||||
@ -4014,10 +4046,34 @@ void JoystickInputMapper::process(const RawEvent* rawEvent) {
|
|||||||
ssize_t index = mAxes.indexOfKey(rawEvent->scanCode);
|
ssize_t index = mAxes.indexOfKey(rawEvent->scanCode);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
Axis& axis = mAxes.editValueAt(index);
|
Axis& axis = mAxes.editValueAt(index);
|
||||||
float newValue = rawEvent->value * axis.scale + axis.offset;
|
float newValue, highNewValue;
|
||||||
if (newValue != axis.newValue) {
|
switch (axis.axisInfo.mode) {
|
||||||
axis.newValue = newValue;
|
case AxisInfo::MODE_INVERT:
|
||||||
|
newValue = (axis.rawAxisInfo.maxValue - rawEvent->value)
|
||||||
|
* axis.scale + axis.offset;
|
||||||
|
highNewValue = 0.0f;
|
||||||
|
break;
|
||||||
|
case AxisInfo::MODE_SPLIT:
|
||||||
|
if (rawEvent->value < axis.axisInfo.splitValue) {
|
||||||
|
newValue = (axis.axisInfo.splitValue - rawEvent->value)
|
||||||
|
* axis.scale + axis.offset;
|
||||||
|
highNewValue = 0.0f;
|
||||||
|
} else if (rawEvent->value > axis.axisInfo.splitValue) {
|
||||||
|
newValue = 0.0f;
|
||||||
|
highNewValue = (rawEvent->value - axis.axisInfo.splitValue)
|
||||||
|
* axis.highScale + axis.highOffset;
|
||||||
|
} else {
|
||||||
|
newValue = 0.0f;
|
||||||
|
highNewValue = 0.0f;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
newValue = rawEvent->value * axis.scale + axis.offset;
|
||||||
|
highNewValue = 0.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
axis.newValue = newValue;
|
||||||
|
axis.highNewValue = highNewValue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -4033,7 +4089,7 @@ void JoystickInputMapper::process(const RawEvent* rawEvent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void JoystickInputMapper::sync(nsecs_t when, bool force) {
|
void JoystickInputMapper::sync(nsecs_t when, bool force) {
|
||||||
if (!force && !haveAxesChangedSignificantly()) {
|
if (!filterAxes(force)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4044,9 +4100,11 @@ void JoystickInputMapper::sync(nsecs_t when, bool force) {
|
|||||||
|
|
||||||
size_t numAxes = mAxes.size();
|
size_t numAxes = mAxes.size();
|
||||||
for (size_t i = 0; i < numAxes; i++) {
|
for (size_t i = 0; i < numAxes; i++) {
|
||||||
Axis& axis = mAxes.editValueAt(i);
|
const Axis& axis = mAxes.valueAt(i);
|
||||||
pointerCoords.setAxisValue(axis.axis, axis.newValue);
|
pointerCoords.setAxisValue(axis.axisInfo.axis, axis.currentValue);
|
||||||
axis.oldValue = axis.newValue;
|
if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
|
||||||
|
pointerCoords.setAxisValue(axis.axisInfo.highAxis, axis.highCurrentValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moving a joystick axis should not wake the devide because joysticks can
|
// Moving a joystick axis should not wake the devide because joysticks can
|
||||||
@ -4061,12 +4119,49 @@ void JoystickInputMapper::sync(nsecs_t when, bool force) {
|
|||||||
1, &pointerId, &pointerCoords, 0, 0, 0);
|
1, &pointerId, &pointerCoords, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JoystickInputMapper::haveAxesChangedSignificantly() {
|
bool JoystickInputMapper::filterAxes(bool force) {
|
||||||
|
bool atLeastOneSignificantChange = force;
|
||||||
size_t numAxes = mAxes.size();
|
size_t numAxes = mAxes.size();
|
||||||
for (size_t i = 0; i < numAxes; i++) {
|
for (size_t i = 0; i < numAxes; i++) {
|
||||||
const Axis& axis = mAxes.valueAt(i);
|
Axis& axis = mAxes.editValueAt(i);
|
||||||
if (axis.newValue != axis.oldValue
|
if (force || hasValueChangedSignificantly(axis.filter,
|
||||||
&& fabs(axis.newValue - axis.oldValue) > axis.filter) {
|
axis.newValue, axis.currentValue, axis.min, axis.max)) {
|
||||||
|
axis.currentValue = axis.newValue;
|
||||||
|
atLeastOneSignificantChange = true;
|
||||||
|
}
|
||||||
|
if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
|
||||||
|
if (force || hasValueChangedSignificantly(axis.filter,
|
||||||
|
axis.highNewValue, axis.highCurrentValue, axis.min, axis.max)) {
|
||||||
|
axis.highCurrentValue = axis.highNewValue;
|
||||||
|
atLeastOneSignificantChange = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return atLeastOneSignificantChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JoystickInputMapper::hasValueChangedSignificantly(
|
||||||
|
float filter, float newValue, float currentValue, float min, float max) {
|
||||||
|
if (newValue != currentValue) {
|
||||||
|
// Filter out small changes in value unless the value is converging on the axis
|
||||||
|
// bounds or center point. This is intended to reduce the amount of information
|
||||||
|
// sent to applications by particularly noisy joysticks (such as PS3).
|
||||||
|
if (fabs(newValue - currentValue) > filter
|
||||||
|
|| hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, min)
|
||||||
|
|| hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, max)
|
||||||
|
|| hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, 0)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JoystickInputMapper::hasMovedNearerToValueWithinFilteredRange(
|
||||||
|
float filter, float newValue, float currentValue, float thresholdValue) {
|
||||||
|
float newDistance = fabs(newValue - thresholdValue);
|
||||||
|
if (newDistance < filter) {
|
||||||
|
float oldDistance = fabs(currentValue - thresholdValue);
|
||||||
|
if (newDistance < oldDistance) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1011,38 +1011,50 @@ public:
|
|||||||
private:
|
private:
|
||||||
struct Axis {
|
struct Axis {
|
||||||
RawAbsoluteAxisInfo rawAxisInfo;
|
RawAbsoluteAxisInfo rawAxisInfo;
|
||||||
|
AxisInfo axisInfo;
|
||||||
|
|
||||||
int32_t axis; // axis id
|
|
||||||
bool explicitlyMapped; // true if the axis was explicitly assigned an axis id
|
bool explicitlyMapped; // true if the axis was explicitly assigned an axis id
|
||||||
|
|
||||||
float scale; // scale factor from raw to normalized values
|
float scale; // scale factor from raw to normalized values
|
||||||
float offset; // offset to add after scaling for normalization
|
float offset; // offset to add after scaling for normalization
|
||||||
|
float highScale; // scale factor from raw to normalized values of high split
|
||||||
|
float highOffset; // offset to add after scaling for normalization of high split
|
||||||
|
|
||||||
float min; // normalized inclusive minimum
|
float min; // normalized inclusive minimum
|
||||||
float max; // normalized inclusive maximum
|
float max; // normalized inclusive maximum
|
||||||
float flat; // normalized flat region size
|
float flat; // normalized flat region size
|
||||||
float fuzz; // normalized error tolerance
|
float fuzz; // normalized error tolerance
|
||||||
|
|
||||||
float oldValue; // previous value
|
|
||||||
float newValue; // most recent value
|
|
||||||
|
|
||||||
float filter; // filter out small variations of this size
|
float filter; // filter out small variations of this size
|
||||||
|
float currentValue; // current value
|
||||||
|
float newValue; // most recent value
|
||||||
|
float highCurrentValue; // current value of high split
|
||||||
|
float highNewValue; // most recent value of high split
|
||||||
|
|
||||||
void initialize(const RawAbsoluteAxisInfo& rawAxisInfo,
|
void initialize(const RawAbsoluteAxisInfo& rawAxisInfo, const AxisInfo& axisInfo,
|
||||||
int32_t axis, bool explicitlyMapped, float scale, float offset,
|
bool explicitlyMapped, float scale, float offset,
|
||||||
|
float highScale, float highOffset,
|
||||||
float min, float max, float flat, float fuzz) {
|
float min, float max, float flat, float fuzz) {
|
||||||
this->rawAxisInfo = rawAxisInfo;
|
this->rawAxisInfo = rawAxisInfo;
|
||||||
this->axis = axis;
|
this->axisInfo = axisInfo;
|
||||||
this->explicitlyMapped = explicitlyMapped;
|
this->explicitlyMapped = explicitlyMapped;
|
||||||
this->scale = scale;
|
this->scale = scale;
|
||||||
this->offset = offset;
|
this->offset = offset;
|
||||||
|
this->highScale = highScale;
|
||||||
|
this->highOffset = highOffset;
|
||||||
this->min = min;
|
this->min = min;
|
||||||
this->max = max;
|
this->max = max;
|
||||||
this->flat = flat;
|
this->flat = flat;
|
||||||
this->fuzz = fuzz;
|
this->fuzz = fuzz;
|
||||||
this->filter = 0;
|
this->filter = 0;
|
||||||
this->oldValue = 0;
|
resetValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetValue() {
|
||||||
|
this->currentValue = 0;
|
||||||
this->newValue = 0;
|
this->newValue = 0;
|
||||||
|
this->highCurrentValue = 0;
|
||||||
|
this->highNewValue = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1051,9 +1063,14 @@ private:
|
|||||||
|
|
||||||
void sync(nsecs_t when, bool force);
|
void sync(nsecs_t when, bool force);
|
||||||
|
|
||||||
bool haveAxis(int32_t axis);
|
bool haveAxis(int32_t axisId);
|
||||||
void pruneAxes(bool ignoreExplicitlyMappedAxes);
|
void pruneAxes(bool ignoreExplicitlyMappedAxes);
|
||||||
bool haveAxesChangedSignificantly();
|
bool filterAxes(bool force);
|
||||||
|
|
||||||
|
static bool hasValueChangedSignificantly(float filter,
|
||||||
|
float newValue, float currentValue, float min, float max);
|
||||||
|
static bool hasMovedNearerToValueWithinFilteredRange(float filter,
|
||||||
|
float newValue, float currentValue, float thresholdValue);
|
||||||
|
|
||||||
static bool isCenteredAxis(int32_t axis);
|
static bool isCenteredAxis(int32_t axis);
|
||||||
};
|
};
|
||||||
|
@ -592,7 +592,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual status_t mapAxis(int32_t deviceId, int scancode,
|
virtual status_t mapAxis(int32_t deviceId, int scancode,
|
||||||
int32_t* outAxis) const {
|
AxisInfo* outAxisInfo) const {
|
||||||
return NAME_NOT_FOUND;
|
return NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user