brintos

brintos / linux-shallow public Read only

0
0
Text · 5.6 KiB · 87dccae Raw
221 lines · c
1// SPDX-License-Identifier: MIT2/* Copyright (C) 2006-2017 Oracle Corporation */3 4#include <linux/vbox_err.h>5#include "vbox_drv.h"6#include "vboxvideo_guest.h"7#include "vboxvideo_vbe.h"8#include "hgsmi_channels.h"9#include "hgsmi_ch_setup.h"10 11/**12 * hgsmi_report_flags_location - Inform the host of the location of13 *                               the host flags in VRAM via an HGSMI cmd.14 * Return: 0 or negative errno value.15 * @ctx:        The context of the guest heap to use.16 * @location:   The offset chosen for the flags within guest VRAM.17 */18int hgsmi_report_flags_location(struct gen_pool *ctx, u32 location)19{20	struct hgsmi_buffer_location *p;21 22	p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_HGSMI,23			       HGSMI_CC_HOST_FLAGS_LOCATION);24	if (!p)25		return -ENOMEM;26 27	p->buf_location = location;28	p->buf_len = sizeof(struct hgsmi_host_flags);29 30	hgsmi_buffer_submit(ctx, p);31	hgsmi_buffer_free(ctx, p);32 33	return 0;34}35 36/**37 * hgsmi_send_caps_info - Notify the host of HGSMI-related guest capabilities38 *                        via an HGSMI command.39 * Return: 0 or negative errno value.40 * @ctx:        The context of the guest heap to use.41 * @caps:       The capabilities to report, see vbva_caps.42 */43int hgsmi_send_caps_info(struct gen_pool *ctx, u32 caps)44{45	struct vbva_caps *p;46 47	p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, VBVA_INFO_CAPS);48	if (!p)49		return -ENOMEM;50 51	p->rc = VERR_NOT_IMPLEMENTED;52	p->caps = caps;53 54	hgsmi_buffer_submit(ctx, p);55 56	WARN_ON_ONCE(p->rc < 0);57 58	hgsmi_buffer_free(ctx, p);59 60	return 0;61}62 63int hgsmi_test_query_conf(struct gen_pool *ctx)64{65	u32 value = 0;66	int ret;67 68	ret = hgsmi_query_conf(ctx, U32_MAX, &value);69	if (ret)70		return ret;71 72	return value == U32_MAX ? 0 : -EIO;73}74 75/**76 * hgsmi_query_conf - Query the host for an HGSMI configuration77 *                    parameter via an HGSMI command.78 * Return: 0 or negative errno value.79 * @ctx:        The context containing the heap used.80 * @index:      The index of the parameter to query.81 * @value_ret:  Where to store the value of the parameter on success.82 */83int hgsmi_query_conf(struct gen_pool *ctx, u32 index, u32 *value_ret)84{85	struct vbva_conf32 *p;86 87	p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,88			       VBVA_QUERY_CONF32);89	if (!p)90		return -ENOMEM;91 92	p->index = index;93	p->value = U32_MAX;94 95	hgsmi_buffer_submit(ctx, p);96 97	*value_ret = p->value;98 99	hgsmi_buffer_free(ctx, p);100 101	return 0;102}103 104/**105 * hgsmi_update_pointer_shape - Pass the host a new mouse pointer shape106 *                              via an HGSMI command.107 * Return: 0 or negative errno value.108 * @ctx:        The context containing the heap to be used.109 * @flags:      Cursor flags.110 * @hot_x:      Horizontal position of the hot spot.111 * @hot_y:      Vertical position of the hot spot.112 * @width:      Width in pixels of the cursor.113 * @height:     Height in pixels of the cursor.114 * @pixels:     Pixel data, @see VMMDevReqMousePointer for the format.115 * @len:        Size in bytes of the pixel data.116 */117int hgsmi_update_pointer_shape(struct gen_pool *ctx, u32 flags,118			       u32 hot_x, u32 hot_y, u32 width, u32 height,119			       u8 *pixels, u32 len)120{121	struct vbva_mouse_pointer_shape *p;122	u32 pixel_len = 0;123	int rc;124 125	if (flags & VBOX_MOUSE_POINTER_SHAPE) {126		/*127		 * Size of the pointer data:128		 * sizeof (AND mask) + sizeof (XOR_MASK)129		 */130		pixel_len = ((((width + 7) / 8) * height + 3) & ~3) +131			 width * 4 * height;132		if (pixel_len > len)133			return -EINVAL;134 135		/*136		 * If shape is supplied, then always create the pointer visible.137		 * See comments in 'vboxUpdatePointerShape'138		 */139		flags |= VBOX_MOUSE_POINTER_VISIBLE;140	}141 142	/*143	 * The 4 extra bytes come from switching struct vbva_mouse_pointer_shape144	 * from having a 4 bytes fixed array at the end to using a proper VLA145	 * at the end. These 4 extra bytes were not subtracted from sizeof(*p)146	 * before the switch to the VLA, so this way the behavior is unchanged.147	 * Chances are these 4 extra bytes are not necessary but they are kept148	 * to avoid regressions.149	 */150	p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len + 4, HGSMI_CH_VBVA,151			       VBVA_MOUSE_POINTER_SHAPE);152	if (!p)153		return -ENOMEM;154 155	p->result = VINF_SUCCESS;156	p->flags = flags;157	p->hot_X = hot_x;158	p->hot_y = hot_y;159	p->width = width;160	p->height = height;161	if (pixel_len)162		memcpy(p->data, pixels, pixel_len);163 164	hgsmi_buffer_submit(ctx, p);165 166	switch (p->result) {167	case VINF_SUCCESS:168		rc = 0;169		break;170	case VERR_NO_MEMORY:171		rc = -ENOMEM;172		break;173	case VERR_NOT_SUPPORTED:174		rc = -EBUSY;175		break;176	default:177		rc = -EINVAL;178	}179 180	hgsmi_buffer_free(ctx, p);181 182	return rc;183}184 185/**186 * hgsmi_cursor_position - Report the guest cursor position.  The host may187 *                         wish to use this information to re-position its188 *                         own cursor (though this is currently unlikely).189 *                         The current host cursor position is returned.190 * Return: 0 or negative errno value.191 * @ctx:              The context containing the heap used.192 * @report_position:  Are we reporting a position?193 * @x:                Guest cursor X position.194 * @y:                Guest cursor Y position.195 * @x_host:           Host cursor X position is stored here.  Optional.196 * @y_host:           Host cursor Y position is stored here.  Optional.197 */198int hgsmi_cursor_position(struct gen_pool *ctx, bool report_position,199			  u32 x, u32 y, u32 *x_host, u32 *y_host)200{201	struct vbva_cursor_position *p;202 203	p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,204			       VBVA_CURSOR_POSITION);205	if (!p)206		return -ENOMEM;207 208	p->report_position = report_position;209	p->x = x;210	p->y = y;211 212	hgsmi_buffer_submit(ctx, p);213 214	*x_host = p->x;215	*y_host = p->y;216 217	hgsmi_buffer_free(ctx, p);218 219	return 0;220}221