0001
0002
0003
0004 #include <linux/vbox_err.h>
0005 #include "vbox_drv.h"
0006 #include "vboxvideo_guest.h"
0007 #include "vboxvideo_vbe.h"
0008 #include "hgsmi_channels.h"
0009 #include "hgsmi_ch_setup.h"
0010
0011
0012
0013
0014
0015
0016
0017
0018 int hgsmi_report_flags_location(struct gen_pool *ctx, u32 location)
0019 {
0020 struct hgsmi_buffer_location *p;
0021
0022 p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_HGSMI,
0023 HGSMI_CC_HOST_FLAGS_LOCATION);
0024 if (!p)
0025 return -ENOMEM;
0026
0027 p->buf_location = location;
0028 p->buf_len = sizeof(struct hgsmi_host_flags);
0029
0030 hgsmi_buffer_submit(ctx, p);
0031 hgsmi_buffer_free(ctx, p);
0032
0033 return 0;
0034 }
0035
0036
0037
0038
0039
0040
0041
0042
0043 int hgsmi_send_caps_info(struct gen_pool *ctx, u32 caps)
0044 {
0045 struct vbva_caps *p;
0046
0047 p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, VBVA_INFO_CAPS);
0048 if (!p)
0049 return -ENOMEM;
0050
0051 p->rc = VERR_NOT_IMPLEMENTED;
0052 p->caps = caps;
0053
0054 hgsmi_buffer_submit(ctx, p);
0055
0056 WARN_ON_ONCE(p->rc < 0);
0057
0058 hgsmi_buffer_free(ctx, p);
0059
0060 return 0;
0061 }
0062
0063 int hgsmi_test_query_conf(struct gen_pool *ctx)
0064 {
0065 u32 value = 0;
0066 int ret;
0067
0068 ret = hgsmi_query_conf(ctx, U32_MAX, &value);
0069 if (ret)
0070 return ret;
0071
0072 return value == U32_MAX ? 0 : -EIO;
0073 }
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083 int hgsmi_query_conf(struct gen_pool *ctx, u32 index, u32 *value_ret)
0084 {
0085 struct vbva_conf32 *p;
0086
0087 p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
0088 VBVA_QUERY_CONF32);
0089 if (!p)
0090 return -ENOMEM;
0091
0092 p->index = index;
0093 p->value = U32_MAX;
0094
0095 hgsmi_buffer_submit(ctx, p);
0096
0097 *value_ret = p->value;
0098
0099 hgsmi_buffer_free(ctx, p);
0100
0101 return 0;
0102 }
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 int hgsmi_update_pointer_shape(struct gen_pool *ctx, u32 flags,
0118 u32 hot_x, u32 hot_y, u32 width, u32 height,
0119 u8 *pixels, u32 len)
0120 {
0121 struct vbva_mouse_pointer_shape *p;
0122 u32 pixel_len = 0;
0123 int rc;
0124
0125 if (flags & VBOX_MOUSE_POINTER_SHAPE) {
0126
0127
0128
0129
0130 pixel_len = ((((width + 7) / 8) * height + 3) & ~3) +
0131 width * 4 * height;
0132 if (pixel_len > len)
0133 return -EINVAL;
0134
0135
0136
0137
0138
0139 flags |= VBOX_MOUSE_POINTER_VISIBLE;
0140 }
0141
0142 p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len, HGSMI_CH_VBVA,
0143 VBVA_MOUSE_POINTER_SHAPE);
0144 if (!p)
0145 return -ENOMEM;
0146
0147 p->result = VINF_SUCCESS;
0148 p->flags = flags;
0149 p->hot_X = hot_x;
0150 p->hot_y = hot_y;
0151 p->width = width;
0152 p->height = height;
0153 if (pixel_len)
0154 memcpy(p->data, pixels, pixel_len);
0155
0156 hgsmi_buffer_submit(ctx, p);
0157
0158 switch (p->result) {
0159 case VINF_SUCCESS:
0160 rc = 0;
0161 break;
0162 case VERR_NO_MEMORY:
0163 rc = -ENOMEM;
0164 break;
0165 case VERR_NOT_SUPPORTED:
0166 rc = -EBUSY;
0167 break;
0168 default:
0169 rc = -EINVAL;
0170 }
0171
0172 hgsmi_buffer_free(ctx, p);
0173
0174 return rc;
0175 }
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190 int hgsmi_cursor_position(struct gen_pool *ctx, bool report_position,
0191 u32 x, u32 y, u32 *x_host, u32 *y_host)
0192 {
0193 struct vbva_cursor_position *p;
0194
0195 p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
0196 VBVA_CURSOR_POSITION);
0197 if (!p)
0198 return -ENOMEM;
0199
0200 p->report_position = report_position;
0201 p->x = x;
0202 p->y = y;
0203
0204 hgsmi_buffer_submit(ctx, p);
0205
0206 *x_host = p->x;
0207 *y_host = p->y;
0208
0209 hgsmi_buffer_free(ctx, p);
0210
0211 return 0;
0212 }