/*
 * Copyright 2012 Intel Corporation
 * 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 <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cairo.h>
#include <math.h>
#include <assert.h>
#include <getopt.h>
#include <errno.h>

#include <wayland-client.h>

#include "clients/window.h"
#include "shared/helpers.h"
#include "shared/matrix.h"

#include "weston-touch-calibration-client-protocol.h"

enum exit_code {
	CAL_EXIT_SUCCESS = 0,
	CAL_EXIT_ERROR = 1,
	CAL_EXIT_CANCELLED = 2,
};

static int debug_;
static int verbose_;

#define pr_ver(...) do { \
	if (verbose_) \
		printf(__VA_ARGS__); \
} while (0)

#define pr_dbg(...) do { \
	if (debug_) \
		fprintf(stderr, __VA_ARGS__); \
} while (0)

static void
pr_err(const char *fmt, ...) WL_PRINTF(1, 2);

/* Our points for the calibration must be not be on a line */
static const struct {
	float x_ratio, y_ratio;
} test_ratios[] =  {
	{ 0.15, 0.10 }, /* three points for calibration */
	{ 0.85, 0.13 },
	{ 0.20, 0.80 },
	{ 0.70, 0.75 }  /* and one for verification */
};

#define NR_SAMPLES ((int)ARRAY_LENGTH(test_ratios))

struct point {
	double x;
	double y;
};

struct sample {
	int ind;
	struct point drawn;	/**< drawn point, pixels */
	struct weston_touch_coordinate *pending;
	struct point drawn_cal;	/**< drawn point, converted */
	bool conv_done;
	struct point touched;	/**< touch point, normalized */
	bool touch_done;
};

struct poly {
	struct color {
		double r, g, b, a;
	} color;
	int n_verts;
	const struct point *verts;
};

/** Touch event handling state machine
 *
 * Only a complete down->up->frame sequence should be accepted with user
 * feedback "right", and anything that deviates from that (invalid_touch,
 * cancel, multiple touch-downs) needs to undo the current sample and
 * possibly show user feedback "wrong".
 *
 * <STATE>
 * - <triggers>: <actions>
 *
 * IDLE
 * - touch down: sample, -> DOWN
 * - touch up: no-op
 * - frame: no-op
 * - invalid_touch: (undo), wrong, -> WAIT
 * - cancel: no-op
 * DOWN (first touch down)
 * - touch down: undo, wrong, -> WAIT
 * - touch up: -> UP
 * - frame: no-op
 * - invalid_touch: undo, wrong, -> WAIT
 * - cancel: undo, -> IDLE
 * UP (first touch was down and up)
 * - touch down: undo, wrong, -> WAIT
 * - touch up: no-op
 * - frame: right, touch finish, -> WAIT
 * - invalid_touch: undo, wrong, -> WAIT
 * - cancel: undo, -> IDLE
 * WAIT (show user feedback)
 * - touch down: no-op
 * - touch up: no-op
 * - frame, cancel, timer: if num_tp == 0 && timer_done -> IDLE
 * - invalid_touch: no-op
 */
enum touch_state {
	STATE_IDLE,
	STATE_DOWN,
	STATE_UP,
	STATE_WAIT
};

struct calibrator {
	struct sample samples[NR_SAMPLES];
	int current_sample;

	struct display *display;
	struct weston_touch_calibration *calibration;
	struct weston_touch_calibrator *calibrator;
	struct window *window;
	struct widget *widget;

	int n_devices_listed;
	char *match_name;
	char *device_name;

	int width;
	int height;

	bool cancelled;

	const struct poly *current_poly;
	bool exiting;

	struct toytimer wait_timer;
	bool timer_pending;
	enum touch_state state;

	int num_tp;		/* touch points down count */
};

static struct sample *
current_sample(struct calibrator *cal)
{
	return &cal->samples[cal->current_sample];
}

static void
sample_start(struct calibrator *cal, int i)
{
	struct sample *s = &cal->samples[i];

	assert(i >= 0 && i < NR_SAMPLES);

	s->ind = i;
	s->drawn.x = round(test_ratios[i].x_ratio * cal->width);
	s->drawn.y = round(test_ratios[i].y_ratio * cal->height);
	s->pending = NULL;
	s->conv_done = false;
	s->touch_done = false;

	cal->current_sample = i;
}

