VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp@ 68642

Last change on this file since 68642 was 67268, checked in by vboxsync, 8 years ago

bugref:8524: Additions/linux: play nicely with distribution-installed Additions
[PATCH 1/2] Additions: VboxVideo: Fix compiler warning when building Linux vboxvideo driver
This commit fixes the following compiler warning:

drivers/staging/vboxvideo/osindependent/Modesetting.c: In function ‘VBoxHGSMIGetModeHints’:
drivers/staging/vboxvideo/osindependent/Modesetting.c:346:5: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]

void *p = VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVAQUERYMODEHINTS)
~

Signed-off-by: Hans de Goede <hdegoede@…>

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.6 KB
Line 
1/* $Id: Modesetting.cpp 67268 2017-06-06 11:54:32Z vboxsync $ */
2/** @file
3 * VirtualBox Video driver, common code - HGSMI initialisation and helper
4 * functions.
5 */
6
7/*
8 * Copyright (C) 2006-2017 Oracle Corporation
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26 * OTHER DEALINGS IN THE SOFTWARE.
27 */
28
29#include <VBoxVideoGuest.h>
30#include <VBoxVideoVBE.h>
31
32#ifndef VBOX_GUESTR3XF86MOD
33# include <VBoxVideoIPRT.h>
34#endif
35
36/**
37 * Gets the count of virtual monitors attached to the guest via an HGSMI
38 * command
39 *
40 * @returns the right count on success or 1 on failure.
41 * @param pCtx the context containing the heap to use
42 */
43DECLHIDDEN(uint32_t) VBoxHGSMIGetMonitorCount(PHGSMIGUESTCOMMANDCONTEXT pCtx)
44{
45 /* Query the configured number of displays. */
46 uint32_t cDisplays = 0;
47 VBoxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_MONITOR_COUNT, &cDisplays);
48 // LogFunc(("cDisplays = %d\n", cDisplays));
49 if (cDisplays == 0 || cDisplays > VBOX_VIDEO_MAX_SCREENS)
50 /* Host reported some bad value. Continue in the 1 screen mode. */
51 cDisplays = 1;
52 return cDisplays;
53}
54
55
56/**
57 * Returns the size of the video RAM in bytes.
58 *
59 * @returns the size
60 */
61DECLHIDDEN(uint32_t) VBoxVideoGetVRAMSize(void)
62{
63 /** @note A 32bit read on this port returns the VRAM size. */
64 return VBVO_PORT_READ_U32(VBE_DISPI_IOPORT_DATA);
65}
66
67
68/**
69 * Check whether this hardware allows the display width to have non-multiple-
70 * of-eight values.
71 *
72 * @returns true if any width is allowed, false otherwise.
73 */
74DECLHIDDEN(bool) VBoxVideoAnyWidthAllowed(void)
75{
76 unsigned DispiId;
77 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
78 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_ANYX);
79 DispiId = VBVO_PORT_READ_U16(VBE_DISPI_IOPORT_DATA);
80 return (DispiId == VBE_DISPI_ID_ANYX);
81}
82
83
84/**
85 * Tell the host about how VRAM is divided up between each screen via an HGSMI
86 * command. It is acceptable to specifiy identical data for each screen if
87 * they share a single framebuffer.
88 *
89 * @returns iprt status code, either VERR_NO_MEMORY or the status returned by
90 * @a pfnFill
91 * @todo What was I thinking of with that callback function? It
92 * would be much simpler to just pass in a structure in normal
93 * memory and copy it.
94 * @param pCtx the context containing the heap to use
95 * @param u32Count the number of screens we are activating
96 * @param pfnFill a callback which initialises the VBVAINFOVIEW structures
97 * for all screens
98 * @param pvData context data for @a pfnFill
99 */
100DECLHIDDEN(int) VBoxHGSMISendViewInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
101 uint32_t u32Count,
102 PFNHGSMIFILLVIEWINFO pfnFill,
103 void *pvData)
104{
105 int rc;
106 /* Issue the screen info command. */
107 void *p = VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVAINFOVIEW) * u32Count,
108 HGSMI_CH_VBVA, VBVA_INFO_VIEW);
109 if (p)
110 {
111 VBVAINFOVIEW *pInfo = (VBVAINFOVIEW *)p;
112 rc = pfnFill(pvData, pInfo, u32Count);
113 if (RT_SUCCESS(rc))
114 VBoxHGSMIBufferSubmit (pCtx, p);
115 VBoxHGSMIBufferFree(pCtx, p);
116 }
117 else
118 rc = VERR_NO_MEMORY;
119 return rc;
120}
121
122
123/**
124 * Set a video mode using port registers. This must be done for the first
125 * screen before every HGSMI modeset and also works when HGSM is not enabled.
126 * @param cWidth the mode width
127 * @param cHeight the mode height
128 * @param cVirtWidth the mode pitch
129 * @param cBPP the colour depth of the mode
130 * @param fFlags flags for the mode. These will be or-ed with the
131 * default _ENABLED flag, so unless you are restoring
132 * a saved mode or have special requirements you can pass
133 * zero here.
134 * @param cx the horizontal panning offset
135 * @param cy the vertical panning offset
136 */
137DECLHIDDEN(void) VBoxVideoSetModeRegisters(uint16_t cWidth, uint16_t cHeight,
138 uint16_t cVirtWidth, uint16_t cBPP,
139 uint16_t fFlags, uint16_t cx,
140 uint16_t cy)
141{
142 /* set the mode characteristics */
143 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES);
144 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_DATA, cWidth);
145 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES);
146 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_DATA, cHeight);
147 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX,
148 VBE_DISPI_INDEX_VIRT_WIDTH);
149 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_DATA, cVirtWidth);
150 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP);
151 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_DATA, cBPP);
152 /* enable the mode */
153 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX,
154 VBE_DISPI_INDEX_ENABLE);
155 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_DATA,
156 fFlags | VBE_DISPI_ENABLED);
157 /* Panning registers */
158 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX,
159 VBE_DISPI_INDEX_X_OFFSET);
160 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_DATA, cx);
161 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX,
162 VBE_DISPI_INDEX_Y_OFFSET);
163 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_DATA, cy);
164 /** @todo read from the port to see if the mode switch was successful */
165}
166
167
168/**
169 * Get the video mode for the first screen using the port registers. All
170 * parameters are optional
171 * @returns true if the VBE mode returned is active, false if we are in VGA
172 * mode
173 * @note If anyone else needs additional register values just extend the
174 * function with additional parameters and fix any existing callers.
175 * @param pcWidth where to store the mode width
176 * @param pcHeight where to store the mode height
177 * @param pcVirtWidth where to store the mode pitch
178 * @param pcBPP where to store the colour depth of the mode
179 * @param pfFlags where to store the flags for the mode
180 */
181DECLHIDDEN(bool) VBoxVideoGetModeRegisters(uint16_t *pcWidth, uint16_t *pcHeight,
182 uint16_t *pcVirtWidth, uint16_t *pcBPP,
183 uint16_t *pfFlags)
184{
185 uint16_t fFlags;
186
187 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX,
188 VBE_DISPI_INDEX_ENABLE);
189 fFlags = VBVO_PORT_READ_U16(VBE_DISPI_IOPORT_DATA);
190 if (pcWidth)
191 {
192 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX,
193 VBE_DISPI_INDEX_XRES);
194 *pcWidth = VBVO_PORT_READ_U16(VBE_DISPI_IOPORT_DATA);
195 }
196 if (pcHeight)
197 {
198 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX,
199 VBE_DISPI_INDEX_YRES);
200 *pcHeight = VBVO_PORT_READ_U16(VBE_DISPI_IOPORT_DATA);
201 }
202 if (pcVirtWidth)
203 {
204 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX,
205 VBE_DISPI_INDEX_VIRT_WIDTH);
206 *pcVirtWidth = VBVO_PORT_READ_U16(VBE_DISPI_IOPORT_DATA);
207 }
208 if (pcBPP)
209 {
210 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX,
211 VBE_DISPI_INDEX_BPP);
212 *pcBPP = VBVO_PORT_READ_U16(VBE_DISPI_IOPORT_DATA);
213 }
214 if (pfFlags)
215 *pfFlags = fFlags;
216 return RT_BOOL(fFlags & VBE_DISPI_ENABLED);
217}
218
219
220/**
221 * Disable our extended graphics mode and go back to VGA mode.
222 */
223DECLHIDDEN(void) VBoxVideoDisableVBE(void)
224{
225 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX,
226 VBE_DISPI_INDEX_ENABLE);
227 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_DATA, 0);
228}
229
230
231/**
232 * Set a video mode via an HGSMI request. The views must have been
233 * initialised first using @a VBoxHGSMISendViewInfo and if the mode is being
234 * set on the first display then it must be set first using registers.
235 * @param pCtx The context containing the heap to use.
236 * @param cDisplay the screen number
237 * @param cOriginX the horizontal displacement relative to the first screen
238 * @param cOriginY the vertical displacement relative to the first screen
239 * @param offStart the offset of the visible area of the framebuffer
240 * relative to the framebuffer start
241 * @param cbPitch the offset in bytes between the starts of two adjecent
242 * scan lines in video RAM
243 * @param cWidth the mode width
244 * @param cHeight the mode height
245 * @param cBPP the colour depth of the mode
246 * @param fFlags flags
247 */
248DECLHIDDEN(void) VBoxHGSMIProcessDisplayInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
249 uint32_t cDisplay,
250 int32_t cOriginX,
251 int32_t cOriginY,
252 uint32_t offStart,
253 uint32_t cbPitch,
254 uint32_t cWidth,
255 uint32_t cHeight,
256 uint16_t cBPP,
257 uint16_t fFlags)
258{
259 /* Issue the screen info command. */
260 void *p = VBoxHGSMIBufferAlloc(pCtx,
261 sizeof (VBVAINFOSCREEN),
262 HGSMI_CH_VBVA,
263 VBVA_INFO_SCREEN);
264 if (!p)
265 {
266 // LogFunc(("HGSMIHeapAlloc failed\n"));
267 }
268 else
269 {
270 VBVAINFOSCREEN *pScreen = (VBVAINFOSCREEN *)p;
271
272 pScreen->u32ViewIndex = cDisplay;
273 pScreen->i32OriginX = cOriginX;
274 pScreen->i32OriginY = cOriginY;
275 pScreen->u32StartOffset = offStart;
276 pScreen->u32LineSize = cbPitch;
277 pScreen->u32Width = cWidth;
278 pScreen->u32Height = cHeight;
279 pScreen->u16BitsPerPixel = cBPP;
280 pScreen->u16Flags = fFlags;
281
282 VBoxHGSMIBufferSubmit(pCtx, p);
283
284 VBoxHGSMIBufferFree(pCtx, p);
285 }
286}
287
288
289/** Report the rectangle relative to which absolute pointer events should be
290 * expressed. This information remains valid until the next VBVA resize event
291 * for any screen, at which time it is reset to the bounding rectangle of all
292 * virtual screens.
293 * @param pCtx The context containing the heap to use.
294 * @param cOriginX Upper left X co-ordinate relative to the first screen.
295 * @param cOriginY Upper left Y co-ordinate relative to the first screen.
296 * @param cWidth Rectangle width.
297 * @param cHeight Rectangle height.
298 * @returns iprt status code.
299 * @returns VERR_NO_MEMORY HGSMI heap allocation failed.
300 */
301DECLHIDDEN(int) VBoxHGSMIUpdateInputMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx, int32_t cOriginX, int32_t cOriginY,
302 uint32_t cWidth, uint32_t cHeight)
303{
304 int rc = VINF_SUCCESS;
305 VBVAREPORTINPUTMAPPING *p;
306 // Log(("%s: cOriginX=%d, cOriginY=%d, cWidth=%u, cHeight=%u\n", __PRETTY_FUNCTION__, (int)cOriginX, (int)cOriginX,
307 // (unsigned)cWidth, (unsigned)cHeight));
308
309 /* Allocate the IO buffer. */
310 p = (VBVAREPORTINPUTMAPPING *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVAREPORTINPUTMAPPING), HGSMI_CH_VBVA,
311 VBVA_REPORT_INPUT_MAPPING);
312 if (p)
313 {
314 /* Prepare data to be sent to the host. */
315 p->x = cOriginX;
316 p->y = cOriginY;
317 p->cx = cWidth;
318 p->cy = cHeight;
319 rc = VBoxHGSMIBufferSubmit(pCtx, p);
320 /* Free the IO buffer. */
321 VBoxHGSMIBufferFree(pCtx, p);
322 }
323 else
324 rc = VERR_NO_MEMORY;
325 // LogFunc(("rc = %d\n", rc));
326 return rc;
327}
328
329
330/**
331 * Get most recent video mode hints.
332 * @param pCtx the context containing the heap to use
333 * @param cScreens the number of screens to query hints for, starting at 0.
334 * @param paHints array of VBVAMODEHINT structures for receiving the hints.
335 * @returns iprt status code
336 * @returns VERR_NO_MEMORY HGSMI heap allocation failed.
337 * @returns VERR_NOT_SUPPORTED Host does not support this command.
338 */
339DECLHIDDEN(int) VBoxHGSMIGetModeHints(PHGSMIGUESTCOMMANDCONTEXT pCtx,
340 unsigned cScreens, VBVAMODEHINT *paHints)
341{
342 int rc;
343 void *p;
344
345 AssertPtr(paHints);
346 if (!VALID_PTR(paHints))
347 return VERR_INVALID_POINTER;
348
349 p = VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVAQUERYMODEHINTS)
350 + cScreens * sizeof(VBVAMODEHINT),
351 HGSMI_CH_VBVA, VBVA_QUERY_MODE_HINTS);
352 if (!p)
353 {
354 // LogFunc(("HGSMIHeapAlloc failed\n"));
355 return VERR_NO_MEMORY;
356 }
357 else
358 {
359 VBVAQUERYMODEHINTS *pQuery = (VBVAQUERYMODEHINTS *)p;
360
361 pQuery->cHintsQueried = cScreens;
362 pQuery->cbHintStructureGuest = sizeof(VBVAMODEHINT);
363 pQuery->rc = VERR_NOT_SUPPORTED;
364
365 VBoxHGSMIBufferSubmit(pCtx, p);
366 rc = pQuery->rc;
367 if (RT_SUCCESS(rc))
368 memcpy(paHints, ((uint8_t *)p) + sizeof(VBVAQUERYMODEHINTS),
369 cScreens * sizeof(VBVAMODEHINT));
370
371 VBoxHGSMIBufferFree(pCtx, p);
372 }
373 return rc;
374}
375
376
377/**
378 * Query the supported flags in VBVAINFOSCREEN::u16Flags.
379 *
380 * @returns The mask of VBVA_SCREEN_F_* flags or 0 if host does not support the request.
381 * @param pCtx the context containing the heap to use
382 */
383DECLHIDDEN(uint16_t) VBoxHGSMIGetScreenFlags(PHGSMIGUESTCOMMANDCONTEXT pCtx)
384{
385 uint32_t u32Flags = 0;
386 int rc = VBoxQueryConfHGSMIDef(pCtx, VBOX_VBVA_CONF32_SCREEN_FLAGS, 0, &u32Flags);
387 // LogFunc(("u32Flags = 0x%x rc %Rrc\n", u32Flags, rc));
388 if (RT_FAILURE(rc))
389 u32Flags = 0;
390 return (uint16_t)u32Flags;
391}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette