1 // SPDX-License-Identifier: MIT 2 /* 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 10 /** 11 * Set a video mode via an HGSMI request. The views must have been 12 * initialised first using @a VBoxHGSMISendViewInfo and if the mode is being 13 * set on the first display then it must be set first using registers. 14 * @ctx: The context containing the heap to use. 15 * @display: The screen number. 16 * @origin_x: The horizontal displacement relative to the first scrn. 17 * @origin_y: The vertical displacement relative to the first screen. 18 * @start_offset: The offset of the visible area of the framebuffer 19 * relative to the framebuffer start. 20 * @pitch: The offset in bytes between the starts of two adjecent 21 * scan lines in video RAM. 22 * @width: The mode width. 23 * @height: The mode height. 24 * @bpp: The colour depth of the mode. 25 * @flags: Flags. 26 */ 27 void hgsmi_process_display_info(struct gen_pool *ctx, u32 display, 28 s32 origin_x, s32 origin_y, u32 start_offset, 29 u32 pitch, u32 width, u32 height, 30 u16 bpp, u16 flags) 31 { 32 struct vbva_infoscreen *p; 33 34 p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, 35 VBVA_INFO_SCREEN); 36 if (!p) 37 return; 38 39 p->view_index = display; 40 p->origin_x = origin_x; 41 p->origin_y = origin_y; 42 p->start_offset = start_offset; 43 p->line_size = pitch; 44 p->width = width; 45 p->height = height; 46 p->bits_per_pixel = bpp; 47 p->flags = flags; 48 49 hgsmi_buffer_submit(ctx, p); 50 hgsmi_buffer_free(ctx, p); 51 } 52 53 /** 54 * Report the rectangle relative to which absolute pointer events should be 55 * expressed. This information remains valid until the next VBVA resize event 56 * for any screen, at which time it is reset to the bounding rectangle of all 57 * virtual screens. 58 * Return: 0 or negative errno value. 59 * @ctx: The context containing the heap to use. 60 * @origin_x: Upper left X co-ordinate relative to the first screen. 61 * @origin_y: Upper left Y co-ordinate relative to the first screen. 62 * @width: Rectangle width. 63 * @height: Rectangle height. 64 */ 65 int hgsmi_update_input_mapping(struct gen_pool *ctx, s32 origin_x, s32 origin_y, 66 u32 width, u32 height) 67 { 68 struct vbva_report_input_mapping *p; 69 70 p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, 71 VBVA_REPORT_INPUT_MAPPING); 72 if (!p) 73 return -ENOMEM; 74 75 p->x = origin_x; 76 p->y = origin_y; 77 p->cx = width; 78 p->cy = height; 79 80 hgsmi_buffer_submit(ctx, p); 81 hgsmi_buffer_free(ctx, p); 82 83 return 0; 84 } 85 86 /** 87 * Get most recent video mode hints. 88 * Return: 0 or negative errno value. 89 * @ctx: The context containing the heap to use. 90 * @screens: The number of screens to query hints for, starting at 0. 91 * @hints: Array of vbva_modehint structures for receiving the hints. 92 */ 93 int hgsmi_get_mode_hints(struct gen_pool *ctx, unsigned int screens, 94 struct vbva_modehint *hints) 95 { 96 struct vbva_query_mode_hints *p; 97 size_t size; 98 99 if (WARN_ON(!hints)) 100 return -EINVAL; 101 102 size = screens * sizeof(struct vbva_modehint); 103 p = hgsmi_buffer_alloc(ctx, sizeof(*p) + size, HGSMI_CH_VBVA, 104 VBVA_QUERY_MODE_HINTS); 105 if (!p) 106 return -ENOMEM; 107 108 p->hints_queried_count = screens; 109 p->hint_structure_guest_size = sizeof(struct vbva_modehint); 110 p->rc = VERR_NOT_SUPPORTED; 111 112 hgsmi_buffer_submit(ctx, p); 113 114 if (p->rc < 0) { 115 hgsmi_buffer_free(ctx, p); 116 return -EIO; 117 } 118 119 memcpy(hints, ((u8 *)p) + sizeof(struct vbva_query_mode_hints), size); 120 hgsmi_buffer_free(ctx, p); 121 122 return 0; 123 } 124