Adds touch support to wlfreerdp

This commit is contained in:
Julian Albrecht 2020-03-25 16:52:30 +01:00 committed by akallabeth
parent a6ccd38b68
commit 7ecce5acbe
4 changed files with 201 additions and 4 deletions

View File

@ -22,10 +22,26 @@
#include <linux/input.h>
#include <freerdp/locale/keyboard.h>
#include <freerdp/client/rdpei.h>
#include <uwac/uwac.h>
#include "wlfreerdp.h"
#include "wlf_input.h"
#define TAG CLIENT_TAG("wayland.input")
#define MAX_CONTACTS 10
typedef struct touch_contact
{
int id;
double pos_x;
double pos_y;
BOOL emulate_mouse;
} touchContact;
static touchContact contacts[MAX_CONTACTS];
BOOL wlf_handle_pointer_enter(freerdp* instance, const UwacPointerEnterLeaveEvent* ev)
{
uint32_t x, y;
@ -191,3 +207,155 @@ BOOL wlf_keyboard_enter(freerdp* instance, const UwacKeyboardEnterLeaveEvent* ev
return freerdp_input_send_focus_in_event(input, 0) &&
freerdp_input_send_mouse_event(input, PTR_FLAGS_MOVE, 0, 0);
}
BOOL wlf_handle_touch_up(freerdp* instance, const UwacTouchUp* ev)
{
uint32_t x, y;
int i;
int touchId;
int contactId;
if (!instance || !ev || !instance->context)
return FALSE;
touchId = ev->id;
for (i = 0; i < MAX_CONTACTS; i++)
{
if (contacts[i].id == touchId)
{
contacts[i].id = 0;
x = contacts[i].pos_x;
y = contacts[i].pos_y;
break;
}
}
WLog_DBG(TAG, "%s called | event_id: %u | x: %u / y: %u", __FUNCTION__, touchId, x, y);
if (!wlf_scale_coordinates(instance->context, &x, &y, TRUE))
return FALSE;
RdpeiClientContext* rdpei = ((wlfContext*) instance->context)->rdpei;
if (contacts[i].emulate_mouse == TRUE)
{
UINT16 flags = 0;
flags |= PTR_FLAGS_BUTTON1;
if ((flags & ~PTR_FLAGS_DOWN) != 0)
return freerdp_input_send_mouse_event(instance->input, flags, x, y);
return TRUE;
}
if (!rdpei)
return FALSE;
rdpei->TouchEnd(rdpei, touchId, x, y, &contactId);
return TRUE;
}
BOOL wlf_handle_touch_down(freerdp* instance, const UwacTouchDown* ev)
{
uint32_t x, y;
int i;
int touchId;
int contactId;
wlfContext* context;
if (!instance || !ev || !instance->context)
return FALSE;
x = ev->x;
y = ev->y;
touchId = ev->id;
WLog_DBG(TAG, "%s called | event_id: %u | x: %u / y: %u", __FUNCTION__, touchId, x, y);
for (i = 0; i < MAX_CONTACTS; i++)
{
if (contacts[i].id == 0)
{
contacts[i].id = touchId;
contacts[i].pos_x = x;
contacts[i].pos_y = y;
contacts[i].emulate_mouse = FALSE;
break;
}
}
if (!wlf_scale_coordinates(instance->context, &x, &y, TRUE))
return FALSE;
context = (wlfContext*)instance->context;
RdpeiClientContext* rdpei = ((wlfContext*) instance->context)->rdpei;
// Emulate mouse click if touch is not possible, like in login screen
if (!rdpei)
{
contacts[i].emulate_mouse = TRUE;
UINT16 flags = 0;
flags |= PTR_FLAGS_DOWN;
flags |= PTR_FLAGS_BUTTON1;
if ((flags & ~PTR_FLAGS_DOWN) != 0)
return freerdp_input_send_mouse_event(instance->input, flags, x, y);
return FALSE;
}
rdpei->TouchBegin(rdpei, touchId, x, y, &contactId);
return TRUE;
}
BOOL wlf_handle_touch_motion(freerdp* instance, const UwacTouchMotion* ev)
{
uint32_t x, y;
int i;
int touchId;
int contactId;
if (!instance || !ev || !instance->context)
return FALSE;
x = ev->x;
y = ev->y;
touchId = ev->id;
for (i = 0; i < MAX_CONTACTS; i++)
{
if (contacts[i].id == touchId)
{
if(contacts[i].pos_x == x && contacts[i].pos_y == y)
{
return TRUE;
}
contacts[i].pos_x = x;
contacts[i].pos_y = y;
break;
}
}
WLog_DBG(TAG, "%s called | event_id: %u | x: %u / y: %u", __FUNCTION__, touchId, x, y);
if (!wlf_scale_coordinates(instance->context, &x, &y, TRUE))
return FALSE;
RdpeiClientContext* rdpei = ((wlfContext*) instance->context)->rdpei;
if (contacts[i].emulate_mouse == TRUE)
{
return TRUE;
}
if (!rdpei)
return FALSE;
rdpei->TouchUpdate(rdpei, touchId, x, y, &contactId);
return TRUE;
}

View File

@ -30,6 +30,9 @@ BOOL wlf_handle_pointer_enter(freerdp* instance, const UwacPointerEnterLeaveEven
BOOL wlf_handle_pointer_motion(freerdp* instance, const UwacPointerMotionEvent* ev);
BOOL wlf_handle_pointer_buttons(freerdp* instance, const UwacPointerButtonEvent* ev);
BOOL wlf_handle_pointer_axis(freerdp* instance, const UwacPointerAxisEvent* ev);
BOOL wlf_handle_touch_up(freerdp* instance, const UwacTouchUp* ev);
BOOL wlf_handle_touch_down(freerdp* instance, const UwacTouchDown* ev);
BOOL wlf_handle_touch_motion(freerdp* instance, const UwacTouchMotion* ev);
BOOL wlf_handle_key(freerdp* instance, const UwacKeyEvent* ev);
BOOL wlf_keyboard_enter(freerdp* instance, const UwacKeyboardEnterLeaveEvent* ev);

View File

@ -352,6 +352,24 @@ static BOOL handle_uwac_events(freerdp* instance, UwacDisplay* display)
break;
case UWAC_EVENT_TOUCH_UP:
if(!wlf_handle_touch_up(instance, &event.touchUp))
return FALSE;
break;
case UWAC_EVENT_TOUCH_DOWN:
if(!wlf_handle_touch_down(instance, &event.touchDown))
return FALSE;
break;
case UWAC_EVENT_TOUCH_MOTION:
if(!wlf_handle_touch_motion(instance, &event.touchMotion))
return FALSE;
break;
case UWAC_EVENT_KEYBOARD_ENTER:
if (instance->context->settings->GrabKeyboard)
UwacSeatInhibitShortcuts(event.keyboard_enter_leave.seat, true);

View File

@ -495,8 +495,12 @@ static void touch_handle_down(void* data, struct wl_touch* wl_touch, uint32_t se
tdata->seat = seat;
tdata->id = id;
tdata->x = x_w;
tdata->y = y_w;
float sx = wl_fixed_to_double(x_w);
float sy = wl_fixed_to_double(y_w);
tdata->x = sx;
tdata->y = sy;
#if 0
struct widget *widget;
@ -597,8 +601,12 @@ static void touch_handle_motion(void* data, struct wl_touch* wl_touch, uint32_t
tdata->seat = seat;
tdata->id = id;
tdata->x = x_w;
tdata->y = y_w;
float sx = wl_fixed_to_double(x_w);
float sy = wl_fixed_to_double(y_w);
tdata->x = sx;
tdata->y = sy;
#if 0
struct touch_point *tp;