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