/*
 * Copyright © 2010 Intel Corporation
 * Copyright © 2013 Jonas Ådahl
 * Copyright 2017-2018 Collabora, Ltd.
 * Copyright 2017-2018 General Electric Company
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "config.h"

#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <linux/input.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <libinput.h>

#include "compositor.h"
#include "libinput-device.h"
#include "shared/helpers.h"
#include "shared/timespec-util.h"

void
evdev_led_update(struct evdev_device *device, enum weston_led weston_leds)
{
	enum libinput_led leds = 0;

	if (weston_leds & LED_NUM_LOCK)
		leds |= LIBINPUT_LED_NUM_LOCK;
	if (weston_leds & LED_CAPS_LOCK)
		leds |= LIBINPUT_LED_CAPS_LOCK;
	if (weston_leds & LED_SCROLL_LOCK)
		leds |= LIBINPUT_LED_SCROLL_LOCK;

	libinput_device_led_update(device->device, leds);
}

static void
handle_keyboard_key(struct libinput_device *libinput_device,
		    struct libinput_event_keyboard *keyboard_event)
{
	struct evdev_device *device =
		libinput_device_get_user_data(libinput_device);
	int key_state =
		libinput_event_keyboard_get_key_state(keyboard_event);
	int seat_key_count =
		libinput_event_keyboard_get_seat_key_count(keyboard_event);
	struct timespec time;

	/* Ignore key events that are not seat wide state changes. */
	if ((key_state == LIBINPUT_KEY_STATE_PRESSED &&
	     seat_key_count != 1) ||
	    (key_state == LIBINPUT_KEY_STATE_RELEASED &&
	     seat_key_count != 0))
		return;

	timespec_from_usec(&time,
			   libinput_event_keyboard_get_time_usec(keyboard_event));

	notify_key(device->seat, &time,
		   libinput_event_keyboard_get_key(keyboard_event),
		   key_state, STATE_UPDATE_AUTOMATIC);
}

static bool
handle_pointer_motion(struct libinput_device *libinput_device,
		      struct libinput_event_pointer *pointer_event)
{
	struct evdev_device *device =
		libinput_device_get_user_data(libinput_device);
	struct weston_pointer_motion_event event = { 0 };
	struct timespec time;
	double dx_unaccel, dy_unaccel;

	timespec_from_usec(&time,
			   libinput_event_pointer_get_time_usec(pointer_event));
	dx_unaccel = libinput_event_pointer_get_dx_unaccelerated(pointer_event);
	dy_unaccel = libinput_event_pointer_get_dy_unaccelerated(pointer_event);

	event = (struct weston_pointer_motion_event) {
		.mask = WESTON_POINTER_MOTION_REL |
			WESTON_POINTER_MOTION_REL_UNACCEL,
		.time = time,
		.dx = libinput_event_pointer_get_dx(pointer_event),
		.dy = libinput_event_pointer_get_dy(pointer_event),
		.dx_unaccel = dx_unaccel,
		.dy_unaccel = dy_unaccel,
	};

	notify_motion(device->seat, &time, &event);

	return true;
}

static bool
handle_pointer_motion_absolute(
	struct libinput_device *libinput_device,
	struct libinput_event_pointer *pointer_event)
{
	struct evdev_device *device =
		libinput_device_get_user_data(libinput_device);
	struct weston_output *output = device->output;
	struct timespec time;
	double x, y;
	uint32_t width, height;

	if (!output)
		return false;

	timespec_from_usec(&time,
			   libinput_event_pointer_get_time_usec(pointer_event));
	width = device->output->current_mode->width;
	height = device->output->current_mode->height;

	x = libinput_event_pointer_get_absolute_x_transformed(pointer_event,
							      width);
	y = libinput_event_pointer_get_absolute_y_transformed(pointer_event,
							      height);

	weston_output_transform_coordinate(device->output, x, y, &x, &y);
	notify_motion_absolute(device->seat, &time, x, y);

	return true;
}

static bool
handle_pointer_button(struct libinput_device *libinput_device,
		      struct libinput_event_pointer *pointer_event)
{
	struct evdev_device *device =
		libinput_device_get_user_data(libinput_device);
	int button_state =
		libinput_event_pointer_get_button_state(pointer_event);
	int seat_button_count =
		libinput_event_pointer_get_seat_button_count(pointer_event);
	struct timespec time;

