1 /*
2  * Copyright (C) 2006-2017 Oracle Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include "vbox_drv.h"
24 #include "vbox_err.h"
25 #include "vboxvideo_guest.h"
26 #include "vboxvideo_vbe.h"
27 #include "hgsmi_channels.h"
28 
29 /**
30  * Set a video mode via an HGSMI request.  The views must have been
31  * initialised first using @a VBoxHGSMISendViewInfo and if the mode is being
32  * set on the first display then it must be set first using registers.
33  * @param  ctx           The context containing the heap to use
34  * @param  display       The screen number
35  * @param  origin_x      The horizontal displacement relative to the first scrn
36  * @param  origin_y      The vertical displacement relative to the first screen
37  * @param  start_offset  The offset of the visible area of the framebuffer
38  *                       relative to the framebuffer start
39  * @param  pitch         The offset in bytes between the starts of two adjecent
40  *                       scan lines in video RAM
41  * @param  width         The mode width
42  * @param  height        The mode height
43  * @param  bpp           The colour depth of the mode
44  * @param  flags         Flags
45  */
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)46 void hgsmi_process_display_info(struct gen_pool *ctx, u32 display,
47 				s32 origin_x, s32 origin_y, u32 start_offset,
48 				u32 pitch, u32 width, u32 height,
49 				u16 bpp, u16 flags)
50 {
51 	struct vbva_infoscreen *p;
52 
53 	p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
54 			       VBVA_INFO_SCREEN);
55 	if (!p)
56 		return;
57 
58 	p->view_index = display;
59 	p->origin_x = origin_x;
60 	p->origin_y = origin_y;
61 	p->start_offset = start_offset;
62 	p->line_size = pitch;
63 	p->width = width;
64 	p->height = height;
65 	p->bits_per_pixel = bpp;
66 	p->flags = flags;
67 
68 	hgsmi_buffer_submit(ctx, p);
69 	hgsmi_buffer_free(ctx, p);
70 }
71 
72 /**
73  * Report the rectangle relative to which absolute pointer events should be
74  * expressed.  This information remains valid until the next VBVA resize event
75  * for any screen, at which time it is reset to the bounding rectangle of all
76  * virtual screens.
77  * @param  ctx       The context containing the heap to use.
78  * @param  origin_x  Upper left X co-ordinate relative to the first screen.
79  * @param  origin_y  Upper left Y co-ordinate relative to the first screen.
80  * @param  width     Rectangle width.
81  * @param  height    Rectangle height.
82  * @returns 0 on success, -errno on failure
83  */
hgsmi_update_input_mapping(struct gen_pool * ctx,s32 origin_x,s32 origin_y,u32 width,u32 height)84 int hgsmi_update_input_mapping(struct gen_pool *ctx, s32 origin_x, s32 origin_y,
85 			       u32 width, u32 height)
86 {
87 	struct vbva_report_input_mapping *p;
88 
89 	p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
90 			       VBVA_REPORT_INPUT_MAPPING);
91 	if (!p)
92 		return -ENOMEM;
93 
94 	p->x = origin_x;
95 	p->y = origin_y;
96 	p->cx = width;
97 	p->cy = height;
98 
99 	hgsmi_buffer_submit(ctx, p);
100 	hgsmi_buffer_free(ctx, p);
101 
102 	return 0;
103 }
104 
105 /**
106  * Get most recent video mode hints.
107  * @param  ctx      The context containing the heap to use.
108  * @param  screens  The number of screens to query hints for, starting at 0.
109  * @param  hints    Array of vbva_modehint structures for receiving the hints.
110  * @returns 0 on success, -errno on failure
111  */
hgsmi_get_mode_hints(struct gen_pool * ctx,unsigned int screens,struct vbva_modehint * hints)112 int hgsmi_get_mode_hints(struct gen_pool *ctx, unsigned int screens,
113 			 struct vbva_modehint *hints)
114 {
115 	struct vbva_query_mode_hints *p;
116 	size_t size;
117 
118 	if (WARN_ON(!hints))
119 		return -EINVAL;
120 
121 	size = screens * sizeof(struct vbva_modehint);
122 	p = hgsmi_buffer_alloc(ctx, sizeof(*p) + size, HGSMI_CH_VBVA,
123 			       VBVA_QUERY_MODE_HINTS);
124 	if (!p)
125 		return -ENOMEM;
126 
127 	p->hints_queried_count = screens;
128 	p->hint_structure_guest_size = sizeof(struct vbva_modehint);
129 	p->rc = VERR_NOT_SUPPORTED;
130 
131 	hgsmi_buffer_submit(ctx, p);
132 
133 	if (RT_FAILURE(p->rc)) {
134 		hgsmi_buffer_free(ctx, p);
135 		return -EIO;
136 	}
137 
138 	memcpy(hints, ((u8 *)p) + sizeof(struct vbva_query_mode_hints), size);
139 	hgsmi_buffer_free(ctx, p);
140 
141 	return 0;
142 }
143