128 lines
3.9 KiB
C
128 lines
3.9 KiB
C
// 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;
|
|
}
|