	/* Ignore button events that are not seat wide state changes. */
	if ((button_state == LIBINPUT_BUTTON_STATE_PRESSED &&
	     seat_button_count != 1) ||
	    (button_state == LIBINPUT_BUTTON_STATE_RELEASED &&
	     seat_button_count != 0))
		return false;

	timespec_from_usec(&time,
			   libinput_event_pointer_get_time_usec(pointer_event));

	notify_button(device->seat, &time,
		      libinput_event_pointer_get_button(pointer_event),
                      button_state);

	return true;
}

static double
normalize_scroll(struct libinput_event_pointer *pointer_event,
		 enum libinput_pointer_axis axis)
{
	enum libinput_pointer_axis_source source;
	double value = 0.0;

	source = libinput_event_pointer_get_axis_source(pointer_event);
	/* libinput < 0.8 sent wheel click events with value 10. Since 0.8
	   the value is the angle of the click in degrees. To keep
	   backwards-compat with existing clients, we just send multiples of
	   the click count.
	 */
	switch (source) {
	case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
		value = 10 * libinput_event_pointer_get_axis_value_discrete(
								   pointer_event,
								   axis);
		break;
	case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
	case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
		value = libinput_event_pointer_get_axis_value(pointer_event,
							      axis);
		break;
	default:
		assert(!"unhandled event source in normalize_scroll");
	}

	return value;
}

static int32_t
get_axis_discrete(struct libinput_event_pointer *pointer_event,
		  enum libinput_pointer_axis axis)
{
	enum libinput_pointer_axis_source source;

	source = libinput_event_pointer_get_axis_source(pointer_event);

	if (source != LIBINPUT_POINTER_AXIS_SOURCE_WHEEL)
		return 0;

	return libinput_event_pointer_get_axis_value_discrete(pointer_event,
							      axis);
}

static bool
handle_pointer_axis(struct libinput_device *libinput_device,
		    struct libinput_event_pointer *pointer_event)
{
	static int warned;
	struct evdev_device *device =
		libinput_device_get_user_data(libinput_device);
	double vert, horiz;
	int32_t vert_discrete, horiz_discrete;
	enum libinput_pointer_axis axis;
	struct weston_pointer_axis_event weston_event;
	enum libinput_pointer_axis_source source;
	uint32_t wl_axis_source;
	bool has_vert, has_horiz;
	struct timespec time;

	has_vert = libinput_event_pointer_has_axis(pointer_event,
				   LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
	has_horiz = libinput_event_pointer_has_axis(pointer_event,
				   LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);

	if (!has_vert && !has_horiz)
		return false;

	source = libinput_event_pointer_get_axis_source(pointer_event);
	switch (source) {
	case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
		wl_axis_source = WL_POINTER_AXIS_SOURCE_WHEEL;
		break;
	case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
		wl_axis_source = WL_POINTER_AXIS_SOURCE_FINGER;
		break;
	case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
		wl_axis_source = WL_POINTER_AXIS_SOURCE_CONTINUOUS;
		break;
	default:
		if (warned < 5) {
			weston_log("Unknown scroll source %d.\n", source);
			warned++;
		}
		return false;
	}

	notify_axis_source(device->seat, wl_axis_source);

	timespec_from_usec(&time,
			   libinput_event_pointer_get_time_usec(pointer_event));

	if (has_vert) {
		axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
		vert_discrete = get_axis_discrete(pointer_event, axis);
		vert = normalize_scroll(pointer_event, axis);

		weston_event.axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
		weston_event.value = vert;
		weston_event.discrete = vert_discrete;
		weston_event.has_discrete = (vert_discrete != 0);

		notify_axis(device->seat, &time, &weston_event);
	}

	if (has_horiz) {
		axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
		horiz_discrete = get_axis_discrete(pointer_event, axis);
		horiz = normalize_scroll(pointer_event, axis);

		weston_event.axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
		weston_event.value = horiz;
		weston_event.discrete = horiz_discrete;
		weston_event.has_discrete = (horiz_discrete != 0);

		notify_axis(device->seat, &time, &weston_event);
	}

	return true;
}

static struct weston_output *
touch_get_output(struct weston_touch_device *device)
{
	struct evdev_device *evdev_device = device->backend_data;

	return evdev_device->output;
}

static const char *
touch_get_calibration_head_name(struct weston_touch_device *device)
{
	struct evdev_device *evdev_device = device->backend_data;
	struct weston_output *output = evdev_device->output;
	struct weston_head *head;

	if (!output)
		return NULL;

	assert(output->enabled);
	if (evdev_device->output_name)
		return evdev_device->output_name;

	/* No specific head was configured, so the association was made by
	 * the default rule. Just grab whatever head's name.
	 */
	wl_list_for_each(head, &output->head_list, output_link)
		return head->name;

	assert(0);
	return NULL;
}

static void
touch_get_calibration(struct weston_touch_device *device,
		      struct weston_touch_device_matrix *cal)
{
	struct evdev_device *evdev_device = device->backend_data;

