Multitouch refactor

This commit is contained in:
Niellune
2026-02-28 12:49:27 +02:00
parent 2941444a4c
commit d4fe9a9d66
7 changed files with 281 additions and 30 deletions
+213
View File
@@ -0,0 +1,213 @@
# Decompiled MotionEvent Handler Analysis
## Overview
This function processes an Android `MotionEvent`, normalizes pointer coordinates to a 01 range, packs them into a custom event object, and forwards it to another component.
---
## What It Does
1. Determines whether the event is a **press/move (1)** or **release (0)**:
- `ACTION_DOWN`, `ACTION_POINTER_DOWN`, `ACTION_MOVE` → state = 1
- `ACTION_UP`, `ACTION_POINTER_UP` → state = 0
2. Iterates over active pointers (maximum of 5).
3. For each pointer:
- Gets the pointer ID.
- If pointer ID ≥ 5 → abort and return `true`.
- For `ACTION_POINTER_DOWN` / `ACTION_POINTER_UP`, only processes the pointer at `getActionIndex()`.
4. For each processed pointer:
- Gets raw X/Y coordinates.
- Subtracts offsets.
- Normalizes coordinates into `[0, 1]` using width/height bounds.
- Clamps values to `[0, 1]`.
5. Stores per-pointer data into a custom container:
- Normalized X
- Normalized Y
- State (1 = down/move, 0 = up)
- Pointer ID
6. Sends the packed structure to another component.
7. Always returns `true`.
---
## Clean, Readable Version
```java
public static boolean handleMotionEvent(
MotionEvent event,
int offsetX,
int offsetY,
int width,
int height
) {
TouchPacket packet = new TouchPacket();
int action = event.getActionMasked();
// Determine press state
int state;
if (action == MotionEvent.ACTION_DOWN ||
action == MotionEvent.ACTION_POINTER_DOWN ||
action == MotionEvent.ACTION_MOVE) {
state = 1; // pressed/moving
} else {
state = 0; // released
}
int pointerCount = Math.min(event.getPointerCount(), 5);
for (int i = 0; i < pointerCount; i++) {
int pointerId = event.getPointerId(i);
// Only support pointer IDs 04
if (pointerId >= 5) {
return true;
}
// If pointer down/up, only handle the changed pointer
if (action == MotionEvent.ACTION_POINTER_DOWN ||
action == MotionEvent.ACTION_POINTER_UP) {
int changedPointerId =
event.getPointerId(event.getActionIndex());
if (pointerId != changedPointerId) {
continue;
}
}
float rawX = event.getX(i);
float rawY = event.getY(i);
int x = (int) rawX - offsetX;
int y = (int) rawY - offsetY;
float normX = normalize(x, width);
float normY = normalize(y, height);
packet.addPointer(normX, normY, state, pointerId);
}
TouchSender.send(packet);
return true;
}
private static float normalize(int value, int max) {
if (value <= 0) return 0f;
if (value >= max) return 1f;
return (float) value / (float) max;
}
+1
View File
@@ -2,6 +2,7 @@
#define SRC_HELPER_FUNCTIONS
#include <iostream>
#include <cstring>
#include <SDL2/SDL.h>
#if defined(__linux__) || defined(__APPLE__)
+7
View File
@@ -38,6 +38,8 @@
#define BTN_SIRI 5
#define BTN_MICROPHONE 7
#define BTN_12 12
// Navigation buttons
#define BTN_LEFT 100
#define BTN_RIGHT 101
#define BTN_SELECT_DOWN 104
@@ -45,10 +47,15 @@
#define BTN_BACK 106
#define BTN_DOWN 114
#define BTN_HOME 200
// Play control buttons
#define BTN_PLAY 201
#define BTN_PAUSE 202
#define BTN_203 203 // pause/resume??
#define BTN_NEXT_TRACK 204
#define BTN_PREVIOUS_TRACK 205
// Unknown buttons, volume????
#define BTN_300 300
#define BTN_301 301
#define AUDIO_BUFFER_SIZE 2560
+2
View File
@@ -60,7 +60,9 @@ void processKey(Protocol &protocol, SDL_Keysym key, RunParams &params)
case SDLK_r:
params.dirty = true;
protocol.sendKey(BTN_12);
return;
case SDLK_h:
protocol.sendKey(BTN_HOME);
return;
+15 -15
View File
@@ -153,26 +153,26 @@ void Protocol::sendClick(float x, float y, bool down)
send(CMD_TOUCH, false, buf, 16);
}
void Protocol::sendMultiTouch(const std::vector<Protocol::Touch>& touches)
void Protocol::sendMultiTouch(const Multitouch &touches)
{
if (touches.empty()) return;
int count = touches.size();
if (count == 0)
return;
const size_t touchSize = 16;
const size_t totalSize = touches.size() * touchSize;
uint8_t buf[MUTLITOUCH_MAX_TOUCH * sizeof(Multitouch::Touch)];
uint8_t *p = buf;
std::vector<uint8_t> buf(totalSize);
uint8_t* p = buf.data();
for (const auto& t : touches) {
write_float_le(p + 0, t.x);
write_float_le(p + 4, t.y);
write_uint32_le(p + 8, static_cast<uint32_t>(t.action));
write_uint32_le(p + 12, t.id);
p += touchSize;
for (int i = 0; i < count; ++i)
{
const Multitouch::Touch &t = touches[i];
write_float_le(p + 0, t.x);
write_float_le(p + 4, t.y);
write_uint32_le(p + 8, static_cast<uint32_t>(t.state));
write_uint32_le(p + 12, static_cast<uint32_t>(t.id));
p += 16;
}
send(CMD_MULTI_TOUCH, false, buf.data(), totalSize);
send(CMD_MULTI_TOUCH, false, buf, 16 * count);
}
void Protocol::sendMove(float dx, float dy)
+2 -15
View File
@@ -3,6 +3,7 @@
#include "struct/atomic_queue.h"
#include "struct/message.h"
#include "struct/multitouch.h"
#include "helper/iaudio_sender.h"
#include "settings.h"
#include "connector.h"
@@ -18,20 +19,6 @@ public:
Protocol(const Protocol &) = delete;
Protocol &operator=(const Protocol &) = delete;
enum Action {
UP = 16,
DOWN = 14,
MOVE = 15
};
struct Touch {
float x;
float y;
Action action;
uint32_t id;
};
void start(uint32_t evtStatus, uint32_t evtPhone);
void stop();
@@ -40,7 +27,7 @@ public:
void sendFile(const char *filename, const char *value);
void sendFile(const char *filename, int value);
void sendClick(float x, float y, bool down);
void sendMultiTouch(const std::vector<Touch>& touches);
void sendMultiTouch(const Multitouch &touches);
void sendMove(float dx, float dy);
void sendAudio(uint8_t *data, uint32_t length) override;
+41
View File
@@ -0,0 +1,41 @@
#ifndef SRC_STRUCT_MULTITOUCH
#define SRC_STRUCT_MULTITOUCH
#define MUTLITOUCH_MAX_TOUCH 5
class Multitouch
{
public:
struct Touch
{
float x;
float y;
int state;
int id;
};
Multitouch() : _count(0) {}
bool add(float x, float y, int state, int id)
{
if (_count >= MUTLITOUCH_MAX_TOUCH)
return false;
_touches[_count++] = { x, y, state, id };
return true;
}
int size() const {
return _count;
}
const Touch& operator[](int index) const {
return _touches[index];
}
private:
Touch _touches[MUTLITOUCH_MAX_TOUCH];
int _count;
};
#endif /* SRC_STRUCT_MULTITOUCH */