// SPDX-License-Identifier: MIT
/* Copyright (C) 2006-2017 Oracle Corporation */

#include <linux/vbox_err.h>
#include "vbox_drv.h"
#include "vboxvideo_guest.h"
#include "vboxvideo_vbe.h"
#include "hgsmi_channels.h"
#include "hgsmi_ch_setup.h"

/**
 * hgsmi_report_flags_location - Inform the host of the location of
 *                               the host flags in VRAM via an HGSMI cmd.
 * Return: 0 or negative errno value.
 * @ctx:        The context of the guest heap to use.
 * @location:   The offset chosen for the flags within guest VRAM.
 */
int hgsmi_report_flags_location(struct gen_pool *ctx, u32 location)
{
	struct hgsmi_buffer_location *p;

	p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_HGSMI,
			       HGSMI_CC_HOST_FLAGS_LOCATION);
	if (!p)
		return -ENOMEM;

	p->buf_location = location;
	p->buf_len = sizeof(struct hgsmi_host_flags);

	hgsmi_buffer_submit(ctx, p);
	hgsmi_buffer_free(ctx, p);

	return 0;
}

/**
 * hgsmi_send_caps_info - Notify the host of HGSMI-related guest capabilities
 *                        via an HGSMI command.
 * Return: 0 or negative errno value.
 * @ctx:        The context of the guest heap to use.
 * @caps:       The capabilities to report, see vbva_caps.
 */
int hgsmi_send_caps_info(struct gen_pool *ctx, u32 caps)
{
	struct vbva_caps *p;

	p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, VBVA_INFO_CAPS);
	if (!p)
		return -ENOMEM;

	p->rc = VERR_NOT_IMPLEMENTED;
	p->caps = caps;

	hgsmi_buffer_submit(ctx, p);

	WARN_ON_ONCE(p->rc < 0);

	hgsmi_buffer_free(ctx, p);

	return 0;
}

int hgsmi_test_query_conf(struct gen_pool *ctx)
{
	u32 value = 0;
	int ret;

	ret = hgsmi_query_conf(ctx, U32_MAX, &value);
	if (ret)
		return ret;

	return value == U32_MAX ? 0 : -EIO;
}

/**
 * hgsmi_query_conf - Query the host for an HGSMI configuration
 *                    parameter via an HGSMI command.
 * Return: 0 or negative errno value.
 * @ctx:        The context containing the heap used.
 * @index:      The index of the parameter to query.
 * @value_ret:  Where to store the value of the parameter on success.
 */
int hgsmi_query_conf(struct gen_pool *ctx, u32 index, u32 *value_ret)
{
	struct vbva_conf32 *p;

	p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
			       VBVA_QUERY_CONF32);
	if (!p)
		return -ENOMEM;

	p->index = index;
	p->value = U32_MAX;

	hgsmi_buffer_submit(ctx, p);

	*value_ret = p->value;

	hgsmi_buffer_free(ctx, p);

	return 0;
}

/**
 * hgsmi_update_pointer_shape - Pass the host a new mouse pointer shape
 *                              via an HGSMI command.
 * Return: 0 or negative errno value.
 * @ctx:        The context containing the heap to be used.
 * @flags:      Cursor flags.
 * @hot_x:      Horizontal position of the hot spot.
 * @hot_y:      Vertical position of the hot spot.
 * @width:      Width in pixels of the cursor.
 * @height:     Height in pixels of the cursor.
 * @pixels:     Pixel data, @see VMMDevReqMousePointer for the format.
 * @len:        Size in bytes of the pixel data.
 */
int hgsmi_update_pointer_shape(struct gen_pool *ctx, u32 flags,
			       u32 hot_x, u32 hot_y, u32 width, u32 height,
			       u8 *pixels, u32 len)
{
	struct vbva_mouse_pointer_shape *p;
	u32 pixel_len = 0;
	int rc;

	if (flags & VBOX_MOUSE_POINTER_SHAPE) {
		/*
		 * Size of the pointer data:
		 * sizeof (AND mask) + sizeof (XOR_MASK)
		 */
		pixel_len = ((((width + 7) / 8) * height + 3) & ~3) +
			 width * 4 * height;
		if (pixel_len > len)
			return -EINVAL;

		/*
		 * If shape is supplied, then always create the pointer visible.
		 * See comments in 'vboxUpdatePointerShape'
		 */
		flags |= VBOX_MOUSE_POINTER_VISIBLE;
	}

	/*
	 * The 4 extra bytes come from switching struct vbva_mouse_pointer_shape
	 * from having a 4 bytes fixed array at the end to using a proper VLA
	 * at the end. These 4 extra bytes were not subtracted from sizeof(*p)
	 * before the switch to the VLA, so this way the behavior is unchanged.
	 * Chances are these 4 extra bytes are not necessary but they are kept
	 * to avoid regressions.
	 */
	p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len + 4, HGSMI_CH_VBVA,
			       VBVA_MOUSE_POINTER_SHAPE);
	if (!p)
		return -ENOMEM;

	p->result = VINF_SUCCESS;
	p->flags = flags;
	p->hot_X = hot_x;
	p->hot_y = hot_y;
	p->width = width;
	p->height = height;
	if (pixel_len)
		memcpy(p->data, pixels, pixel_len);

	hgsmi_buffer_submit(ctx, p);

	switch (p->result) {
	case VINF_SUCCESS:
		rc = 0;
		break;
	case VERR_NO_MEMORY:
		rc = -ENOMEM;
		break;
	case VERR_NOT_SUPPORTED:
		rc = -EBUSY;
		break;
	default:
		rc = -EINVAL;
	}

	hgsmi_buffer_free(ctx, p);

	return rc;
}

/**
 * hgsmi_cursor_position - Report the guest cursor position.  The host may
 *                         wish to use this information to re-position its
 *                         own cursor (though this is currently unlikely).
 *                         The current host cursor position is returned.
 * Return: 0 or negative errno value.
 * @ctx:              The context containing the heap used.
 * @report_position:  Are we reporting a position?
 * @x:                Guest cursor X position.
 * @y:                Guest cursor Y position.
 * @x_host:           Host cursor X position is stored here.  Optional.
 * @y_host:           Host cursor Y position is stored here.  Optional.
 */
int hgsmi_cursor_position(struct gen_pool *ctx, bool report_position,
			  u32 x, u32 y, u32 *x_host, u32 *y_host)
{
	struct vbva_cursor_position *p;

	p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
			       VBVA_CURSOR_POSITION);
	if (!p)
		return -ENOMEM;

	p->report_position = report_position;
	p->x = x;
	p->y = y;

	hgsmi_buffer_submit(ctx, p);

	*x_host = p->x;
	*y_host = p->y;

	hgsmi_buffer_free(ctx, p);

	return 0;
}