	libinput_device_config_calibration_get_matrix(evdev_device->device,
						      cal->m);
}

static void
do_set_calibration(struct evdev_device *evdev_device,
		   const struct weston_touch_device_matrix *cal)
{
	enum libinput_config_status status;

	weston_log("input device %s: applying calibration:\n",
		   libinput_device_get_sysname(evdev_device->device));
	weston_log_continue(STAMP_SPACE "  %f %f %f\n",
			    cal->m[0], cal->m[1], cal->m[2]);
	weston_log_continue(STAMP_SPACE "  %f %f %f\n",
			    cal->m[3], cal->m[4], cal->m[5]);

	status = libinput_device_config_calibration_set_matrix(evdev_device->device,
							       cal->m);
	if (status != LIBINPUT_CONFIG_STATUS_SUCCESS)
		weston_log("Error: Failed to apply calibration.\n");
}

static void
touch_set_calibration(struct weston_touch_device *device,
		      const struct weston_touch_device_matrix *cal)
{
	struct evdev_device *evdev_device = device->backend_data;

	/* Stop output hotplug from reloading the WL_CALIBRATION values.
	 * libinput will maintain the latest calibration for us.
	 */
	evdev_device->override_wl_calibration = true;

	do_set_calibration(evdev_device, cal);
}

static const struct weston_touch_device_ops touch_calibration_ops = {
	.get_output = touch_get_output,
	.get_calibration_head_name = touch_get_calibration_head_name,
	.get_calibration = touch_get_calibration,
	.set_calibration = touch_set_calibration
};

static struct weston_touch_device *
create_touch_device(struct evdev_device *device)
{
	const struct weston_touch_device_ops *ops = NULL;
	struct weston_touch_device *touch_device;
	struct udev_device *udev_device;

	if (libinput_device_config_calibration_has_matrix(device->device))
		ops = &touch_calibration_ops;

	udev_device = libinput_device_get_udev_device(device->device);
	if (!udev_device)
		return NULL;

	touch_device = weston_touch_create_touch_device(device->seat->touch_state,
					udev_device_get_syspath(udev_device),
					device, ops);

	udev_device_unref(udev_device);

	if (!touch_device)
		return NULL;

	weston_log("Touchscreen - %s - %s\n",
		   libinput_device_get_name(device->device),
		   touch_device->syspath);

	return touch_device;
}

static void
handle_touch_with_coords(struct libinput_device *libinput_device,
			 struct libinput_event_touch *touch_event,
			 int touch_type)
{
	struct evdev_device *device =
		libinput_device_get_user_data(libinput_device);
	double x;
	double y;
	uint32_t width, height;
	struct timespec time;
	int32_t slot;

	if (!device->output)
		return;

	timespec_from_usec(&time,
			   libinput_event_touch_get_time_usec(touch_event));
	slot = libinput_event_touch_get_seat_slot(touch_event);

	width = device->output->current_mode->width;
	height = device->output->current_mode->height;
	x =  libinput_event_touch_get_x_transformed(touch_event, width);
	y =  libinput_event_touch_get_y_transformed(touch_event, height);

	weston_output_transform_coordinate(device->output,
					   x, y, &x, &y);

	notify_touch(device->seat, &time, slot, x, y, touch_type);
}

static void
handle_touch_down(struct libinput_device *device,
		  struct libinput_event_touch *touch_event)
{
	handle_touch_with_coords(device, touch_event, WL_TOUCH_DOWN);
}

static void
handle_touch_motion(struct libinput_device *device,
		    struct libinput_event_touch *touch_event)
{
	handle_touch_with_coords(device, touch_event, WL_TOUCH_MOTION);
}

static void
handle_touch_up(struct libinput_device *libinput_device,
		struct libinput_event_touch *touch_event)
{
	struct evdev_device *device =
		libinput_device_get_user_data(libinput_device);
	struct timespec time;
	int32_t slot = libinput_event_touch_get_seat_slot(touch_event);

