Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 151 additions & 0 deletions hwcomposer/wayland-hwc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
#include "xdg-shell-client-protocol.h"
#include "tablet-unstable-v2-client-protocol.h"
#include "pointer-constraints-unstable-v1-client-protocol.h"
#include "pointer-gestures-unstable-v1-client-protocol.h"
#include "relative-pointer-unstable-v1-client-protocol.h"
#include "idle-inhibit-unstable-v1-client-protocol.h"
#include "fractional-scale-v1-client-protocol.h"
Expand Down Expand Up @@ -1034,6 +1035,15 @@ static const struct wl_pointer_listener pointer_listener = {
};


static bool
empty_touch_id(struct display *display) {
for (int i = 0; i < MAX_TOUCHPOINTS; i++) {
if (display->touch_id[i] != -1)
return false;
}
return true;
}

static int
get_touch_id(struct display *display, int id)
{
Expand Down Expand Up @@ -1284,6 +1294,129 @@ static const struct wl_touch_listener touch_listener = {
touch_handle_orientation,
};

static void
gesture_pinch_begin(void *data, struct zwp_pointer_gesture_pinch_v1 *, uint32_t id, uint32_t, struct wl_surface *, uint32_t)
{
struct display* display = (struct display*)data;

// Do not interrupt active gestures
if (!empty_touch_id(display))
return;

display->gesturePoints[0] = create_touch_id(display, id);
display->gesturePoints[1] = create_touch_id(display, id + 1);
display->gesturePosX = display->ptrPrvX;
display->gesturePosY = display->ptrPrvY;
display->gestureLength = -1;
}

static void
gesture_pinch_update(void *data, struct zwp_pointer_gesture_pinch_v1 *, uint32_t,
wl_fixed_t, wl_fixed_t, wl_fixed_t scale, wl_fixed_t)
{
struct display* display = (struct display*)data;
struct input_event event[11];
struct timespec rt;
double zoom_scale = wl_fixed_to_double(scale);
unsigned int res, n = 0;

if (display->gesturePoints[0] == -1 || display->gesturePoints[1] == -1)
return;

if (ensure_pipe(display, INPUT_TOUCH))
return;

if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
ALOGE("%s:%d error in touch clock_gettime: %s",
__FILE__, __LINE__, strerror(errno));
}

if (display->gestureLength == -1) {
display->gestureLength = display->zoomSensitivity * display->scale * ((zoom_scale < 1) ? 2 : 1);

ADD_EVENT(EV_ABS, ABS_MT_SLOT, display->gesturePoints[0]);
ADD_EVENT(EV_ABS, ABS_MT_TRACKING_ID, display->gesturePoints[0]);
ADD_EVENT(EV_ABS, ABS_MT_POSITION_X, display->gesturePosX - (display->gestureLength / 2));
ADD_EVENT(EV_ABS, ABS_MT_POSITION_Y, display->gesturePosY);
ADD_EVENT(EV_ABS, ABS_MT_PRESSURE, 50);

ADD_EVENT(EV_ABS, ABS_MT_SLOT, display->gesturePoints[1]);
ADD_EVENT(EV_ABS, ABS_MT_TRACKING_ID, display->gesturePoints[1]);
ADD_EVENT(EV_ABS, ABS_MT_POSITION_X, display->gesturePosX + (display->gestureLength / 2));
ADD_EVENT(EV_ABS, ABS_MT_POSITION_Y, display->gesturePosY);
ADD_EVENT(EV_ABS, ABS_MT_PRESSURE, 50);

ADD_EVENT(EV_SYN, SYN_REPORT, 0);

res = write(display->input_fd[INPUT_TOUCH], &event, sizeof(event));
if (res < sizeof(event))
ALOGE("Failed to write event for InputFlinger: %s", strerror(errno));

n = 0;
}

ADD_EVENT(EV_ABS, ABS_MT_SLOT, display->gesturePoints[0]);
ADD_EVENT(EV_ABS, ABS_MT_TRACKING_ID, display->gesturePoints[0]);
ADD_EVENT(EV_ABS, ABS_MT_POSITION_X, display->gesturePosX - (display->gestureLength * zoom_scale / 2));
ADD_EVENT(EV_ABS, ABS_MT_POSITION_Y, display->gesturePosY);
ADD_EVENT(EV_ABS, ABS_MT_PRESSURE, 50);

ADD_EVENT(EV_ABS, ABS_MT_SLOT, display->gesturePoints[1]);
ADD_EVENT(EV_ABS, ABS_MT_TRACKING_ID, display->gesturePoints[1]);
ADD_EVENT(EV_ABS, ABS_MT_POSITION_X, display->gesturePosX + (display->gestureLength * zoom_scale / 2));
ADD_EVENT(EV_ABS, ABS_MT_POSITION_Y, display->gesturePosY);
ADD_EVENT(EV_ABS, ABS_MT_PRESSURE, 50);

ADD_EVENT(EV_SYN, SYN_REPORT, 0);

res = write(display->input_fd[INPUT_TOUCH], &event, sizeof(event));
if (res < sizeof(event))
ALOGE("Failed to write event for InputFlinger: %s", strerror(errno));
}

