Merge pull request #17195 from RandomShaper/touch-to-mouse-x11-2.1

Generate mouse events from touch on X11 (2.1)
This commit is contained in:
Rémi Verschelde 2018-03-06 10:14:20 +01:00 committed by GitHub
commit b30c46bb9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 2 deletions

View File

@ -1451,6 +1451,10 @@ void OS_X11::process_xevents() {
input_event.ID = ++event_id;
input_event.device = 0;
InputEvent mouse_event;
mouse_event.ID = ++event_id;
mouse_event.device = 0;
XIDeviceEvent *event_data = (XIDeviceEvent *)event.xcookie.data;
int index = event_data->detail;
Point2i pos = Point2i(event_data->event_x, event_data->event_y);
@ -1465,22 +1469,53 @@ void OS_X11::process_xevents() {
bool is_begin = event_data->evtype == XI_TouchBegin;
bool translate = false;
if (is_begin) {
++num_touches;
if (num_touches == 1) {
touch_mouse_index = index;
translate = true;
}
} else {
--num_touches;
if (num_touches == 0) {
translate = true;
} else if (num_touches < 0) { // Defensive
num_touches = 0;
}
touch_mouse_index = -1;
}
input_event.type = InputEvent::SCREEN_TOUCH;
input_event.screen_touch.index = index;
input_event.screen_touch.x = pos.x;
input_event.screen_touch.y = pos.y;
input_event.screen_touch.pressed = is_begin;
if (translate) {
mouse_event.type = InputEvent::MOUSE_BUTTON;
mouse_event.mouse_button.x = pos.x;
mouse_event.mouse_button.y = pos.y;
mouse_event.mouse_button.global_x = pos.x;
mouse_event.mouse_button.global_y = pos.y;
input->set_mouse_pos(pos);
mouse_event.mouse_button.button_index = 1;
mouse_event.mouse_button.pressed = is_begin;
last_mouse_pos = pos;
}
if (is_begin) {
if (touch.state.has(index)) // Defensive
break;
touch.state[index] = pos;
input->parse_input_event(input_event);
input->parse_input_event(mouse_event);
} else {
if (!touch.state.has(index)) // Defensive
break;
touch.state.erase(index);
input->parse_input_event(input_event);
input->parse_input_event(mouse_event);
}
} break;
@ -1500,6 +1535,19 @@ void OS_X11::process_xevents() {
input_event.screen_drag.relative_y = pos.y - curr_pos_elem->value().y;
input->parse_input_event(input_event);
if (index == touch_mouse_index) {
mouse_event.type = InputEvent::MOUSE_MOTION;
mouse_event.mouse_motion.x = pos.x;
mouse_event.mouse_motion.y = pos.y;
mouse_event.mouse_motion.global_x = pos.x;
mouse_event.mouse_motion.global_y = pos.y;
input->set_mouse_pos(pos);
mouse_event.mouse_motion.relative_x = pos.x - last_mouse_pos.x;
mouse_event.mouse_motion.relative_y = pos.y - last_mouse_pos.y;
last_mouse_pos = pos;
input->parse_input_event(mouse_event);
}
curr_pos_elem->value() = pos;
}
} break;
@ -1547,6 +1595,9 @@ void OS_X11::process_xevents() {
/*for (int i = 0; i < touch.devices.size(); ++i) {
XIGrabDevice(x11_display, touch.devices[i], x11_window, CurrentTime, None, XIGrabModeAsync, XIGrabModeAsync, False, &touch.event_mask);
}*/
// Ensure touch mouse is unstuck
touch_mouse_index = -1;
num_touches = 0;
#endif
break;
@ -2328,6 +2379,10 @@ OS_X11::OS_X11() {
minimized = false;
xim_style = 0L;
mouse_mode = MOUSE_MODE_VISIBLE;
#ifdef TOUCH_ENABLED
num_touches = 0;
touch_mouse_index = -1;
#endif
}
void OS_X11::disable_crash_handler() {

View File

@ -132,6 +132,9 @@ class OS_X11 : public OS_Unix {
XIEventMask event_mask;
Map<int, Point2i> state;
} touch;
// For touch-to-mouse
int num_touches;
int touch_mouse_index;
#endif
PhysicsServer *physics_server;