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