static void
gesture_pinch_end(void *data, struct zwp_pointer_gesture_pinch_v1 *, uint32_t, uint32_t, int)
{
struct display* display = (struct display*)data;
struct input_event event[6];
struct timespec rt;
int touch_id[2];
unsigned int res, n = 0;

if (display->gesturePoints[0] == -1 || display->gesturePoints[1] == -1)
return;

if (ensure_pipe(display, INPUT_TOUCH))
return;

if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
ALOGE("%s:%d error in touch clock_gettime: %s",
__FILE__, __LINE__, strerror(errno));
}

ADD_EVENT(EV_ABS, ABS_MT_SLOT, display->gesturePoints[0]);
ADD_EVENT(EV_ABS, ABS_MT_TRACKING_ID, -1);
ADD_EVENT(EV_SYN, SYN_REPORT, 0);

ADD_EVENT(EV_ABS, ABS_MT_SLOT, display->gesturePoints[1]);
ADD_EVENT(EV_ABS, ABS_MT_TRACKING_ID, -1);
ADD_EVENT(EV_SYN, SYN_REPORT, 0);

flush_touch_id(display, display->touch_id[display->gesturePoints[0]]);
flush_touch_id(display, display->touch_id[display->gesturePoints[1]]);
display->gesturePoints[0] = display->gesturePoints[1] = -1;

res = write(display->input_fd[INPUT_TOUCH], &event, sizeof(event));
if (res < sizeof(event))
ALOGE("Failed to write event for InputFlinger: %s", strerror(errno));
}

static const struct zwp_pointer_gesture_pinch_v1_listener pinch_listener = {
gesture_pinch_begin,
gesture_pinch_update,
gesture_pinch_end,
};

static void
xdg_wm_base_ping(void *, struct xdg_wm_base *wm_base, uint32_t serial)
{
Expand All @@ -1306,6 +1439,8 @@ seat_handle_capabilities(void *data, struct wl_seat *seat, uint32_t wl_caps)
d->ptrPrvX = 0;
d->ptrPrvY = 0;
d->reverseScroll = property_get_bool("persist.waydroid.reverse_scrolling", false);
d->zoomSensitivity = property_get_int32("persist.waydroid.zoom_sensitivity", 120);
d->gesturePoints[0] = d->gesturePoints[1] = -1;
mkfifo(INPUT_PIPE_NAME[INPUT_POINTER], S_IRWXO | S_IRWXG | S_IRWXU);
chown(INPUT_PIPE_NAME[INPUT_POINTER], 1000, 1000);
wl_pointer_add_listener(d->pointer, &pointer_listener, d);
Expand Down Expand Up @@ -1341,6 +1476,19 @@ seat_handle_capabilities(void *data, struct wl_seat *seat, uint32_t wl_caps)
wl_touch_destroy(d->touch);
d->touch = NULL;
}

if (d->pointer_gestures && d->pointer) {
if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && !d->touch) {
d->input_fd[INPUT_TOUCH] = -1;
mkfifo(INPUT_PIPE_NAME[INPUT_TOUCH], S_IRWXO | S_IRWXG | S_IRWXU);
chown(INPUT_PIPE_NAME[INPUT_TOUCH], 1000, 1000);
for (int i = 0; i < MAX_TOUCHPOINTS; i++)
d->touch_id[i] = -1;
}

d->pointer_gesture_pinch = zwp_pointer_gestures_v1_get_pinch_gesture(d->pointer_gestures, d->pointer);
zwp_pointer_gesture_pinch_v1_add_listener(d->pointer_gesture_pinch, &pinch_listener, d);
}
}

static void
Expand Down Expand Up @@ -1899,6 +2047,9 @@ registry_handle_global(void *data, struct wl_registry *registry,
} else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) {
d->pointer_constraints = (struct zwp_pointer_constraints_v1 *)wl_registry_bind(
registry, id, &zwp_pointer_constraints_v1_interface, 1);
} else if (strcmp(interface, "zwp_pointer_gestures_v1") == 0) {
d->pointer_gestures = (struct zwp_pointer_gestures_v1 *)wl_registry_bind(
registry, id, &zwp_pointer_gestures_v1_interface, 1);
} else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) {
d->relative_pointer_manager = (struct zwp_relative_pointer_manager_v1 *)wl_registry_bind(
registry, id, &zwp_relative_pointer_manager_v1_interface, 1);
Expand Down
7 changes: 7 additions & 0 deletions hwcomposer/wayland-hwc.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,8 @@ struct display {
struct zwp_tablet_manager_v2* tablet_manager;
struct zwp_tablet_seat_v2 *tablet_seat;
struct zwp_pointer_constraints_v1 *pointer_constraints;
struct zwp_pointer_gestures_v1 *pointer_gestures;
struct zwp_pointer_gesture_pinch_v1 *pointer_gesture_pinch;
struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
struct zwp_relative_pointer_v1 *relative_pointer;
struct zwp_idle_inhibit_manager_v1 *idle_manager;
Expand All @@ -339,6 +341,11 @@ struct display {
double wheelAccumulatorY;
bool wheelEvtIsDiscrete;
bool reverseScroll;
int zoomSensitivity;
int gesturePoints[2];
int gesturePosX;
int gesturePosY;
int gestureLength;
int touch_id[MAX_TOUCHPOINTS];
std::map<struct wl_surface *, struct layerFrame> layers;

Expand Down