static struct point
wire_to_point(uint32_t xu, uint32_t yu)
{
	struct point p = {
		.x = (double)xu / 0xffffffff,
		.y = (double)yu / 0xffffffff
	};

	return p;
}

static void
sample_touch_down(struct calibrator *cal, uint32_t xu, uint32_t yu)
{
	struct sample *s = current_sample(cal);

	s->touched = wire_to_point(xu, yu);
	s->touch_done = true;

	pr_dbg("Down[%d] (%f, %f)\n", s->ind, s->touched.x, s->touched.y);
}

static void
coordinate_result_handler(void *data, struct weston_touch_coordinate *interface,
			  uint32_t xu, uint32_t yu)
{
	struct sample *s = data;

	weston_touch_coordinate_destroy(s->pending);
	s->pending = NULL;

	s->drawn_cal = wire_to_point(xu, yu);
	s->conv_done = true;

	pr_dbg("Conv[%d] (%f, %f)\n", s->ind, s->drawn_cal.x, s->drawn_cal.y);
}

struct weston_touch_coordinate_listener coordinate_listener = {
	coordinate_result_handler
};

static void
sample_undo(struct calibrator *cal)
{
	struct sample *s = current_sample(cal);

	pr_dbg("Undo[%d]\n", s->ind);

	s->touch_done = false;
	s->conv_done = false;
	if (s->pending) {
		weston_touch_coordinate_destroy(s->pending);
		s->pending = NULL;
	}
}

static void
sample_finish(struct calibrator *cal)
{
	struct sample *s = current_sample(cal);

	pr_dbg("Finish[%d]\n", s->ind);

	assert(!s->pending && !s->conv_done);

	s->pending = weston_touch_calibrator_convert(cal->calibrator,
						     (int32_t)s->drawn.x,
						     (int32_t)s->drawn.y);
	weston_touch_coordinate_add_listener(s->pending,
					     &coordinate_listener, s);

	if (cal->current_sample + 1 < NR_SAMPLES) {
		sample_start(cal, cal->current_sample + 1);
	} else {
		pr_dbg("got all touches\n");
		cal->exiting = true;
	}
}

/*
 * Calibration algorithm:
 *
 * The equation we want to apply at event time where x' and y' are the
 * calibrated co-ordinates.
 *
 * x' = Ax + By + C
 * y' = Dx + Ey + F
 *
 * For example "zero calibration" would be A=1.0 B=0.0 C=0.0, D=0.0, E=1.0,
 * and F=0.0.
 *
 * With 6 unknowns we need 6 equations to find the constants:
 *
 * x1' = Ax1 + By1 + C
 * y1' = Dx1 + Ey1 + F
 * ...
 * x3' = Ax3 + By3 + C
 * y3' = Dx3 + Ey3 + F
 *
 * In matrix form:
 *
 * x1'   x1 y1 1      A
 * x2' = x2 y2 1  x   B
 * x3'   x3 y3 1      C
 *
 * So making the matrix M we can find the constants with:
 *
 * A            x1'
 * B = M^-1  x  x2'
 * C            x3'
 *
 * (and similarly for D, E and F)
 *
 * For the calibration the desired values x, y are the same values at which
 * we've drawn at.
 *
 */
static int
compute_calibration(struct calibrator *cal, float *result)
{
	struct weston_matrix m;
	struct weston_matrix inverse;
	struct weston_vector x_calib;
	struct weston_vector y_calib;
	int i;

	assert(NR_SAMPLES >= 3);

	/*
	 * x1 y1  1  0
	 * x2 y2  1  0
	 * x3 y3  1  0
	 *  0  0  0  1
	 */
	weston_matrix_init(&m);
	for (i = 0; i < 3; i++) {
		m.d[i + 0] = cal->samples[i].touched.x;
		m.d[i + 4] = cal->samples[i].touched.y;
		m.d[i + 8] = 1.0f;
	}
	m.type = WESTON_MATRIX_TRANSFORM_OTHER;

	if (weston_matrix_invert(&inverse, &m) < 0) {
		pr_err("non-invertible matrix during computation\n");
		return -1;
	}

	for (i = 0; i < 3; i++) {
		x_calib.f[i] = cal->samples[i].drawn_cal.x;
		y_calib.f[i] = cal->samples[i].drawn_cal.y;
	}
	x_calib.f[3] = 0.0f;
	y_calib.f[3] = 0.0f;

	/* Multiples into the vector */
	weston_matrix_transform(&inverse, &x_calib);
	weston_matrix_transform(&inverse, &y_calib);

	for (i = 0; i < 3; i++)
		result[i] = x_calib.f[i];
	for (i = 0; i < 3; i++)
		result[i + 3] = y_calib.f[i];

	return 0;
}