	timespec_from_usec(&time,
			   libinput_event_touch_get_time_usec(touch_event));

	notify_touch(device->seat, &time, slot, 0, 0, WL_TOUCH_UP);
}

static void
handle_touch_frame(struct libinput_device *libinput_device,
		   struct libinput_event_touch *touch_event)
{
	struct evdev_device *device =
		libinput_device_get_user_data(libinput_device);
	struct weston_seat *seat = device->seat;

	notify_touch_frame(seat);
}

int
evdev_device_process_event(struct libinput_event *event)
{
	struct libinput_device *libinput_device =
		libinput_event_get_device(event);
	struct evdev_device *device =
		libinput_device_get_user_data(libinput_device);
	int handled = 1;
	bool need_frame = false;

	switch (libinput_event_get_type(event)) {
	case LIBINPUT_EVENT_KEYBOARD_KEY:
		handle_keyboard_key(libinput_device,
				    libinput_event_get_keyboard_event(event));
		break;
	case LIBINPUT_EVENT_POINTER_MOTION:
		need_frame = handle_pointer_motion(libinput_device,
				      libinput_event_get_pointer_event(event));
		break;
	case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
		need_frame = handle_pointer_motion_absolute(
				libinput_device,
				libinput_event_get_pointer_event(event));
		break;
	case LIBINPUT_EVENT_POINTER_BUTTON:
		need_frame = handle_pointer_button(libinput_device,
				      libinput_event_get_pointer_event(event));
		break;
	case LIBINPUT_EVENT_POINTER_AXIS:
		need_frame = handle_pointer_axis(
				 libinput_device,
				 libinput_event_get_pointer_event(event));
		break;
	case LIBINPUT_EVENT_TOUCH_DOWN:
		handle_touch_down(libinput_device,
				  libinput_event_get_touch_event(event));
		break;
	case LIBINPUT_EVENT_TOUCH_MOTION:
		handle_touch_motion(libinput_device,
				    libinput_event_get_touch_event(event));
		break;
	case LIBINPUT_EVENT_TOUCH_UP:
		handle_touch_up(libinput_device,
				libinput_event_get_touch_event(event));
		break;
	case LIBINPUT_EVENT_TOUCH_FRAME:
		handle_touch_frame(libinput_device,
				   libinput_event_get_touch_event(event));
		break;
	default:
		handled = 0;
		weston_log("unknown libinput event %d\n",
			   libinput_event_get_type(event));
	}

	if (need_frame)
		notify_pointer_frame(device->seat);

	return handled;
}

static void
notify_output_destroy(struct wl_listener *listener, void *data)
{
	struct evdev_device *device =
		container_of(listener,
			     struct evdev_device, output_destroy_listener);

	evdev_device_set_output(device, NULL);
}

/**
 * The WL_CALIBRATION property requires a pixel-specific matrix to be
 * applied after scaling device coordinates to screen coordinates. libinput
 * can't do that, so we need to convert the calibration to the normalized
 * format libinput expects.
 */
void
evdev_device_set_calibration(struct evdev_device *device)
{
	struct udev *udev;
	struct udev_device *udev_device = NULL;
	const char *sysname = libinput_device_get_sysname(device->device);
	const char *calibration_values;
	uint32_t width, height;
	struct weston_touch_device_matrix calibration;

	if (!libinput_device_config_calibration_has_matrix(device->device))
		return;

	/* If LIBINPUT_CALIBRATION_MATRIX was set to non-identity, we will not
	 * override it with WL_CALIBRATION. It also means we don't need an
	 * output to load a calibration. */
	if (libinput_device_config_calibration_get_default_matrix(
							  device->device,
							  calibration.m) != 0)
		return;

	/* touch_set_calibration() has updated the values, do not load old
	 * values from WL_CALIBRATION.
	 */
	if (device->override_wl_calibration)
		return;

	if (!device->output) {
		weston_log("input device %s has no enabled output associated "
			   "(%s named), skipping calibration for now.\n",
			   sysname, device->output_name ?: "none");
		return;
	}

	width = device->output->width;
	height = device->output->height;
	if (width == 0 || height == 0)
		return;

	udev = udev_new();
	if (!udev)
		return;

	udev_device = udev_device_new_from_subsystem_sysname(udev,
							     "input",
							     sysname);
	if (!udev_device)
		goto out;

	calibration_values =
		udev_device_get_property_value(udev_device,
					       "WL_CALIBRATION");

	if (calibration_values) {
		weston_log("Warning: input device %s has WL_CALIBRATION property set. "
			   "Support for it will be removed in the future. "
			   "Please use LIBINPUT_CALIBRATION_MATRIX instead.\n",
			   sysname);
	}

	if (!calibration_values || sscanf(calibration_values,
					  "%f %f %f %f %f %f",
					  &calibration.m[0],
					  &calibration.m[1],
					  &calibration.m[2],
					  &calibration.m[3],
					  &calibration.m[4],
					  &calibration.m[5]) != 6)
		goto out;

	/* normalize to a format libinput can use. There is a chance of
	   this being wrong if the width/height don't match the device
	   width/height but I'm not sure how to fix that */
	calibration.m[2] /= width;
	calibration.m[5] /= height;

	do_set_calibration(device, &calibration);

	weston_log_continue(STAMP_SPACE "  raw translation %f %f for output %s\n",
		   calibration.m[2] * width,
		   calibration.m[5] * height,
		   device->output->name);

out:
	if (udev_device)
		udev_device_unref(udev_device);
	udev_unref(udev);
}

void
evdev_device_set_output(struct evdev_device *device,
			struct weston_output *output)
{
	if (device->output == output)
		return;

