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