static int
verify_calibration(struct calibrator *cal, const float *r)
{
	double thr = 0.1; /* accepted error radius */
	struct point e; /* expected value; error */
	const struct sample *s = &cal->samples[3];

	/* transform raw touches through the matrix */
	e.x = r[0] * s->touched.x + r[1] * s->touched.y + r[2];
	e.y = r[3] * s->touched.x + r[4] * s->touched.y + r[5];

	/* compute error */
	e.x -= s->drawn_cal.x;
	e.y -= s->drawn_cal.y;

	pr_dbg("calibration test error: %f, %f\n", e.x, e.y);

	if (e.x * e.x + e.y * e.y < thr * thr)
		return 0;

	pr_err("Calibration verification failed, too large error.\n");
	return -1;
}

static void
send_calibration(struct calibrator *cal, float *values)
{
	struct wl_array matrix;
	float *f;
	int i;

	wl_array_init(&matrix);
	for (i = 0; i < 6; i++) {
		f = wl_array_add(&matrix, sizeof *f);
		*f = values[i];
	}
	weston_touch_calibration_save(cal->calibration,
				      cal->device_name, &matrix);
	wl_array_release(&matrix);
}

static const struct point cross_verts[] = {
	{ 0.1, 0.2 },
	{ 0.2, 0.1 },
	{ 0.5, 0.4 },
	{ 0.8, 0.1 },
	{ 0.9, 0.2 },
	{ 0.6, 0.5 },
	{ 0.9, 0.8 },
	{ 0.8, 0.9 },
	{ 0.5, 0.6 },
	{ 0.2, 0.9 },
	{ 0.1, 0.8 },
	{ 0.4, 0.5 },
};

/* a red cross, for "wrong" */
static const struct poly cross = {
	.color = { 0.7, 0.0, 0.0, 1.0 },
	.n_verts = ARRAY_LENGTH(cross_verts),
	.verts = cross_verts
};

static const struct point check_verts[] = {
	{ 0.5, 0.7 },
	{ 0.8, 0.1 },
	{ 0.9, 0.1 },
	{ 0.55, 0.8 },
	{ 0.45, 0.8 },
	{ 0.3, 0.5 },
	{ 0.4, 0.5 }
};

/* a green check mark, for "right" */
static const struct poly check = {
	.color = { 0.0, 0.7, 0.0, 1.0 },
	.n_verts = ARRAY_LENGTH(check_verts),
	.verts = check_verts
};

static void
draw_poly(cairo_t *cr, const struct poly *poly)
{
	int i;

	cairo_set_source_rgba(cr, poly->color.r, poly->color.g,
			      poly->color.b, poly->color.a);
	cairo_move_to(cr, poly->verts[0].x, poly->verts[0].y);
	for (i = 1; i < poly->n_verts; i++)
		cairo_line_to(cr, poly->verts[i].x, poly->verts[i].y);
	cairo_close_path(cr);
	cairo_fill(cr);
}

static void
feedback_show(struct calibrator *cal, const struct poly *what)
{
	cal->current_poly = what;
	widget_schedule_redraw(cal->widget);

	toytimer_arm_once_usec(&cal->wait_timer, 1000 * 1000);
	cal->timer_pending = true;
}

static void
feedback_hide(struct calibrator *cal)
{
	cal->current_poly = NULL;
	widget_schedule_redraw(cal->widget);
}

static void
try_enter_state_idle(struct calibrator *cal)
{
	if (cal->num_tp != 0)
		return;

	if (cal->timer_pending)
		return;

	cal->state = STATE_IDLE;

	feedback_hide(cal);

	if (cal->exiting)
		display_exit(cal->display);
}

static void
enter_state_wait(struct calibrator *cal)
{
	assert(cal->timer_pending);
	cal->state = STATE_WAIT;
}

static void
wait_timer_done(struct toytimer *tt)
{
	struct calibrator *cal = container_of(tt, struct calibrator, wait_timer);

	assert(cal->state == STATE_WAIT);
	cal->timer_pending = false;
	try_enter_state_idle(cal);
}

static void
redraw_handler(struct widget *widget, void *data)
{
	struct calibrator *cal = data;
	struct sample *s = current_sample(cal);
	struct rectangle allocation;
	cairo_surface_t *surface;
	cairo_t *cr;

	widget_get_allocation(cal->widget, &allocation);
	assert(allocation.width == cal->width);
	assert(allocation.height == cal->height);

	surface = window_get_surface(cal->window);
	cr = cairo_create(surface);
	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
	cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
	cairo_paint(cr);

	if (!cal->current_poly) {
		cairo_translate(cr, s->drawn.x, s->drawn.y);
		cairo_set_line_width(cr, 2.0);
		cairo_set_source_rgb(cr, 0.7, 0.0, 0.0);
		cairo_move_to(cr, 0, -10.0);
		cairo_line_to(cr, 0, 10.0);
		cairo_stroke(cr);
		cairo_move_to(cr, -10.0, 0);
		cairo_line_to(cr, 10.0, 0.0);
		cairo_stroke(cr);
	} else {
		cairo_scale(cr, allocation.width, allocation.height);
		draw_poly(cr, cal->current_poly);
	}

	cairo_destroy(cr);
	cairo_surface_destroy(surface);
}

static struct calibrator *
calibrator_create(struct display *display, const char *match_name)
{
	struct calibrator *cal;

	cal = zalloc(sizeof *cal);
	if (!cal)
		abort();

	cal->match_name = match_name ? strdup(match_name) : NULL;
	cal->window = window_create_custom(display);
	cal->widget = window_add_widget(cal->window, cal);
	window_inhibit_redraw(cal->window);
	window_set_title(cal->window, "Touchscreen calibrator");
	cal->display = display;

	widget_set_redraw_handler(cal->widget, redraw_handler);

	toytimer_init(&cal->wait_timer, CLOCK_MONOTONIC,
		      display, wait_timer_done);

	cal->state = STATE_IDLE;
	cal->num_tp = 0;

	return cal;
}

static void
configure_handler(void *data, struct weston_touch_calibrator *interface,
		  int32_t width, int32_t height)
{
	struct calibrator *cal = data;

	pr_dbg("Configure calibrator window to size %ix%i\n", width, height);
	cal->width = width;
	cal->height = height;
	window_schedule_resize(cal->window, width, height);
	window_uninhibit_redraw(cal->window);

	sample_start(cal, 0);
	widget_schedule_redraw(cal->widget);
}

static void
cancel_calibration_handler(void *data, struct weston_touch_calibrator *interface)
{
	struct calibrator *cal = data;

	pr_dbg("calibration cancelled by the display server, quitting.\n");
	cal->cancelled = true;
	display_exit(cal->display);
}

static void
invalid_touch_handler(void *data, struct weston_touch_calibrator *interface)
{
	struct calibrator *cal = data;

	pr_dbg("invalid touch\n");

	switch (cal->state) {
	case STATE_IDLE:
	case STATE_DOWN:
	case STATE_UP:
		sample_undo(cal);
		feedback_show(cal, &cross);
		enter_state_wait(cal);
		break;
	case STATE_WAIT:
		/* no-op */
		break;
	}
}

static void
down_handler(void *data, struct weston_touch_calibrator *interface,
	     uint32_t time, int32_t id, uint32_t xu, uint32_t yu)
{
	struct calibrator *cal = data;

	cal->num_tp++;

	switch (cal->state) {
	case STATE_IDLE:
		sample_touch_down(cal, xu, yu);
		cal->state = STATE_DOWN;
		break;
	case STATE_DOWN:
	case STATE_UP:
		sample_undo(cal);
		feedback_show(cal, &cross);
		enter_state_wait(cal);
		break;
	case STATE_WAIT:
		/* no-op */
		break;
	}

	if (cal->current_poly)
		return;
}

