Skip to content

Commit bdfda8c

Browse files
authored
Merge pull request anbox#1129 from p-an/enable_multitouch
enable multitouch
2 parents 10afc4d + 7b1f588 commit bdfda8c

File tree

2 files changed

+74
-58
lines changed

2 files changed

+74
-58
lines changed

src/anbox/platform/sdl/platform.cpp

Lines changed: 62 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,6 @@ Platform::Platform(
111111
touch_->set_driver_version(1);
112112
touch_->set_input_id({BUS_VIRTUAL, 4, 4, 4});
113113
touch_->set_physical_location("none");
114-
touch_->set_key_bit(BTN_TOUCH);
115-
touch_->set_key_bit(BTN_TOOL_FINGER);
116-
117114
touch_->set_abs_bit(ABS_MT_SLOT);
118115
touch_->set_abs_max(ABS_MT_SLOT, 10);
119116
touch_->set_abs_bit(ABS_MT_TOUCH_MAJOR);
@@ -125,9 +122,12 @@ Platform::Platform(
125122
touch_->set_abs_bit(ABS_MT_POSITION_Y);
126123
touch_->set_abs_max(ABS_MT_POSITION_Y, display_frame.height());
127124
touch_->set_abs_bit(ABS_MT_TRACKING_ID);
128-
touch_->set_abs_max(ABS_MT_TRACKING_ID, 10);
125+
touch_->set_abs_max(ABS_MT_TRACKING_ID, MAX_TRACKING_ID);
129126
touch_->set_prop_bit(INPUT_PROP_DIRECT);
130127

128+
for (int i = 0; i < MAX_FINGERS; i++)
129+
touch_slots[i] = -1;
130+
131131
event_thread_ = std::thread(&Platform::process_events, this);
132132
}
133133

@@ -204,30 +204,14 @@ void Platform::process_input_event(const SDL_Event &event) {
204204
y = event.button.y;
205205
if (!adjust_coordinates(x, y))
206206
break;
207-
208-
touch_events.push_back({EV_ABS, ABS_MT_TRACKING_ID, static_cast<std::int32_t>(emulated_touch_id_)});
209-
touch_events.push_back({EV_ABS, ABS_MT_SLOT, 0});
210-
touch_events.push_back({EV_KEY, BTN_TOUCH, 1});
211-
touch_events.push_back({EV_KEY, BTN_TOOL_FINGER, 1});
212-
213-
touch_events.push_back({EV_ABS, ABS_MT_POSITION_X, x});
214-
touch_events.push_back({EV_ABS, ABS_MT_POSITION_Y, y});
215-
216-
touch_events.push_back({EV_ABS, ABS_MT_TOUCH_MAJOR, 24});
217-
touch_events.push_back({EV_ABS, ABS_MT_TOUCH_MINOR, 24});
218-
219-
touch_events.push_back({EV_SYN, SYN_REPORT, 0});
207+
push_finger_down(x, y, emulated_touch_id_, touch_events);
220208
}
221209
break;
222210
case SDL_MOUSEBUTTONUP:
223211
if (config_.no_touch_emulation) {
224212
mouse_events.push_back({EV_KEY, BTN_LEFT, 0});
225213
} else {
226-
touch_events.push_back({EV_ABS, ABS_MT_TRACKING_ID, -1});
227-
touch_events.push_back({EV_ABS, ABS_MT_SLOT, 0});
228-
touch_events.push_back({EV_KEY, BTN_TOUCH, 0});
229-
touch_events.push_back({EV_KEY, BTN_TOOL_FINGER, 0});
230-
touch_events.push_back({EV_SYN, SYN_REPORT, 0});
214+
push_finger_up(emulated_touch_id_, touch_events);
231215
}
232216
break;
233217
case SDL_MOUSEMOTION:
@@ -248,14 +232,7 @@ void Platform::process_input_event(const SDL_Event &event) {
248232
mouse_events.push_back({EV_REL, REL_X, event.motion.xrel});
249233
mouse_events.push_back({EV_REL, REL_Y, event.motion.yrel});
250234
} else {
251-
touch_events.push_back({EV_ABS, ABS_MT_SLOT, 0});
252-
253-
touch_events.push_back({EV_ABS, ABS_MT_POSITION_X, x});
254-
touch_events.push_back({EV_ABS, ABS_MT_POSITION_Y, y});
255-
256-
touch_events.push_back({EV_ABS, ABS_MT_TOUCH_MAJOR, 24});
257-
touch_events.push_back({EV_ABS, ABS_MT_TOUCH_MINOR, 24});
258-
touch_events.push_back({EV_SYN, SYN_REPORT, 0});
235+
push_finger_motion(x, y, emulated_touch_id_, touch_events);
259236
}
260237
break;
261238
case SDL_MOUSEWHEEL:
@@ -285,44 +262,21 @@ void Platform::process_input_event(const SDL_Event &event) {
285262
}
286263
// Touch screen
287264
case SDL_FINGERDOWN: {
288-
touch_events.push_back({EV_ABS, ABS_MT_TRACKING_ID, static_cast<std::int32_t>(event.tfinger.fingerId)});
289-
touch_events.push_back({EV_ABS, ABS_MT_SLOT, 0});
290-
touch_events.push_back({EV_KEY, BTN_TOUCH, 1});
291-
touch_events.push_back({EV_KEY, BTN_TOOL_FINGER, 1});
292-
293265
if (!calculate_touch_coordinates(event, x, y))
294266
break;
267+
push_finger_down(x, y, event.tfinger.fingerId, touch_events);
295268

296-
touch_events.push_back({EV_ABS, ABS_MT_POSITION_X, x});
297-
touch_events.push_back({EV_ABS, ABS_MT_POSITION_Y, y});
298-
299-
touch_events.push_back({EV_ABS, ABS_MT_TOUCH_MAJOR, 24});
300-
touch_events.push_back({EV_ABS, ABS_MT_TOUCH_MINOR, 24});
301-
302-
touch_events.push_back({EV_SYN, SYN_REPORT, 0});
303269
break;
304270
}
305-
case SDL_FINGERUP: {
306-
touch_events.push_back({EV_ABS, ABS_MT_TRACKING_ID, -1});
307-
touch_events.push_back({EV_ABS, ABS_MT_SLOT, 0});
308-
touch_events.push_back({EV_KEY, BTN_TOUCH, 0});
309-
touch_events.push_back({EV_KEY, BTN_TOOL_FINGER, 0});
310-
touch_events.push_back({EV_SYN, SYN_REPORT, 0});
271+
case SDL_FINGERUP: {
272+
push_finger_up(event.tfinger.fingerId, touch_events);
311273
break;
312274
}
313-
case SDL_FINGERMOTION: {
314-
touch_events.push_back({EV_ABS, ABS_MT_SLOT, 0});
275+
case SDL_FINGERMOTION: {
315276

316277
if (!calculate_touch_coordinates(event, x, y))
317278
break;
318-
319-
touch_events.push_back({EV_ABS, ABS_MT_POSITION_X, x});
320-
touch_events.push_back({EV_ABS, ABS_MT_POSITION_Y, y});
321-
DEBUG("ABS_MT_POSITION: x: %i y: %i", x,y);
322-
323-
touch_events.push_back({EV_ABS, ABS_MT_TOUCH_MAJOR, 24});
324-
touch_events.push_back({EV_ABS, ABS_MT_TOUCH_MINOR, 24});
325-
touch_events.push_back({EV_SYN, SYN_REPORT, 0});
279+
push_finger_motion(x, y, event.tfinger.fingerId, touch_events);
326280
break;
327281
}
328282
default:
@@ -341,6 +295,56 @@ void Platform::process_input_event(const SDL_Event &event) {
341295
touch_->send_events(touch_events);
342296
}
343297

298+
int Platform::find_touch_slot(int id){
299+
for (int i = 0; i < MAX_FINGERS; i++) {
300+
if (touch_slots[i] == id)
301+
return i;
302+
}
303+
return -1;
304+
}
305+
306+
void Platform::push_slot(std::vector<input::Event> &touch_events, int slot){
307+
if (last_slot != slot) {
308+
touch_events.push_back({EV_ABS, ABS_MT_SLOT, slot});
309+
last_slot = slot;
310+
}
311+
}
312+
313+
void Platform::push_finger_down(int x, int y, int finger_id, std::vector<input::Event> &touch_events){
314+
int slot = find_touch_slot(-1);
315+
if (slot == -1) {
316+
DEBUG("no free slot!");
317+
return;
318+
}
319+
touch_slots[slot] = finger_id;
320+
push_slot(touch_events, slot);
321+
touch_events.push_back({EV_ABS, ABS_MT_TRACKING_ID, static_cast<std::int32_t>(finger_id % MAX_TRACKING_ID + 1)});
322+
touch_events.push_back({EV_ABS, ABS_MT_POSITION_X, x});
323+
touch_events.push_back({EV_ABS, ABS_MT_POSITION_Y, y});
324+
touch_events.push_back({EV_SYN, SYN_REPORT, 0});
325+
}
326+
327+
void Platform::push_finger_up(int finger_id, std::vector<input::Event> &touch_events){
328+
int slot = find_touch_slot(finger_id);
329+
if (slot == -1)
330+
return;
331+
push_slot(touch_events, slot);
332+
touch_events.push_back({EV_ABS, ABS_MT_TRACKING_ID, -1});
333+
touch_events.push_back({EV_SYN, SYN_REPORT, 0});
334+
touch_slots[slot] = -1;
335+
}
336+
337+
void Platform::push_finger_motion(int x, int y, int finger_id, std::vector<input::Event> &touch_events){
338+
int slot = find_touch_slot(finger_id);
339+
if (slot == -1)
340+
return;
341+
push_slot(touch_events, slot);
342+
touch_events.push_back({EV_ABS, ABS_MT_POSITION_X, x});
343+
touch_events.push_back({EV_ABS, ABS_MT_POSITION_Y, y});
344+
touch_events.push_back({EV_SYN, SYN_REPORT, 0});
345+
}
346+
347+
344348
bool Platform::adjust_coordinates(std::int32_t &x, std::int32_t &y) {
345349
SDL_Window *window = nullptr;
346350

src/anbox/platform/sdl/platform.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "anbox/platform/sdl/sdl_wrapper.h"
2323
#include "anbox/platform/base_platform.h"
2424
#include "anbox/graphics/emugl/DisplayManager.h"
25+
#include "anbox/input/device.h"
2526

2627
#include <map>
2728
#include <thread>
@@ -97,6 +98,17 @@ class Platform : public std::enable_shared_from_this<Platform>,
9798
bool window_size_immutable_ = false;
9899
std::uint32_t focused_sdl_window_id_ = 0;
99100
Configuration config_;
101+
102+
static const int MAX_FINGERS = 10;
103+
static const int MAX_TRACKING_ID = 10;
104+
int touch_slots[MAX_FINGERS];
105+
int last_slot = -1;
106+
107+
int find_touch_slot(int id);
108+
void push_slot(std::vector<input::Event> &touch_events, int slot);
109+
void push_finger_down(int x, int y, int finger_id, std::vector<input::Event> &touch_events);
110+
void push_finger_up(int finger_id, std::vector<input::Event> &touch_events);
111+
void push_finger_motion(int x, int y, int finger_id, std::vector<input::Event> &touch_events);
100112
};
101113
} // namespace sdl
102114
} // namespace platform

0 commit comments

Comments
 (0)