| // 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; | |
| } |