static void
up_handler(void *data, struct weston_touch_calibrator *interface,
	   uint32_t time, int32_t id)
{
	struct calibrator *cal = data;

	cal->num_tp--;
	if (cal->num_tp < 0) {
		pr_dbg("Unmatched touch up.\n");
		cal->num_tp = 0;
	}

	switch (cal->state) {
	case STATE_DOWN:
		cal->state = STATE_UP;
		break;
	case STATE_IDLE:
	case STATE_UP:
	case STATE_WAIT:
		/* no-op */
		break;
	}
}

static void
motion_handler(void *data, struct weston_touch_calibrator *interface,
	       uint32_t time, int32_t id, uint32_t xu, uint32_t yu)
{
	/* motion is ignored */
}

static void
frame_handler(void *data, struct weston_touch_calibrator *interface)
{
	struct calibrator *cal = data;

	switch (cal->state) {
	case STATE_IDLE:
	case STATE_DOWN:
		/* no-op */
		break;
	case STATE_UP:
		feedback_show(cal, &check);
		sample_finish(cal);
		enter_state_wait(cal);
		break;
	case STATE_WAIT:
		try_enter_state_idle(cal);
		break;
	}
}

static void
cancel_handler(void *data, struct weston_touch_calibrator *interface)
{
	struct calibrator *cal = data;

	cal->num_tp = 0;

	switch (cal->state) {
	case STATE_IDLE:
		/* no-op */
		break;
	case STATE_DOWN:
	case STATE_UP:
		sample_undo(cal);
		try_enter_state_idle(cal);
		break;
	case STATE_WAIT:
		try_enter_state_idle(cal);
		break;
	}
}

struct weston_touch_calibrator_listener calibrator_listener = {
	configure_handler,
	cancel_calibration_handler,
	invalid_touch_handler,
	down_handler,
	up_handler,
	motion_handler,
	frame_handler,
	cancel_handler
};

static void
calibrator_show(struct calibrator *cal)
{
	struct wl_surface *surface = window_get_wl_surface(cal->window);

	cal->calibrator =
		weston_touch_calibration_create_calibrator(cal->calibration,
							   surface,
							   cal->device_name);
	weston_touch_calibrator_add_listener(cal->calibrator,
					     &calibrator_listener, cal);
}

static void
calibrator_destroy(struct calibrator *cal)
{
	toytimer_fini(&cal->wait_timer);
	if (cal->calibrator)
		weston_touch_calibrator_destroy(cal->calibrator);
	if (cal->calibration)
		weston_touch_calibration_destroy(cal->calibration);
	if (cal->widget)
		widget_destroy(cal->widget);
	if (cal->window)
		window_destroy(cal->window);
	free(cal->match_name);
	free(cal->device_name);
	free(cal);
}

static void
touch_device_handler(void *data, struct weston_touch_calibration *c,
		     const char *device, const char *head)
{
	struct calibrator *cal = data;

	cal->n_devices_listed++;

	if (!cal->match_name) {
		printf("device \"%s\" - head \"%s\"\n", device, head);
		return;
	}

	if (cal->device_name)
		return;

	if (strcmp(cal->match_name, device) == 0 ||
	    strcmp(cal->match_name, head) == 0)
		cal->device_name = strdup(device);
}

struct weston_touch_calibration_listener touch_calibration_listener = {
	touch_device_handler
};

static void
global_handler(struct display *display, uint32_t name,
	       const char *interface, uint32_t version, void *data)
{
	struct calibrator *cal = data;

	if (strcmp(interface, "weston_touch_calibration") == 0) {
		cal->calibration = display_bind(display, name,
						&weston_touch_calibration_interface, 1);
		weston_touch_calibration_add_listener(cal->calibration,
						      &touch_calibration_listener,
						      cal);
	}
}

static int
calibrator_run(struct calibrator *cal)
{
	struct wl_display *dpy;
	struct sample *s;
	bool wait;
	int i;
	int ret;
	float result[6];

	calibrator_show(cal);
	display_run(cal->display);

	if (cal->cancelled)
		return CAL_EXIT_CANCELLED;

	/* remove the window, no more input events */
	widget_destroy(cal->widget);
	cal->widget = NULL;
	window_destroy(cal->window);
	cal->window = NULL;

	/* wait for all conversions to return */
	dpy = display_get_display(cal->display);
	do {
		wait = false;

		for (i = 0; i < NR_SAMPLES; i++)
			if (cal->samples[i].pending)
				wait = true;

		if (wait) {
			ret = wl_display_roundtrip(dpy);
			if (ret < 0)
				return CAL_EXIT_ERROR;
		}
	} while (wait);

	for (i = 0; i < NR_SAMPLES; i++) {
		s = &cal->samples[i];
		if (!s->conv_done || !s->touch_done)
			return CAL_EXIT_ERROR;
	}

	if (compute_calibration(cal, result) < 0)
		return CAL_EXIT_ERROR;

	if (verify_calibration(cal, result) < 0)
		return CAL_EXIT_ERROR;

	pr_ver("Calibration values:");
	for (i = 0; i < 6; i++)
		pr_ver(" %f", result[i]);
	pr_ver("\n");

	send_calibration(cal, result);
	ret = wl_display_roundtrip(dpy);
	if (ret < 0)
		return CAL_EXIT_ERROR;

	return CAL_EXIT_SUCCESS;
}

static void
pr_err(const char *fmt, ...)
{
	va_list argp;

	va_start(argp, fmt);
	fprintf(stderr, "%s error: ", program_invocation_short_name);
	vfprintf(stderr, fmt, argp);
	va_end(argp);
}

static void
help(void)
{
	fprintf(stderr, "Compute a touchscreen calibration matrix for "
		"a Wayland compositor by\n"
		"having the user touch points on the screen.\n\n");
	fprintf(stderr, "Usage: %s [options...] name\n\n",
		program_invocation_short_name);
	fprintf(stderr,
		"Where 'name' can be a touch device sys path or a head name.\n"
		"If 'name' is not given, all devices available for "
		"calibration will be listed.\n"
		"If 'name' is given, it must be exactly as listed.\n"
		"Options:\n"
		"  --debug         Print messages to help debugging.\n"
		"  -h, --help      Display this help message\n"
		"  -v, --verbose   Print list header and calibration result.\n");
}

int
main(int argc, char *argv[])
{
	struct display *display;
	struct calibrator *cal;
	int c;
	char *match_name = NULL;
	int exit_code = CAL_EXIT_SUCCESS;
	static const struct option opts[] = {
		{ "help",    no_argument,       NULL,      'h' },
		{ "debug",   no_argument,       &debug_,   1 },
		{ "verbose", no_argument,       &verbose_, 1 },
		{ 0,         0,                 NULL,      0  }
	};

	while ((c = getopt_long(argc, argv, "hv", opts, NULL)) != -1) {
		switch (c) {
		case 'h':
			help();
			return CAL_EXIT_SUCCESS;
		case 'v':
			verbose_ = 1;
			break;
		case 0:
			break;
		default:
			return CAL_EXIT_ERROR;
		}
	}

	if (optind < argc)
		match_name = argv[optind++];

	if (optind < argc) {
		pr_err("extra arguments given.\n\n");
		help();
		return CAL_EXIT_ERROR;
	}

	display = display_create(&argc, argv);
	if (!display)
		return CAL_EXIT_ERROR;

	cal = calibrator_create(display, match_name);
	if (!cal)
		return CAL_EXIT_ERROR;

	display_set_user_data(display, cal);
	display_set_global_handler(display, global_handler);

	if (!match_name)
		pr_ver("Available touch devices:\n");

	/* Roundtrip to get list of available touch devices,
	 * first globals, then touch_device events */
	wl_display_roundtrip(display_get_display(display));
	wl_display_roundtrip(display_get_display(display));

	if (!cal->calibration) {
		exit_code = CAL_EXIT_ERROR;
		pr_err("the Wayland server does not expose the calibration interface.\n");
	} else if (cal->device_name) {
		exit_code = calibrator_run(cal);
	} else if (match_name) {
		exit_code = CAL_EXIT_ERROR;
		pr_err("\"%s\" was not found.\n", match_name);
	} else if (cal->n_devices_listed == 0) {
		fprintf(stderr, "No devices listed.\n");
	}

	calibrator_destroy(cal);
	display_destroy(display);

	return exit_code;
}