	if (device->output_destroy_listener.notify) {
		wl_list_remove(&device->output_destroy_listener.link);
		device->output_destroy_listener.notify = NULL;
	}

	if (!output) {
		weston_log("output for input device %s removed\n",
			   libinput_device_get_sysname(device->device));

		device->output = NULL;
		return;
	}

	weston_log("associating input device %s with output %s "
		   "(%s by udev)\n",
		   libinput_device_get_sysname(device->device),
		   output->name,
		   device->output_name ?: "none");

	device->output = output;
	device->output_destroy_listener.notify = notify_output_destroy;
	wl_signal_add(&output->destroy_signal,
		      &device->output_destroy_listener);
	evdev_device_set_calibration(device);
}

struct evdev_device *
evdev_device_create(struct libinput_device *libinput_device,
		    struct weston_seat *seat)
{
	struct evdev_device *device;

	device = zalloc(sizeof *device);
	if (device == NULL)
		return NULL;

	device->seat = seat;
	wl_list_init(&device->link);
	device->device = libinput_device;

	if (libinput_device_has_capability(libinput_device,
					   LIBINPUT_DEVICE_CAP_KEYBOARD)) {
		weston_seat_init_keyboard(seat, NULL);
		device->seat_caps |= EVDEV_SEAT_KEYBOARD;
	}
	if (libinput_device_has_capability(libinput_device,
					   LIBINPUT_DEVICE_CAP_POINTER)) {
		weston_seat_init_pointer(seat);
		device->seat_caps |= EVDEV_SEAT_POINTER;
	}
	if (libinput_device_has_capability(libinput_device,
					   LIBINPUT_DEVICE_CAP_TOUCH)) {
		weston_seat_init_touch(seat);
		device->seat_caps |= EVDEV_SEAT_TOUCH;
		device->touch_device = create_touch_device(device);
	}

	libinput_device_set_user_data(libinput_device, device);
	libinput_device_ref(libinput_device);

	return device;
}

void
evdev_device_destroy(struct evdev_device *device)
{
	if (device->seat_caps & EVDEV_SEAT_POINTER)
		weston_seat_release_pointer(device->seat);
	if (device->seat_caps & EVDEV_SEAT_KEYBOARD)
		weston_seat_release_keyboard(device->seat);
	if (device->seat_caps & EVDEV_SEAT_TOUCH) {
		weston_touch_device_destroy(device->touch_device);
		weston_seat_release_touch(device->seat);
	}

	if (device->output)
		wl_list_remove(&device->output_destroy_listener.link);
	wl_list_remove(&device->link);
	libinput_device_unref(device->device);
	free(device->output_name);
	free(device);
}

void
evdev_notify_keyboard_focus(struct weston_seat *seat,
			    struct wl_list *evdev_devices)
{
	struct wl_array keys;

	if (seat->keyboard_device_count == 0)
		return;

	wl_array_init(&keys);
	notify_keyboard_focus_in(seat, &keys, STATE_UPDATE_AUTOMATIC);
	wl_array_release(&keys);
}
