// 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"

/**
 * hgsmi_process_display_info - Set a video mode via an HGSMI request.
 *                              The views must have been initialised first
 *                              using @a VBoxHGSMISendViewInfo and if the mode
 *                              is being set on the first display then it must
 *                              be set first using registers.
 * @ctx:           The context containing the heap to use.
 * @display:       The screen number.
 * @origin_x:      The horizontal displacement relative to the first scrn.
 * @origin_y:      The vertical displacement relative to the first screen.
 * @start_offset:  The offset of the visible area of the framebuffer
 *                 relative to the framebuffer start.
 * @pitch:         The offset in bytes between the starts of two adjecent
 *                 scan lines in video RAM.
 * @width:         The mode width.
 * @height:        The mode height.
 * @bpp:           The colour depth of the mode.
 * @flags:         Flags.
 */
void hgsmi_process_display_info(struct gen_pool *ctx, u32 display,
				s32 origin_x, s32 origin_y, u32 start_offset,
				u32 pitch, u32 width, u32 height,
				u16 bpp, u16 flags)
{
	struct vbva_infoscreen *p;

	p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
			       VBVA_INFO_SCREEN);
	if (!p)
		return;

	p->view_index = display;
	p->origin_x = origin_x;
	p->origin_y = origin_y;
	p->start_offset = start_offset;
	p->line_size = pitch;
	p->width = width;
	p->height = height;
	p->bits_per_pixel = bpp;
	p->flags = flags;

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

/**
 * hgsmi_update_input_mapping - Report the rectangle relative to which absolute
 *                              pointer events should be expressed.  This
 *                              information remains valid until the next VBVA
 *                              resize event for any screen, at which time it is
 *                              reset to the bounding rectangle of all virtual
 *                              screens.
 * Return: 0 or negative errno value.
 * @ctx:       The context containing the heap to use.
 * @origin_x:  Upper left X co-ordinate relative to the first screen.
 * @origin_y:  Upper left Y co-ordinate relative to the first screen.
 * @width:     Rectangle width.
 * @height:    Rectangle height.
 */
int hgsmi_update_input_mapping(struct gen_pool *ctx, s32 origin_x, s32 origin_y,
			       u32 width, u32 height)
{
	struct vbva_report_input_mapping *p;

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

	p->x = origin_x;
	p->y = origin_y;
	p->cx = width;
	p->cy = height;

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

	return 0;
}

/**
 * hgsmi_get_mode_hints - Get most recent video mode hints.
 * Return: 0 or negative errno value.
 * @ctx:      The context containing the heap to use.
 * @screens:  The number of screens to query hints for, starting at 0.
 * @hints:    Array of vbva_modehint structures for receiving the hints.
 */
int hgsmi_get_mode_hints(struct gen_pool *ctx, unsigned int screens,
			 struct vbva_modehint *hints)
{
	struct vbva_query_mode_hints *p;
	size_t size;

	if (WARN_ON(!hints))
		return -EINVAL;

	size = screens * sizeof(struct vbva_modehint);
	p = hgsmi_buffer_alloc(ctx, sizeof(*p) + size, HGSMI_CH_VBVA,
			       VBVA_QUERY_MODE_HINTS);
	if (!p)
		return -ENOMEM;

	p->hints_queried_count = screens;
	p->hint_structure_guest_size = sizeof(struct vbva_modehint);
	p->rc = VERR_NOT_SUPPORTED;

	hgsmi_buffer_submit(ctx, p);

	if (p->rc < 0) {
		hgsmi_buffer_free(ctx, p);
		return -EIO;
	}

	memcpy(hints, ((u8 *)p) + sizeof(struct vbva_query_mode_hints), size);
	hgsmi_buffer_free(ctx, p);

	return 0;
}
