- Timestamp:
- Mar 31, 2015 3:59:35 PM (10 years ago)
- Location:
- trunk/src/VBox/Additions
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp
r53970 r55043 466 466 467 467 468 /** Sanity test on first call. We do not worry about concurrency issues. */ 469 static int testQueryConf(PHGSMIGUESTCOMMANDCONTEXT pCtx) 470 { 471 static bool cOnce = false; 472 uint32_t ulValue = 0; 473 int rc; 474 475 if (cOnce) 476 return VINF_SUCCESS; 477 cOnce = true; 478 rc = VBoxQueryConfHGSMI(pCtx, UINT32_MAX, &ulValue); 479 if (RT_SUCCESS(rc) && ulValue == UINT32_MAX) 480 return VINF_SUCCESS; 481 cOnce = false; 482 if (RT_FAILURE(rc)) 483 return rc; 484 return VERR_INTERNAL_ERROR; 485 } 486 487 468 488 /** 469 489 * Query the host for an HGSMI configuration parameter via an HGSMI command. … … 481 501 LogFunc(("u32Index = %d\n", u32Index)); 482 502 503 rc = testQueryConf(pCtx); 504 if (RT_FAILURE(rc)) 505 return rc; 483 506 /* Allocate the IO buffer. */ 484 507 p = (VBVACONF32 *)VBoxHGSMIBufferAlloc(pCtx, … … 489 512 /* Prepare data to be sent to the host. */ 490 513 p->u32Index = u32Index; 491 p->u32Value = 0;514 p->u32Value = UINT32_MAX; 492 515 rc = VBoxHGSMIBufferSubmit(pCtx, p); 493 516 if (RT_SUCCESS(rc)) -
trunk/src/VBox/Additions/x11/VBoxClient/display.cpp
r54192 r55043 86 86 /** Tell the VBoxGuest driver we no longer want any events and tell the host 87 87 * we no longer support any capabilities. */ 88 static int disableEventsAndCaps( )88 static int disableEventsAndCaps(bool fDisableEvents) 89 89 { 90 90 int rc = VbglR3SetGuestCaps(0, VMMDEV_GUEST_SUPPORTS_GRAPHICS); … … 94 94 if (RT_FAILURE(rc)) 95 95 VBClFatalError(("Failed to unset mouse status, rc=%Rrc.\n", rc)); 96 rc = VbglR3CtlFilterMask(0, VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED97 96 if (fDisableEvents) 97 rc = VbglR3CtlFilterMask(0, VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED | VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST); 98 98 if (RT_FAILURE(rc)) 99 99 VBClFatalError(("Failed to unset filter mask, rc=%Rrc.\n", rc)); … … 174 174 static void updateSizeHintsProperty(struct DISPLAYSTATE *pState) 175 175 { 176 long *paSizeHints = (long *)RTMemTmpAllocZ(pState->cScreensTracked * sizeof(long) );176 long *paSizeHints = (long *)RTMemTmpAllocZ(pState->cScreensTracked * sizeof(long) * 2); 177 177 unsigned i; 178 178 … … 181 181 for (i = 0; i < pState->cScreensTracked; ++i) 182 182 { 183 if (pState->paScreenInformation[i].fEnabled) 184 paSizeHints[2 * i] = (pState->paScreenInformation[i].cx & 0x8fff) << 16 185 | (pState->paScreenInformation[i].cy & 0x8fff); 186 else if (pState->paScreenInformation[i].cx != 0 && pState->paScreenInformation[i].cy != 0) 187 paSizeHints[2 * i] = -1; 183 188 if ( pState->paScreenInformation[i].fEnabled 184 && pState->paScreenInformation[i].cx != 0 && pState->paScreenInformation[i].cy != 0) 185 paSizeHints[i] = (pState->paScreenInformation[i].cx & 0x8fff) << 16 | (pState->paScreenInformation[i].cy & 0x8fff); 186 else if (pState->paScreenInformation[i].cx != 0 && pState->paScreenInformation[i].cy != 0) 187 paSizeHints[i] = -1; 189 && pState->paScreenInformation[i].fUpdatePosition) 190 paSizeHints[2 * i + 1] = (pState->paScreenInformation[i].x & 0x8fff) << 16 191 | (pState->paScreenInformation[i].y & 0x8fff); 192 else 193 paSizeHints[2 * i + 1] = -1; 188 194 } 189 195 XChangeProperty(pState->pDisplay, DefaultRootWindow(pState->pDisplay), XInternAtom(pState->pDisplay, "VBOX_SIZE_HINTS", 0), 190 XA_INTEGER, 32, PropModeReplace, (unsigned char *)paSizeHints, pState->cScreensTracked );196 XA_INTEGER, 32, PropModeReplace, (unsigned char *)paSizeHints, pState->cScreensTracked * 2); 191 197 XFlush(pState->pDisplay); 192 198 RTMemTmpFree(paSizeHints); 193 199 } 194 200 195 static void notifyXServer (struct DISPLAYSTATE *pState)201 static void notifyXServerRandR11(struct DISPLAYSTATE *pState) 196 202 { 197 203 char szCommand[256]; 198 unsigned i;199 bool fUpdateInformation = false;200 204 201 205 /** @note The xrandr command can fail if something else accesses RandR at 202 206 * the same time. We just ignore failure for now and let the user try 203 207 * again as we do not know what someone else is doing. */ 204 for (i = 0; i < pState->cScreensTracked; ++i) 205 if (pState->paScreenInformation[i].fUpdateSize) 206 fUpdateInformation = true; 207 if ( !pState->fHaveRandR12 && pState->paScreenInformation[0].fUpdateSize 208 if ( pState->paScreenInformation[0].fUpdateSize 208 209 && pState->paScreenInformation[0].cx > 0 && pState->paScreenInformation[0].cy > 0) 209 210 { … … 212 213 system(szCommand); 213 214 pState->paScreenInformation[0].fUpdateSize = false; 214 }215 else if (pState->fHaveRandR12 && fUpdateInformation)216 for (i = 0; i < pState->cScreensTracked; ++i)217 {218 if (pState->paScreenInformation[i].fUpdateSize)219 {220 RTStrPrintf(szCommand, sizeof(szCommand), "%s --output VGA-%u --preferred", pState->pcszXrandr, i);221 system(szCommand);222 }223 if (pState->paScreenInformation[i].fUpdatePosition)224 {225 RTStrPrintf(szCommand, sizeof(szCommand), "%s --output VGA-%u --auto --pos %ux%u",226 pState->pcszXrandr, i, pState->paScreenInformation[i].x, pState->paScreenInformation[i].y);227 system(szCommand);228 }229 pState->paScreenInformation[i].fUpdateSize = pState->paScreenInformation[i].fUpdatePosition = false;230 }231 else232 {233 RTStrPrintf(szCommand, sizeof(szCommand), "%s", pState->pcszXrandr);234 system(szCommand);235 215 } 236 216 } … … 250 230 (unsigned char *)&fFeatures, 1); 251 231 XFlush(pState->pDisplay); 252 if (pState->fHaveRandR12)253 for (i = 0; i < pState->cScreensTracked; ++i)254 pState->paScreenInformation[i].fUpdateSize = true;255 else256 pState->paScreenInformation[0].fUpdateSize = true;257 232 } 258 233 … … 294 269 updateMouseCapabilities(pState); 295 270 updateSizeHintsProperty(pState); 296 notifyXServer(pState); 271 if (!pState->fHaveRandR12) 272 notifyXServerRandR11(pState); 297 273 do 298 274 rc = VbglR3WaitEvent( VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST … … 385 361 if (!pSelf->mfInit) 386 362 return VERR_WRONG_ORDER; 387 return disableEventsAndCaps( );363 return disableEventsAndCaps(false); 388 364 } 389 365 … … 400 376 { 401 377 NOREF(ppInterface); 402 disableEventsAndCaps( );378 disableEventsAndCaps(true); 403 379 VbglR3Term(); 404 380 } -
trunk/src/VBox/Additions/x11/undefined_xorg
r54531 r55043 106 106 __register_frame_info_bases 107 107 rename 108 RRC hangeOutputProperty108 RRCrtcNotify 109 109 RRGetInfo 110 RRScreenSizeNotify 111 RRTellChanged 110 112 setenv 111 113 ShadowFBInit2 … … 157 159 xf86CrtcCreate 158 160 xf86CrtcScreenInit 161 xf86CrtcSetMode 159 162 xf86CrtcSetSizeRange 160 163 xf86DestroyCursorInfoRec … … 174 177 xf86SetModeDefaultName 175 178 xf86SetSingleMode 179 xf86UpdateDesktopDimensions 176 180 __xstat64 -
trunk/src/VBox/Additions/x11/vboxvideo/README.testing
r54531 r55043 7 7 * Dynamic resizing should work, on CentOS 6 and later Linux guests it should 8 8 work without VBoxClient running. 9 * Disabling and enabling virtual screens ( only possible as of 4.4).9 * Disabling and enabling virtual screens (VBoxManage in 4.3). 10 10 * Dynamic resizing with one of more virtual screens disabled. 11 11 * Test switching to virtual terminals and back from windowed, full screen and 12 seamless modes. 12 seamless modes (seamless currently only works properly with VBoxClient 13 running). 13 14 * Test switching directly between normal, full-screen, seamless and scaled 14 15 modes. 15 * Test enabling and disabling guest screens from the host.16 16 * execute "xprop -root | grep VBOX" after resizing a screen: VBOX_SIZE_HINTS 17 17 should be set, and VBOX_SIZE_HINTS_MISMATCH should equal 0 on CentOS 6 and 18 later. 18 later (4.4 and later). 19 * Test re-ordering the virtual screen using the native guest operating system 20 tools and make sure that mouse integration still works as expected. 21 * Test disabling and re-enabling guest screens with the native system tools. 22 * Try disabling and re-enabling mouse integration and check that capturing 23 works with multiple guest screens. 19 24 * Shutting down and re-starting a virtual machine should restore the last size 20 for all monitors (note: currently only after log-in). 25 for all monitors (note: currently only after log-in). Full shut-down, not 26 a reboot. 27 * Test power management by disabling guest screens ("xrandr --output VGA-n 28 --off") and re-enabling them ("xrandr --output VGA-n --preferred --pos XxY") 29 where X and Y are the position of the screen before disabling it. 30 * Test sending video mode hints with screen position information via 31 VBoxManage. The screen position is a hint only. The approximate position 32 should be preserved after a shut down and re-start of the guest. 33 * Test re-starting the X server after resizing all guest windows. The server 34 should not crash. -
trunk/src/VBox/Additions/x11/vboxvideo/getmode.c
r54531 r55043 38 38 #ifdef VBOXVIDEO_13 39 39 # ifdef RT_OS_LINUX 40 # include "randrstr.h"41 # include "xf86_OSproc.h"42 40 # include <linux/input.h> 43 41 # ifndef EVIOCGRAB … … 53 51 # endif /* RT_OS_LINUX */ 54 52 #endif /* VBOXVIDEO_13 */ 53 55 54 /************************************************************************** 56 55 * Main functions * … … 99 98 } 100 99 101 /** vboxvideo's list of standard video modes */102 struct103 {104 /** mode width */105 uint32_t cx;106 /** mode height */107 uint32_t cy;108 } vboxStandardModes[] =109 {110 { 1600, 1200 },111 { 1440, 1050 },112 { 1280, 960 },113 { 1024, 768 },114 { 800, 600 },115 { 640, 480 },116 { 0, 0 }117 };118 enum119 {120 vboxNumStdModes = sizeof(vboxStandardModes) / sizeof(vboxStandardModes[0])121 };122 123 /**124 * Returns a standard mode which the host likes. Can be called multiple125 * times with the index returned by the previous call to get a list of modes.126 * @returns the index of the mode in the list, or 0 if no more modes are127 * available128 * @param pScrn the screen information structure129 * @param pScrn->bitsPerPixel130 * if this is non-null, only modes with this BPP will be131 * returned132 * @param cIndex the index of the last mode queried, or 0 to query the133 * first mode available. Note: the first index is 1134 * @param pcx where to store the mode's width135 * @param pcy where to store the mode's height136 * @param pcBits where to store the mode's BPP137 */138 unsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex,139 uint32_t *pcx, uint32_t *pcy)140 {141 unsigned i;142 143 VBVXASSERT(cIndex < vboxNumStdModes,144 ("cIndex = %d, vboxNumStdModes = %d\n", cIndex,145 vboxNumStdModes));146 for (i = cIndex; i < vboxNumStdModes - 1; ++i)147 {148 uint32_t cx = vboxStandardModes[i].cx;149 uint32_t cy = vboxStandardModes[i].cy;150 151 if (pcx)152 *pcx = cx;153 if (pcy)154 *pcy = cy;155 return i + 1;156 }157 return 0;158 }159 160 100 /** 161 101 * Allocates an empty display mode and links it into the doubly linked list of … … 188 128 * of the graphics modes that we wish to support, that is: 189 129 * - A dynamic mode in first place which will be updated by the RandR code. 190 * - Several standard modes.191 130 * - Any modes that the user requested in xorg.conf/XFree86Config. 192 131 */ … … 203 142 pMode = vboxAddEmptyScreenMode(pScrn); 204 143 vboxFillDisplayMode(pScrn, pMode, NULL, 1024, 768); 205 /* Add standard modes supported by the host */ 206 for ( ; ; ) 207 { 208 cIndex = vboxNextStandardMode(pScrn, cIndex, &cx, &cy); 209 if (cIndex == 0) 210 break; 211 pMode = vboxAddEmptyScreenMode(pScrn); 212 vboxFillDisplayMode(pScrn, pMode, NULL, cx, cy); 213 } 214 /* And finally any modes specified by the user. We assume here that 215 * the mode names reflect the mode sizes. */ 144 /* Add any modes specified by the user. We assume here that the mode names 145 * reflect the mode sizes. */ 216 146 for (i = 0; pScrn->display->modes && pScrn->display->modes[i]; i++) 217 147 { … … 224 154 } 225 155 226 /** Set the initial values for the guest screen size hints by reading saved 227 * values from files. */ 228 /** @todo Actually read the files instead of setting dummies. */ 156 /** Set the initial values for the guest screen size hints to standard values 157 * in case nothing else is available. */ 229 158 void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn) 230 159 { … … 242 171 pScrn->modes->HDisplay = pVBox->pScreens[0].aPreferredSize.cx; 243 172 pScrn->modes->VDisplay = pVBox->pScreens[0].aPreferredSize.cy; 244 /* RandR 1.1 quirk: make sure that the initial resolution is always present 245 * in the mode list as RandR will always advertise a mode of the initial 246 * virtual resolution via GetScreenInfo. */ 247 pMode = vboxAddEmptyScreenMode(pScrn); 248 vboxFillDisplayMode(pScrn, pMode, NULL, pVBox->pScreens[0].aPreferredSize.cx, 249 pVBox->pScreens[0].aPreferredSize.cy); 250 } 251 252 static void updateUseHardwareCursor(VBOXPtr pVBox, uint32_t fCursorCapabilities) 173 } 174 175 static bool useHardwareCursor(uint32_t fCursorCapabilities) 253 176 { 254 177 if ( !(fCursorCapabilities & VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER) 255 178 && (fCursorCapabilities & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE)) 256 pVBox->fUseHardwareCursor = true; 257 else 258 pVBox->fUseHardwareCursor = false; 259 } 260 261 # define SIZE_HINTS_PROPERTY "VBOX_SIZE_HINTS" 262 # define MOUSE_CAPABILITIES_PROPERTY "VBOX_MOUSE_CAPABILITIES" 263 264 /** Read in information about the most recent size hints requested for the 265 * guest screens. A client application sets the hint information as a root 266 * window property. */ 267 /* TESTING: dynamic resizing and absolute pointer toggling work on old guest X servers and recent ones on Linux at the log-in screen. */ 268 /** @note we try to maximise code coverage by typically using all code paths (HGSMI and properties) in a single X session. */ 269 void VBoxUpdateSizeHints(ScrnInfoPtr pScrn) 179 return true; 180 return false; 181 } 182 183 static void compareAndMaybeSetUseHardwareCursor(VBOXPtr pVBox, uint32_t fCursorCapabilities, bool *pfChanged, bool fSet) 184 { 185 if (pVBox->fUseHardwareCursor != useHardwareCursor(fCursorCapabilities)) 186 *pfChanged = true; 187 if (fSet) 188 pVBox->fUseHardwareCursor = useHardwareCursor(fCursorCapabilities); 189 } 190 191 #define SIZE_HINTS_PROPERTY "VBOX_SIZE_HINTS" 192 #define SIZE_HINTS_MISMATCH_PROPERTY "VBOX_SIZE_HINTS_MISMATCH" 193 #define MOUSE_CAPABILITIES_PROPERTY "VBOX_MOUSE_CAPABILITIES" 194 195 #define COMPARE_AND_MAYBE_SET(pDest, src, pfChanged, fSet) \ 196 do { \ 197 if (*(pDest) != (src)) \ 198 { \ 199 if (fSet) \ 200 *(pDest) = (src); \ 201 *(pfChanged) = true; \ 202 } \ 203 } while(0) 204 205 /** Read in information about the most recent size hints and cursor 206 * capabilities requested for the guest screens from a root window property set 207 * by an X11 client. Information obtained via HGSMI takes priority. */ 208 void vbvxReadSizesAndCursorIntegrationFromProperties(ScrnInfoPtr pScrn, bool *pfNeedUpdate) 270 209 { 271 210 VBOXPtr pVBox = VBOXGetRec(pScrn); 272 size_t cModesFromProperty, cDummy; 273 int32_t *paModeHints, *pfCursorCapabilities; 211 size_t cPropertyElements, cDummy; 212 int32_t *paModeHints, *pfCursorCapabilities; 213 int rc; 274 214 unsigned i; 275 uint32_t fCursorCapabilities; 276 bool fOldUseHardwareCursor = pVBox->fUseHardwareCursor; 277 278 if (vbvxGetIntegerPropery(pScrn, SIZE_HINTS_PROPERTY, &cModesFromProperty, &paModeHints) != VINF_SUCCESS) 215 bool fChanged; 216 bool fNeedUpdate = false; 217 int32_t fSizeMismatch = false; 218 219 if (vbvxGetIntegerPropery(pScrn, SIZE_HINTS_PROPERTY, &cPropertyElements, &paModeHints) != VINF_SUCCESS) 279 220 paModeHints = NULL; 280 if ( vbvxGetIntegerPropery(pScrn, MOUSE_CAPABILITIES_PROPERTY, &cDummy, &pfCursorCapabilities) != VINF_SUCCESS 281 || cDummy != 1) 282 pfCursorCapabilities = NULL; 283 #ifdef VBOXVIDEO_13 284 if (!pVBox->fHaveReadHGSMIModeHintData && RT_SUCCESS(VBoxHGSMIGetModeHints(&pVBox->guestCtx, pVBox->cScreens, 285 pVBox->paVBVAModeHints))) 286 { 287 for (i = 0; i < pVBox->cScreens; ++i) 221 if (paModeHints != NULL) 222 for (i = 0; i < cPropertyElements / 2 && i < pVBox->cScreens; ++i) 288 223 { 289 if (pVBox->paVBVAModeHints[i].magic == VBVAMODEHINT_MAGIC) 224 VBVAMODEHINT *pVBVAModeHint = &pVBox->paVBVAModeHints[i]; 225 int32_t iSizeHint = paModeHints[i * 2]; 226 int32_t iLocation = paModeHints[i * 2 + 1]; 227 bool fNoHGSMI = !pVBox->fHaveHGSMIModeHints || pVBVAModeHint->magic != VBVAMODEHINT_MAGIC; 228 229 fChanged = false; 230 if (iSizeHint != 0) 290 231 { 291 pVBox->pScreens[i].aPreferredSize.cx = pVBox->paVBVAModeHints[i].cx; 292 pVBox->pScreens[i].aPreferredSize.cy = pVBox->paVBVAModeHints[i].cy; 293 pVBox->pScreens[i].afConnected = pVBox->paVBVAModeHints[i].fEnabled; 294 /* Do not re-read this if we have data from HGSMI. */ 295 if (paModeHints != NULL && i < cModesFromProperty) 296 pVBox->pScreens[i].lastModeHintFromProperty = paModeHints[i]; 232 if (iSizeHint == -1) 233 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afConnected, false, &fChanged, fNoHGSMI); 234 else 235 { 236 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cx, (iSizeHint >> 16) & 0x8fff, &fChanged, fNoHGSMI); 237 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cy, iSizeHint & 0x8fff, &fChanged, fNoHGSMI); 238 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afConnected, true, &fChanged, fNoHGSMI); 239 } 240 if (iLocation == -1) 241 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afHaveLocation, false, &fChanged, fNoHGSMI); 242 else 243 { 244 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredLocation.x, (iLocation >> 16) & 0x8fff, &fChanged, 245 fNoHGSMI); 246 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredLocation.y, iLocation & 0x8fff, &fChanged, fNoHGSMI); 247 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afHaveLocation, true, &fChanged, fNoHGSMI); 248 } 249 if (fChanged && fNoHGSMI) 250 fNeedUpdate = true; 251 if (fChanged && !fNoHGSMI) 252 fSizeMismatch = true; 297 253 } 298 254 } 299 } 300 if (!pVBox->fHaveReadHGSMIModeHintData) 301 { 302 if (RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &fCursorCapabilities))) 303 updateUseHardwareCursor(pVBox, fCursorCapabilities); 304 else 305 pVBox->fUseHardwareCursor = false; 306 /* Do not re-read this if we have data from HGSMI. */ 307 if (pfCursorCapabilities != NULL) 308 pVBox->fLastCursorCapabilitiesFromProperty = *pfCursorCapabilities; 309 } 310 pVBox->fHaveReadHGSMIModeHintData = true; 311 #endif 312 if (paModeHints != NULL) 313 for (i = 0; i < cModesFromProperty && i < pVBox->cScreens; ++i) 255 fChanged = false; 256 if ( vbvxGetIntegerPropery(pScrn, MOUSE_CAPABILITIES_PROPERTY, &cDummy, &pfCursorCapabilities) == VINF_SUCCESS 257 && cDummy == 1) 258 compareAndMaybeSetUseHardwareCursor(pVBox, *pfCursorCapabilities, &fChanged, !pVBox->fHaveHGSMIModeHints); 259 if (fChanged && !pVBox->fHaveHGSMIModeHints) 260 fNeedUpdate = true; 261 if (fChanged && pVBox->fHaveHGSMIModeHints) 262 fSizeMismatch = true; 263 vbvxSetIntegerPropery(pScrn, SIZE_HINTS_MISMATCH_PROPERTY, 1, &fSizeMismatch, false); 264 if (pfNeedUpdate != NULL && fNeedUpdate) 265 *pfNeedUpdate = true; 266 } 267 268 /** Read in information about the most recent size hints and cursor 269 * capabilities requested for the guest screens from HGSMI. */ 270 void vbvxReadSizesAndCursorIntegrationFromHGSMI(ScrnInfoPtr pScrn, bool *pfNeedUpdate) 271 { 272 VBOXPtr pVBox = VBOXGetRec(pScrn); 273 int rc; 274 unsigned i; 275 bool fChanged = false; 276 uint32_t fCursorCapabilities; 277 278 if (!pVBox->fHaveHGSMIModeHints) 279 return; 280 rc = VBoxHGSMIGetModeHints(&pVBox->guestCtx, pVBox->cScreens, pVBox->paVBVAModeHints); 281 VBVXASSERT(rc == VINF_SUCCESS, ("VBoxHGSMIGetModeHints failed, rc=%d.\n", rc)); 282 for (i = 0; i < pVBox->cScreens; ++i) 283 if (pVBox->paVBVAModeHints[i].magic == VBVAMODEHINT_MAGIC) 314 284 { 315 if (paModeHints[i] != 0 && paModeHints[i] != pVBox->pScreens[i].lastModeHintFromProperty) 316 { 317 if (paModeHints[i] == -1) 318 pVBox->pScreens[i].afConnected = false; 319 else 320 { 321 pVBox->pScreens[i].aPreferredSize.cx = paModeHints[i] >> 16; 322 pVBox->pScreens[i].aPreferredSize.cy = paModeHints[i] & 0x8fff; 323 pVBox->pScreens[i].afConnected = true; 324 } 325 pVBox->pScreens[i].lastModeHintFromProperty = paModeHints[i]; 326 } 285 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cx, pVBox->paVBVAModeHints[i].cx & 0x8fff, &fChanged, true); 286 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cy, pVBox->paVBVAModeHints[i].cy & 0x8fff, &fChanged, true); 287 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afConnected, RT_BOOL(pVBox->paVBVAModeHints[i].fEnabled), &fChanged, true); 288 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredLocation.x, (int32_t)pVBox->paVBVAModeHints[i].dx & 0x8fff, &fChanged, 289 true); 290 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredLocation.y, (int32_t)pVBox->paVBVAModeHints[i].dy & 0x8fff, &fChanged, 291 true); 292 if (pVBox->paVBVAModeHints[i].dx != ~(uint32_t)0 && pVBox->paVBVAModeHints[i].dy != ~(uint32_t)0) 293 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afHaveLocation, true, &fChanged, true); 294 else 295 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afHaveLocation, false, &fChanged, true); 327 296 } 328 if (pfCursorCapabilities != NULL && *pfCursorCapabilities != pVBox->fLastCursorCapabilitiesFromProperty) 329 { 330 updateUseHardwareCursor(pVBox, (uint32_t)*pfCursorCapabilities); 331 pVBox->fLastCursorCapabilitiesFromProperty = *pfCursorCapabilities; 332 } 333 if (pVBox->fUseHardwareCursor != fOldUseHardwareCursor) 334 vbvxReprobeCursor(pScrn); 335 } 336 337 #ifndef VBOXVIDEO_13 338 339 /** The RandR "proc" vector, which we wrap with our own in order to notice 340 * when a client sends a GetScreenInfo request. */ 341 static int (*g_pfnVBoxRandRProc)(ClientPtr) = NULL; 342 /** The swapped RandR "proc" vector. */ 343 static int (*g_pfnVBoxRandRSwappedProc)(ClientPtr) = NULL; 344 345 /* TESTING: dynamic resizing and toggling cursor integration work with older guest X servers (1.2 and older). */ 346 static void vboxRandRDispatchCore(ClientPtr pClient) 347 { 348 xRRGetScreenInfoReq *pReq = (xRRGetScreenInfoReq *)pClient->requestBuffer; 349 WindowPtr pWin; 350 ScrnInfoPtr pScrn; 351 VBOXPtr pVBox; 352 DisplayModePtr pMode; 353 354 if (pClient->req_len != sizeof(xRRGetScreenInfoReq) >> 2) 355 return; 356 pWin = (WindowPtr)SecurityLookupWindow(pReq->window, pClient, 357 SecurityReadAccess); 358 if (!pWin) 359 return; 360 pScrn = xf86Screens[pWin->drawable.pScreen->myNum]; 361 pVBox = VBOXGetRec(pScrn); 362 TRACE_LOG("pVBox->fUseHardwareCursor=%u\n", pVBox->fUseHardwareCursor); 363 VBoxUpdateSizeHints(pScrn); 364 pMode = pScrn->modes; 365 if (pScrn->currentMode == pMode) 366 pMode = pMode->next; 367 pMode->HDisplay = pVBox->pScreens[0].aPreferredSize.cx; 368 pMode->VDisplay = pVBox->pScreens[0].aPreferredSize.cy; 369 } 370 371 static int vboxRandRDispatch(ClientPtr pClient) 372 { 373 xReq *pReq = (xReq *)pClient->requestBuffer; 374 375 if (pReq->data == X_RRGetScreenInfo) 376 vboxRandRDispatchCore(pClient); 377 return g_pfnVBoxRandRProc(pClient); 378 } 379 380 static int vboxRandRSwappedDispatch(ClientPtr pClient) 381 { 382 xReq *pReq = (xReq *)pClient->requestBuffer; 383 384 if (pReq->data == X_RRGetScreenInfo) 385 vboxRandRDispatchCore(pClient); 386 return g_pfnVBoxRandRSwappedProc(pClient); 387 } 388 389 static Bool vboxRandRCreateScreenResources(ScreenPtr pScreen) 390 { 391 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 392 VBOXPtr pVBox = VBOXGetRec(pScrn); 393 ExtensionEntry *pExt; 394 395 pScreen->CreateScreenResources = pVBox->pfnCreateScreenResources; 396 if (!pScreen->CreateScreenResources(pScreen)) 397 return FALSE; 398 /* I doubt we can be loaded twice - should I fail here? */ 399 if (g_pfnVBoxRandRProc) 400 return TRUE; 401 pExt = CheckExtension(RANDR_NAME); 402 if (!pExt) 403 { 404 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 405 "RandR extension not found, disabling dynamic resizing.\n"); 406 return TRUE; 407 } 408 if ( !ProcVector[pExt->base] 409 #if !defined(XF86_VERSION_CURRENT) \ 410 || XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4, 3, 99, 0, 0) 411 /* SwappedProcVector is not exported in XFree86, so we will not support 412 * swapped byte order clients. I doubt this is a big issue. */ 413 || !SwappedProcVector[pExt->base] 414 #endif 415 ) 416 FatalError("RandR \"proc\" vector not initialised\n"); 417 g_pfnVBoxRandRProc = ProcVector[pExt->base]; 418 ProcVector[pExt->base] = vboxRandRDispatch; 419 #if !defined(XF86_VERSION_CURRENT) \ 420 || XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4, 3, 99, 0, 0) 421 g_pfnVBoxRandRSwappedProc = SwappedProcVector[pExt->base]; 422 SwappedProcVector[pExt->base] = vboxRandRSwappedDispatch; 423 #endif 424 return TRUE; 425 } 426 427 /** Install our private RandR hook procedure, so that we can detect 428 * GetScreenInfo requests from clients to update our dynamic mode. This works 429 * by installing a wrapper around CreateScreenResources(), which will be called 430 * after RandR is initialised. The wrapper then in turn wraps the RandR "proc" 431 * vectors with its own handlers which will get called on any client RandR 432 * request. This should not be used in conjunction with RandR 1.2 or later. 433 * A couple of points of interest in our RandR 1.1 support: 434 * * We use the first two screen modes as dynamic modes. When a new mode hint 435 * arrives we update the first of the two which is not the current mode with 436 * the new size. 437 * * RandR 1.1 always advertises a mode of the size of the initial virtual 438 * resolution via GetScreenInfo(), so we make sure that a mode of that size 439 * is always present in the list. 440 * * RandR adds each new mode it sees to an internal array, but never removes 441 * entries. This array might end up getting rather long given that we can 442 * report a lot more modes than physical hardware. 443 */ 444 void VBoxSetUpRandR11(ScreenPtr pScreen) 445 { 446 VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]); 447 448 if (!pScreen->CreateScreenResources) 449 FatalError("called to early: CreateScreenResources not yet initialised\n"); 450 pVBox->pfnCreateScreenResources = pScreen->CreateScreenResources; 451 pScreen->CreateScreenResources = vboxRandRCreateScreenResources; 452 } 453 454 #endif /* !VBOXVIDEO_13 */ 297 rc = VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &fCursorCapabilities); 298 VBVXASSERT(rc == VINF_SUCCESS, ("Getting VBOX_VBVA_CONF32_CURSOR_CAPABILITIES failed, rc=%d.\n", rc)); 299 compareAndMaybeSetUseHardwareCursor(pVBox, fCursorCapabilities, &fChanged, true); 300 if (pfNeedUpdate != NULL && fChanged) 301 *pfNeedUpdate = true; 302 } 303 304 #undef COMPARE_AND_MAYBE_SET 455 305 456 306 #ifdef VBOXVIDEO_13 457 307 # ifdef RT_OS_LINUX 458 /* TESTING: dynamic resizing works on recent Linux guest X servers at the log-in screen. */ 459 /** @note to maximise code coverage we only read data from HGSMI once, and only when responding to an ACPI event. */ 308 /** We have this for two purposes: one is to ensure that the X server is woken 309 * up when we get a video ACPI event. Two is to grab ACPI video events to 310 * prevent gnome-settings-daemon from seeing them, as older versions ignored 311 * the time stamp and handled them at the wrong time. */ 460 312 static void acpiEventHandler(int fd, void *pvData) 461 313 { … … 465 317 ssize_t rc; 466 318 467 pVBox->fHaveReadHGSMIModeHintData = false;468 RRGetInfo(pScreen469 # if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5470 , TRUE471 # endif472 );473 VBVXASSERT(pVBox->fHaveReadHGSMIModeHintData == true, ("fHaveReadHGSMIModeHintData not set.\n"));474 319 do 475 320 rc = read(fd, &event, sizeof(event)); … … 479 324 } 480 325 481 void VBoxSetUpLinuxACPI(ScreenPtr pScreen)326 void vbvxSetUpLinuxACPI(ScreenPtr pScreen) 482 327 { 483 328 VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]); … … 529 374 } 530 375 531 void VBoxCleanUpLinuxACPI(ScreenPtr pScreen)376 void vbvxCleanUpLinuxACPI(ScreenPtr pScreen) 532 377 { 533 378 VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]); … … 540 385 # endif /* RT_OS_LINUX */ 541 386 #endif /* VBOXVIDEO_13 */ 387 -
trunk/src/VBox/Additions/x11/vboxvideo/helpers.c
r54531 r55043 55 55 } 56 56 57 /* TESTING: if this is broken, dynamic resizing will not work on old X servers (1.2 and older). */58 57 int vbvxGetIntegerPropery(ScrnInfoPtr pScrn, char *pszName, size_t *pcData, int32_t **ppaData) 59 58 { … … 64 63 if (!ROOT_WINDOW(pScrn)) 65 64 return VERR_NOT_FOUND; 66 atom = MakeAtom(pszName, strlen(pszName), FALSE);65 atom = MakeAtom(pszName, strlen(pszName), TRUE); 67 66 if (atom == BAD_RESOURCE) 68 67 return VERR_NOT_FOUND; … … 76 75 *ppaData = (int32_t *)prop->data; 77 76 return VINF_SUCCESS; 77 } 78 79 void vbvxSetIntegerPropery(ScrnInfoPtr pScrn, char *pszName, size_t cData, int32_t *paData, Bool fSendEvent) 80 { 81 Atom property_name; 82 int i; 83 84 property_name = MakeAtom(pszName, strlen(pszName), TRUE); 85 VBVXASSERT(property_name != BAD_RESOURCE, ("Failed to set atom \"%s\"\n", pszName)); 86 ChangeWindowProperty(ROOT_WINDOW(pScrn), property_name, XA_INTEGER, 32, PropModeReplace, cData, paData, fSendEvent); 78 87 } 79 88 -
trunk/src/VBox/Additions/x11/vboxvideo/setmode.c
r54531 r55043 75 75 * size of a new framebuffer. Framebuffer sizes larger than available VRAM 76 76 * be treated as zero and passed over. */ 77 void vb oxClearVRAM(ScrnInfoPtr pScrn, int32_t cNewX, int32_t cNewY)77 void vbvxClearVRAM(ScrnInfoPtr pScrn, size_t cbOldSize, size_t cbNewSize) 78 78 { 79 79 VBOXPtr pVBox = VBOXGetRec(pScrn); 80 uint64_t cbOldFB, cbNewFB;81 80 82 cbOldFB = pVBox->cbLine * pScrn->virtualX; 83 cbNewFB = vboxLineLength(pScrn, cNewX) * cNewY; 84 if (cbOldFB > (uint64_t)pVBox->cbFBMax) 85 cbOldFB = 0; 86 if (cbNewFB > (uint64_t)pVBox->cbFBMax) 87 cbNewFB = 0; 88 memset(pVBox->base, 0, max(cbOldFB, cbNewFB)); 81 /* Assume 32BPP - this is just a sanity test. */ 82 VBVXASSERT( cbOldSize / 4 <= VBOX_VIDEO_MAX_VIRTUAL * VBOX_VIDEO_MAX_VIRTUAL 83 && cbNewSize / 4 <= VBOX_VIDEO_MAX_VIRTUAL * VBOX_VIDEO_MAX_VIRTUAL, 84 ("cbOldSize=%llu cbNewSize=%llu, max=%u.\n", (unsigned long long)cbOldSize, (unsigned long long)cbNewSize, 85 VBOX_VIDEO_MAX_VIRTUAL * VBOX_VIDEO_MAX_VIRTUAL)); 86 if (cbOldSize > (size_t)pVBox->cbFBMax) 87 cbOldSize = pVBox->cbFBMax; 88 if (cbNewSize > (size_t)pVBox->cbFBMax) 89 cbNewSize = pVBox->cbFBMax; 90 memset(pVBox->base, 0, max(cbOldSize, cbNewSize)); 89 91 } 90 92 91 93 /** Set a graphics mode. Poke any required values into registers, do an HGSMI 92 * mode set and tell the host we support advanced graphics functions. This 93 * procedure is complicated by the fact that X.Org can implicitly disable a 94 * screen by resizing the virtual framebuffer so that the screen is no longer 95 * inside it. We have to spot and handle this. 94 * mode set and tell the host we support advanced graphics functions. 96 95 */ 97 Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,98 unsigned cHeight, int x, int y)96 void vbvxSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth, unsigned cHeight, int x, int y, bool fEnabled, 97 bool fConnected, struct vbvxFrameBuffer *pFrameBuffer) 99 98 { 100 99 VBOXPtr pVBox = VBOXGetRec(pScrn); 101 uint32_t offStart, cwReal = cWidth; 102 bool fEnabled; 100 uint32_t offStart; 103 101 uint16_t fFlags; 104 102 int rc; 103 bool fEnabledAndVisible = fEnabled && x + cWidth <= pFrameBuffer->cWidth && y + cHeight <= pFrameBuffer->cHeight; 104 /* Recent host code has a flag to blank the screen; older code needs BPP set to zero. */ 105 uint32_t cBPP = fEnabledAndVisible || pVBox->fHostHasScreenBlankingFlag ? pFrameBuffer->cBPP : 0; 105 106 106 TRACE_LOG("cDisplay=%u, cWidth=%u, cHeight=%u, x=%d, y=%d, displayWidth=%d\n", 107 cDisplay, cWidth, cHeight, x, y, pScrn->displayWidth); 108 offStart = y * pVBox->cbLine + x * vboxBPP(pScrn) / 8; 109 /* Deactivate the screen if the mode - specifically the virtual width - is 110 * too large for VRAM as we sometimes have to do this - see comments in 111 * VBOXPreInit. */ 112 if ( offStart + pVBox->cbLine * cHeight > pVBox->cbFBMax 113 || pVBox->cbLine * pScrn->virtualY > pVBox->cbFBMax) 114 return FALSE; 115 /* Deactivate the screen if it is outside of the virtual framebuffer and 116 * clamp it to lie inside if it is partly outside. */ 117 if (x >= pScrn->displayWidth || x + (int) cWidth <= 0) 118 return FALSE; 119 else 120 cwReal = RT_MIN((int) cWidth, pScrn->displayWidth - x); 121 TRACE_LOG("pVBox->pScreens[%u].fCrtcEnabled=%d, fOutputEnabled=%d\n", 122 cDisplay, (int)pVBox->pScreens[cDisplay].fCrtcEnabled, 123 (int)pVBox->pScreens[cDisplay].fOutputEnabled); 124 if (cDisplay == 0) 125 VBoxVideoSetModeRegisters(cwReal, cHeight, pScrn->displayWidth, 126 vboxBPP(pScrn), 0, x, y); 127 fEnabled = pVBox->pScreens[cDisplay].fCrtcEnabled 128 && pVBox->pScreens[cDisplay].fOutputEnabled; 107 TRACE_LOG("cDisplay=%u, cWidth=%u, cHeight=%u, x=%d, y=%d, fEnabled=%d, fConnected=%d, pFrameBuffer: { x0=%d, y0=%d, cWidth=%u, cHeight=%u, cBPP=%u }\n", 108 cDisplay, cWidth, cHeight, x, y, fEnabled, fConnected, pFrameBuffer->x0, pFrameBuffer->y0, pFrameBuffer->cWidth, 109 pFrameBuffer->cHeight, pFrameBuffer->cBPP); 110 VBVXASSERT(cWidth != 0 && cHeight != 0, ("cWidth = 0 or cHeight = 0\n")); 111 offStart = (y * pFrameBuffer->cWidth + x) * pFrameBuffer->cBPP / 8; 112 if (cDisplay == 0 && fEnabled) 113 VBoxVideoSetModeRegisters(cWidth, cHeight, pFrameBuffer->cWidth, pFrameBuffer->cBPP, 0, x, y); 129 114 fFlags = VBVA_SCREEN_F_ACTIVE; 130 fFlags |= (pVBox->pScreens[cDisplay].afConnected ? 0 131 : VBVA_SCREEN_F_DISABLED); 132 VBoxHGSMIProcessDisplayInfo(&pVBox->guestCtx, cDisplay, x, y, 133 offStart, pVBox->cbLine, cwReal, cHeight, 134 fEnabled ? vboxBPP(pScrn) : 0, fFlags); 135 if (cDisplay == 0) 136 { 137 rc = VBoxHGSMIUpdateInputMapping(&pVBox->guestCtx, 0 - pVBox->pScreens[0].aScreenLocation.x, 138 0 - pVBox->pScreens[0].aScreenLocation.y, pScrn->virtualX, pScrn->virtualY); 139 if (RT_FAILURE(rc)) 140 FatalError("Failed to update the input mapping.\n"); 141 } 142 return TRUE; 115 fFlags |= (fConnected ? 0 : VBVA_SCREEN_F_DISABLED); 116 fFlags |= (!fEnabledAndVisible && pVBox->fHostHasScreenBlankingFlag ? VBVA_SCREEN_F_BLANK : 0); 117 VBoxHGSMIProcessDisplayInfo(&pVBox->guestCtx, cDisplay, x - pFrameBuffer->x0, y - pFrameBuffer->y0, offStart, 118 pFrameBuffer->cWidth * pFrameBuffer->cBPP / 8, cWidth, cHeight, cBPP, fFlags); 119 rc = VBoxHGSMIUpdateInputMapping(&pVBox->guestCtx, 0 - pFrameBuffer->x0, 0 - pFrameBuffer->y0, pFrameBuffer->cWidth, 120 pFrameBuffer->cHeight); 121 if (RT_FAILURE(rc)) 122 FatalError("Failed to update the input mapping.\n"); 143 123 } 144 124 145 /** Resize the virtual framebuffer. After resizing we reset all modes 146 * (X.Org 1.3+) to adjust them to the new framebuffer. 147 */ 148 Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height) 125 /** Tell the virtual mouse device about the new virtual desktop size. */ 126 void vbvxSetSolarisMouseRange(int width, int height) 149 127 { 150 ScreenPtr pScreen = pScrn->pScreen; 151 PixmapPtr pPixmap = pScreen->GetScreenPixmap(pScreen); 152 VBOXPtr pVBox = VBOXGetRec(pScrn); 153 uint64_t cbLine = vboxLineLength(pScrn, width); 154 int displayWidth = vboxDisplayPitch(pScrn, cbLine); 128 #ifdef RT_OS_SOLARIS 155 129 int rc; 130 int hMouse = open("/dev/mouse", O_RDWR); 156 131 157 TRACE_LOG("width=%d, height=%d\n", width, height); 158 if ( width == pScrn->virtualX 159 && height == pScrn->virtualY 160 && displayWidth == pScrn->displayWidth) 161 return TRUE; 162 if (!pPixmap) { 163 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 164 "Failed to get the screen pixmap.\n"); 165 return FALSE; 166 } 167 if (cbLine > UINT32_MAX || cbLine * height >= pVBox->cbFBMax) 132 if (hMouse >= 0) 168 133 { 169 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 170 "Unable to set up a virtual screen size of %dx%d with %lu of %d Kb of video memory available. Please increase the video memory size.\n", 171 width, height, pVBox->cbFBMax / 1024, pScrn->videoRam); 172 return FALSE; 173 } 174 pScreen->ModifyPixmapHeader(pPixmap, width, height, 175 pScrn->depth, vboxBPP(pScrn), cbLine, 176 pVBox->base); 177 vboxClearVRAM(pScrn, width, height); 178 pScrn->virtualX = width; 179 pScrn->virtualY = height; 180 pScrn->displayWidth = displayWidth; 181 pVBox->cbLine = cbLine; 182 #ifdef VBOX_DRI_OLD 183 if (pVBox->useDRI) 184 VBOXDRIUpdateStride(pScrn, pVBox); 185 #endif 186 #ifdef VBOXVIDEO_13 187 /* Write the new values to the hardware */ 188 /** @todo why is this only for VBOXVIDEO_13? */ 189 { 190 unsigned i; 191 for (i = 0; i < pVBox->cScreens; ++i) 192 VBOXSetMode(pScrn, i, pVBox->pScreens[i].aScreenLocation.cx, 193 pVBox->pScreens[i].aScreenLocation.cy, 194 pVBox->pScreens[i].aScreenLocation.x, 195 pVBox->pScreens[i].aScreenLocation.y); 134 do { 135 Ms_screen_resolution Res = { height, width }; 136 rc = ioctl(hMouse, MSIOSRESOLUTION, &Res); 137 } while ((rc != 0) && (errno == EINTR)); 138 close(hMouse); 196 139 } 197 140 #else 198 rc = VBoxHGSMIUpdateInputMapping(&pVBox->guestCtx, 0 - pVBox->pScreens[0].aScreenLocation.x, 199 0 - pVBox->pScreens[0].aScreenLocation.y, pScrn->virtualX, pScrn->virtualY); 200 if (RT_FAILURE(rc)) 201 FatalError("Failed to update the input mapping.\n"); 141 (void)width; (void)height; 202 142 #endif 203 #ifdef RT_OS_SOLARIS204 /* Tell the virtual mouse device about the new virtual desktop size. */205 {206 int rc;207 int hMouse = open("/dev/mouse", O_RDWR);208 if (hMouse >= 0)209 {210 do {211 Ms_screen_resolution Res = { height, width };212 rc = ioctl(hMouse, MSIOSRESOLUTION, &Res);213 } while ((rc != 0) && (errno == EINTR));214 close(hMouse);215 }216 }217 #endif218 return TRUE;219 143 } -
trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
r54531 r55043 80 80 81 81 #include "fb.h" 82 #include "os.h" 82 83 83 84 #include "vboxvideo.h" 84 85 #include <VBox/VBoxGuest.h> 86 #include <VBox/Hardware/VBoxVideoVBE.h> 85 87 #include "version-generated.h" 86 88 #include "product-generated.h" … … 98 100 /* #define DPMS_SERVER 99 101 #include "extensions/dpms.h" */ 102 103 /* ShadowFB support */ 104 #include "shadowfb.h" 100 105 101 106 /* VGA hardware functions for setting and restoring text mode */ … … 145 150 static void VBOXSaveMode(ScrnInfoPtr pScrn); 146 151 static void VBOXRestoreMode(ScrnInfoPtr pScrn); 152 static void setSizesAndCursorIntegration(ScrnInfoPtr pScrn, bool fLimitedContext); 153 154 #ifndef XF86_SCRN_INTERFACE 155 # define xf86ScreenToScrn(pScreen) xf86Screens[(pScreen)->myNum] 156 # define xf86ScrnToScreen(pScrn) screenInfo.screens[(pScrn)->scrnIndex] 157 #endif 147 158 148 159 static inline void VBOXSetRec(ScrnInfoPtr pScrn) … … 262 273 #endif /* !XORG_7X */ 263 274 275 /** Resize the virtual framebuffer. */ 276 static Bool adjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height) 277 { 278 ScreenPtr pScreen = xf86ScrnToScreen(pScrn); 279 VBOXPtr pVBox = VBOXGetRec(pScrn); 280 int adjustedWidth = pScrn->bitsPerPixel == 16 ? (width + 1) & ~1 : width; 281 int cbLine = adjustedWidth * pScrn->bitsPerPixel / 8; 282 PixmapPtr pPixmap; 283 int rc; 284 285 TRACE_LOG("width=%d, height=%d\n", width, height); 286 VBVXASSERT(width >= 0 && height >= 0, ("Invalid negative width (%d) or height (%d)\n", width, height)); 287 if (pScreen == NULL) /* Not yet initialised. */ 288 return TRUE; 289 pPixmap = pScreen->GetScreenPixmap(pScreen); 290 VBVXASSERT(pPixmap != NULL, ("Failed to get the screen pixmap.\n")); 291 if ( adjustedWidth != pPixmap->drawable.width 292 || height != pPixmap->drawable.height) 293 { 294 if ( adjustedWidth > VBOX_VIDEO_MAX_VIRTUAL || height > VBOX_VIDEO_MAX_VIRTUAL 295 || (unsigned)cbLine * (unsigned)height >= pVBox->cbFBMax) 296 { 297 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 298 "Virtual framebuffer %dx%d too large. For information, video memory: %u Kb.\n", 299 adjustedWidth, height, (unsigned) pVBox->cbFBMax / 1024); 300 return FALSE; 301 } 302 vbvxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel / 8, 303 adjustedWidth * height * pScrn->bitsPerPixel / 8); 304 pScreen->ModifyPixmapHeader(pPixmap, adjustedWidth, height, pScrn->depth, pScrn->bitsPerPixel, cbLine, pVBox->base); 305 } 306 pScrn->displayWidth = pScrn->virtualX = adjustedWidth; 307 pScrn->virtualY = height; 308 #ifdef VBOX_DRI_OLD 309 if (pVBox->useDRI) 310 VBOXDRIUpdateStride(pScrn, pVBox); 311 #endif 312 return TRUE; 313 } 314 315 /** Set a video mode to the hardware, RandR 1.1 version. Since we no longer do 316 * virtual frame buffers, adjust the screen pixmap dimensions to match. */ 317 static void setModeRandR11(ScrnInfoPtr pScrn, DisplayModePtr pMode, bool fLimitedContext) 318 { 319 VBOXPtr pVBox = VBOXGetRec(pScrn); 320 struct vbvxFrameBuffer frameBuffer = { 0, 0, pMode->HDisplay, pMode->VDisplay, pScrn->bitsPerPixel}; 321 322 pVBox->pScreens[0].aScreenLocation.cx = pMode->HDisplay; 323 pVBox->pScreens[0].aScreenLocation.cy = pMode->VDisplay; 324 if (fLimitedContext) 325 { 326 pScrn->displayWidth = pScrn->virtualX = pMode->HDisplay; 327 pScrn->virtualY = pMode->VDisplay; 328 } 329 else 330 adjustScreenPixmap(pScrn, pMode->HDisplay, pMode->VDisplay); 331 if (pMode->HDisplay != 0 && pMode->VDisplay != 0) 332 vbvxSetMode(pScrn, 0, pMode->HDisplay, pMode->VDisplay, 0, 0, true, true, &frameBuffer); 333 pScrn->currentMode = pMode; 334 } 335 264 336 #ifdef VBOXVIDEO_13 265 337 /* X.org 1.3+ mode-setting support ******************************************/ 338 339 /** Set a video mode to the hardware, RandR 1.2 version. If this is the first 340 * screen, re-set the current mode for all others (the offset for the first 341 * screen is always treated as zero by the hardware, so all other screens need 342 * to be changed to compensate for any changes!). The mode to set is taken 343 * from the X.Org Crtc structure. */ 344 static void setModeRandR12(ScrnInfoPtr pScrn, unsigned cScreen) 345 { 346 VBOXPtr pVBox = VBOXGetRec(pScrn); 347 unsigned i; 348 struct vbvxFrameBuffer frameBuffer = { pVBox->pScreens[0].paCrtcs->x, pVBox->pScreens[0].paCrtcs->y, pScrn->virtualX, 349 pScrn->virtualY, pScrn->bitsPerPixel }; 350 unsigned cFirst = cScreen; 351 unsigned cLast = cScreen != 0 ? cScreen + 1 : pVBox->cScreens; 352 353 for (i = cFirst; i < cLast; ++i) 354 if (pVBox->pScreens[i].paCrtcs->mode.HDisplay != 0 && pVBox->pScreens[i].paCrtcs->mode.VDisplay != 0) 355 vbvxSetMode(pScrn, i, pVBox->pScreens[i].paCrtcs->mode.HDisplay, pVBox->pScreens[i].paCrtcs->mode.VDisplay, 356 pVBox->pScreens[i].paCrtcs->x, pVBox->pScreens[i].paCrtcs->y, pVBox->pScreens[i].fPowerOn, 357 pVBox->pScreens[i].paOutputs->status == XF86OutputStatusConnected, &frameBuffer); 358 } 359 360 /** Wrapper around setModeRandR12() to avoid exposing non-obvious semantics. 361 */ 362 static void setAllModesRandR12(ScrnInfoPtr pScrn) 363 { 364 setModeRandR12(pScrn, 0); 365 } 266 366 267 367 /* For descriptions of these functions and structures, see … … 272 372 { 273 373 VBOXPtr pVBox = VBOXGetRec(pScrn); 374 Bool rc; 375 unsigned i; 376 274 377 TRACE_LOG("width=%d, height=%d\n", cw, ch); 275 /* Save the size in case we need to re-set it later. */276 pVBox->FBSize.cx = cw;277 pVBox->FBSize.cy = ch;278 378 /* Don't fiddle with the hardware if we are switched 279 379 * to a virtual terminal. */ … … 283 383 return TRUE; 284 384 } 285 return VBOXAdjustScreenPixmap(pScrn, cw, ch); 385 rc = adjustScreenPixmap(pScrn, cw, ch); 386 /* Power-on all screens (the server expects this) and set the new pitch to them. */ 387 for (i = 0; i < pVBox->cScreens; ++i) 388 pVBox->pScreens[i].fPowerOn = true; 389 setAllModesRandR12(pScrn); 390 vbvxSetSolarisMouseRange(cw, ch); 391 return rc; 286 392 } 287 393 … … 293 399 vbox_crtc_dpms(xf86CrtcPtr crtc, int mode) 294 400 { 295 VBOXPtr pVBox = VBOXGetRec(crtc->scrn); 401 ScrnInfoPtr pScrn = crtc->scrn; 402 VBOXPtr pVBox = VBOXGetRec(pScrn); 296 403 unsigned cDisplay = (uintptr_t)crtc->driver_private; 297 bool fEnabled = (mode != DPMSModeOff); 298 299 TRACE_LOG("cDisplay=%u, mode=%i\n", cDisplay, mode); 300 pVBox->pScreens[cDisplay].fCrtcEnabled = fEnabled; 301 /* Don't fiddle with the hardware if we are switched 302 * to a virtual terminal. */ 303 if (!crtc->scrn->vtSema) { 304 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, 305 "We do not own the active VT, exiting.\n"); 306 return; 307 } 308 if ( pVBox->pScreens[cDisplay].aScreenLocation.cx 309 && pVBox->pScreens[cDisplay].aScreenLocation.cy) 310 VBOXSetMode(crtc->scrn, cDisplay, 311 pVBox->pScreens[cDisplay].aScreenLocation.cx, 312 pVBox->pScreens[cDisplay].aScreenLocation.cy, 313 pVBox->pScreens[cDisplay].aScreenLocation.x, 314 pVBox->pScreens[cDisplay].aScreenLocation.y); 404 405 TRACE_LOG("mode=%d\n", mode); 406 pVBox->pScreens[cDisplay].fPowerOn = (mode != DPMSModeOff); 407 setModeRandR12(pScrn, cDisplay); 315 408 } 316 409 … … 345 438 TRACE_LOG("name=%s, HDisplay=%d, VDisplay=%d, x=%d, y=%d\n", adjusted_mode->name, 346 439 adjusted_mode->HDisplay, adjusted_mode->VDisplay, x, y); 347 pVBox->pScreens[cDisplay].fCrtcEnabled = true; 348 pVBox->pScreens[cDisplay].fOutputEnabled = true; 440 pVBox->pScreens[cDisplay].fPowerOn = true; 349 441 pVBox->pScreens[cDisplay].aScreenLocation.cx = adjusted_mode->HDisplay; 350 442 pVBox->pScreens[cDisplay].aScreenLocation.cy = adjusted_mode->VDisplay; … … 359 451 return; 360 452 } 361 VBOXSetMode(crtc->scrn, cDisplay, adjusted_mode->HDisplay, 362 adjusted_mode->VDisplay, x, y); 453 setModeRandR12(crtc->scrn, cDisplay); 363 454 } 364 455 … … 402 493 vbox_output_dpms (xf86OutputPtr output, int mode) 403 494 { 404 VBOXPtr pVBox = VBOXGetRec(output->scrn); 405 unsigned cDisplay = (uintptr_t)output->driver_private; 406 bool fEnabled = (mode == DPMSModeOn); 407 408 TRACE_LOG("cDisplay=%u, mode=%i\n", cDisplay, mode); 409 pVBox->pScreens[cDisplay].fOutputEnabled = fEnabled; 410 /* Don't fiddle with the hardware if we are switched 411 * to a virtual terminal. */ 412 if (!output->scrn->vtSema) { 413 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 414 "We do not own the active VT, exiting.\n"); 415 return; 416 } 417 if ( pVBox->pScreens[cDisplay].aScreenLocation.cx 418 && pVBox->pScreens[cDisplay].aScreenLocation.cy) 419 VBOXSetMode(output->scrn, cDisplay, 420 pVBox->pScreens[cDisplay].aScreenLocation.cx, 421 pVBox->pScreens[cDisplay].aScreenLocation.cy, 422 pVBox->pScreens[cDisplay].aScreenLocation.x, 423 pVBox->pScreens[cDisplay].aScreenLocation.y); 495 (void)output; (void)mode; 424 496 } 425 497 … … 498 570 uint32_t x, y, iScreen; 499 571 iScreen = (uintptr_t)output->driver_private; 500 VBoxUpdateSizeHints(pScrn); 501 pMode = vbox_output_add_mode(pVBox, &pModes, NULL, pVBox->pScreens[iScreen].aPreferredSize.cx, 502 pVBox->pScreens[iScreen].aPreferredSize.cy, TRUE, FALSE); 503 VBOXEDIDSet(output, pMode); 504 /* Add standard modes supported by the host */ 505 for ( ; ; ) 506 { 507 cIndex = vboxNextStandardMode(pScrn, cIndex, &x, &y); 508 if (cIndex == 0) 509 break; 510 vbox_output_add_mode(pVBox, &pModes, NULL, x, y, FALSE, FALSE); 511 } 512 513 /* Also report any modes the user may have requested in the xorg.conf 514 * configuration file. */ 515 for (i = 0; pScrn->display->modes[i] != NULL; i++) 516 { 517 if (2 == sscanf(pScrn->display->modes[i], "%ux%u", &x, &y)) 518 vbox_output_add_mode(pVBox, &pModes, pScrn->display->modes[i], x, y, FALSE, TRUE); 519 } 572 pMode = vbox_output_add_mode(pVBox, &pModes, NULL, 573 RT_CLAMP(pVBox->pScreens[iScreen].aPreferredSize.cx, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL), 574 RT_CLAMP(pVBox->pScreens[iScreen].aPreferredSize.cy, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL), 575 TRUE, FALSE); 576 // VBOXEDIDSet(output, pMode); 520 577 TRACE_EXIT(); 521 578 return pModes; … … 617 674 618 675 #ifndef XF86_SCRN_INTERFACE 619 # define xf86ScreenToScrn(pScreen) xf86Screens[(pScreen)->myNum]620 # define xf86ScrnToScreen(pScrn) screenInfo.screens[(pScrn)->scrnIndex]621 676 # define SCRNINDEXAPI(pfn) pfn ## Index 622 677 static Bool VBOXScreenInitIndex(int scrnIndex, ScreenPtr pScreen, int argc, … … 880 935 * took the first valid values set to these two as maxima over the 881 936 * server lifetime. */ 882 pScrn->virtualX = 32000;883 pScrn->virtualY = 32000;937 pScrn->virtualX = VBOX_VIDEO_MAX_VIRTUAL; 938 pScrn->virtualY = VBOX_VIDEO_MAX_VIRTUAL; 884 939 #else 885 940 /* We don't validate with xf86ValidateModes and xf86PruneModes as we … … 889 944 890 945 /* Set the right virtual resolution. */ 891 pScrn->virtualX = pScrn-> currentMode->HDisplay;946 pScrn->virtualX = pScrn->bitsPerPixel == 16 ? (pScrn->currentMode->HDisplay + 1) & ~1 : pScrn->currentMode->HDisplay; 892 947 pScrn->virtualY = pScrn->currentMode->VDisplay; 893 948 … … 895 950 896 951 /* Needed before we initialise DRI. */ 897 pVBox->cbLine = vboxLineLength(pScrn, pScrn->virtualX); 898 pScrn->displayWidth = vboxDisplayPitch(pScrn, pVBox->cbLine); 952 pScrn->displayWidth = pScrn->virtualX; 899 953 900 954 xf86PrintModes(pScrn); … … 985 1039 if (property_name == BAD_RESOURCE) 986 1040 FatalError("Failed to retrieve \"HAS_VT\" atom\n"); 1041 if (ROOT_WINDOW(pScrn) == NULL) 1042 return; 987 1043 ChangeWindowProperty(ROOT_WINDOW(pScrn), property_name, XA_INTEGER, 32, 988 1044 PropModeReplace, 1, &value, TRUE); 989 1045 } 990 1046 #endif /* SET_HAVE_VT_PROPERTY */ 1047 1048 #ifdef VBOXVIDEO_13 1049 1050 static void setVirtualSizeRandR12(ScrnInfoPtr pScrn, bool fLimitedContext) 1051 { 1052 VBOXPtr pVBox = VBOXGetRec(pScrn); 1053 unsigned i; 1054 unsigned cx = 0; 1055 unsigned cy = 0; 1056 1057 for (i = 0; i < pVBox->cScreens; ++i) 1058 { 1059 if ( pVBox->fHaveHGSMIModeHints && pVBox->pScreens[i].afHaveLocation) 1060 { 1061 pVBox->pScreens[i].paCrtcs->x = pVBox->pScreens[i].aPreferredLocation.x; 1062 pVBox->pScreens[i].paCrtcs->y = pVBox->pScreens[i].aPreferredLocation.y; 1063 } 1064 if ( pVBox->pScreens[i].paOutputs->status == XF86OutputStatusConnected 1065 && pVBox->pScreens[i].paCrtcs->x + pVBox->pScreens[i].aPreferredSize.cx < VBOX_VIDEO_MAX_VIRTUAL 1066 && pVBox->pScreens[i].paCrtcs->y + pVBox->pScreens[i].aPreferredSize.cy < VBOX_VIDEO_MAX_VIRTUAL) 1067 { 1068 cx = max(cx, pVBox->pScreens[i].paCrtcs->x + pVBox->pScreens[i].aPreferredSize.cx); 1069 cy = max(cy, pVBox->pScreens[i].paCrtcs->y + pVBox->pScreens[i].aPreferredSize.cy); 1070 } 1071 } 1072 if (cx != 0 && cy != 0) 1073 { 1074 if (fLimitedContext) 1075 { 1076 pScrn->virtualX = cx; 1077 pScrn->virtualY = cy; 1078 } 1079 else 1080 { 1081 TRACE_LOG("cx=%u, cy=%u\n", cx, cy); 1082 xf86ScrnToScreen(pScrn)->width = cx; 1083 xf86ScrnToScreen(pScrn)->height = cy; 1084 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 14 1085 xf86UpdateDesktopDimensions(); 1086 #elif GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 12 1087 screenInfo.width = cx; 1088 screenInfo.height = cy; 1089 #endif 1090 adjustScreenPixmap(pScrn, cx, cy); 1091 } 1092 } 1093 } 1094 1095 static void setScreenSizesRandR12(ScrnInfoPtr pScrn, bool fLimitedContext) 1096 { 1097 VBOXPtr pVBox = VBOXGetRec(pScrn); 1098 unsigned i; 1099 1100 for (i = 0; i < pVBox->cScreens; ++i) 1101 { 1102 if (!pVBox->pScreens[i].afConnected) 1103 continue; 1104 /* The Crtc can get "unset" if the screen was disconnected previously. 1105 * I couldn't find an API to re-set it which did not have side-effects. 1106 */ 1107 pVBox->pScreens[i].paOutputs->crtc = pVBox->pScreens[i].paCrtcs; 1108 xf86CrtcSetMode(pVBox->pScreens[i].paCrtcs, pVBox->pScreens[i].paOutputs->probed_modes, RR_Rotate_0, 1109 pVBox->pScreens[i].paCrtcs->x, pVBox->pScreens[i].paCrtcs->y); 1110 if (!fLimitedContext) 1111 RRCrtcNotify(pVBox->pScreens[i].paCrtcs->randr_crtc, pVBox->pScreens[i].paOutputs->randr_output->modes[0], 1112 pVBox->pScreens[i].paCrtcs->x, pVBox->pScreens[i].paCrtcs->y, RR_Rotate_0, 1113 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5 1114 NULL, 1115 #endif 1116 1, &pVBox->pScreens[i].paOutputs->randr_output); 1117 } 1118 } 1119 1120 static void setSizesRandR12(ScrnInfoPtr pScrn, bool fLimitedContext) 1121 { 1122 VBOXPtr pVBox = VBOXGetRec(pScrn); 1123 1124 # if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5 1125 RRGetInfo(xf86ScrnToScreen(pScrn), TRUE); 1126 # else 1127 RRGetInfo(xf86ScrnToScreen(pScrn)); 1128 # endif 1129 setVirtualSizeRandR12(pScrn, fLimitedContext); 1130 setScreenSizesRandR12(pScrn, fLimitedContext); 1131 if (!fLimitedContext) 1132 { 1133 RRScreenSizeNotify(xf86ScrnToScreen(pScrn)); 1134 RRTellChanged(xf86ScrnToScreen(pScrn)); 1135 } 1136 } 1137 1138 #else 1139 1140 static void setSizesRandR11(ScrnInfoPtr pScrn, bool fLimitedContext) 1141 { 1142 VBOXPtr pVBox = VBOXGetRec(pScrn); 1143 DisplayModePtr pNewMode; 1144 1145 pNewMode = pScrn->modes != pScrn->currentMode ? pScrn->modes : pScrn->modes->next; 1146 pNewMode->HDisplay = RT_CLAMP(pVBox->pScreens[0].aPreferredSize.cx, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL); 1147 pNewMode->VDisplay = RT_CLAMP(pVBox->pScreens[0].aPreferredSize.cy, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL); 1148 setModeRandR11(pScrn, pScrn->currentMode, fLimitedContext); 1149 } 1150 1151 #endif 1152 1153 static void setSizesAndCursorIntegration(ScrnInfoPtr pScrn, bool fLimitedContext) 1154 { 1155 VBOXPtr pVBox = VBOXGetRec(pScrn); 1156 1157 TRACE_LOG("fLimitedContext=%d\n", fLimitedContext); 1158 #ifdef VBOXVIDEO_13 1159 setSizesRandR12(pScrn, fLimitedContext); 1160 #else 1161 setSizesRandR11(pScrn, fLimitedContext); 1162 #endif 1163 if (!fLimitedContext) 1164 vbvxReprobeCursor(pScrn); 1165 } 1166 1167 /* We update the size hints from the X11 property set by VBoxClient every time 1168 * that the X server goes to sleep (to catch the property change request). 1169 * Although this is far more often than necessary it should not have real-life 1170 * performance consequences and allows us to simplify the code quite a bit. */ 1171 static void updateSizeHintsBlockHandler(pointer pData, OSTimePtr pTimeout, pointer pReadmask) 1172 { 1173 ScrnInfoPtr pScrn = (ScrnInfoPtr)pData; 1174 VBOXPtr pVBox = VBOXGetRec(pScrn); 1175 bool fNeedUpdate = false; 1176 1177 (void)pTimeout; 1178 (void)pReadmask; 1179 if (!pScrn->vtSema) 1180 return; 1181 vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, &fNeedUpdate); 1182 if (ROOT_WINDOW(pScrn) != NULL) 1183 vbvxReadSizesAndCursorIntegrationFromProperties(pScrn, &fNeedUpdate); 1184 if (fNeedUpdate) 1185 setSizesAndCursorIntegration(pScrn, false); 1186 } 991 1187 992 1188 /* … … 1063 1259 1064 1260 #if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX) 1065 VBoxSetUpLinuxACPI(pScreen); 1066 #endif 1067 1068 vbox_open (pScrn, pScreen, pVBox); 1261 vbvxSetUpLinuxACPI(pScreen); 1262 #endif 1263 1264 if (!VBoxHGSMIIsSupported()) 1265 { 1266 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Graphics device too old to support.\n"); 1267 return FALSE; 1268 } 1269 vbvxSetUpHGSMIHeapInGuest(pVBox, pScrn->videoRam * 1024); 1270 pVBox->cScreens = VBoxHGSMIGetMonitorCount(&pVBox->guestCtx); 1271 pVBox->pScreens = xnfcalloc(pVBox->cScreens, sizeof(*pVBox->pScreens)); 1272 pVBox->paVBVAModeHints = xnfcalloc(pVBox->cScreens, sizeof(*pVBox->paVBVAModeHints)); 1273 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested monitor count: %u\n", pVBox->cScreens); 1069 1274 vboxEnableVbva(pScrn); 1275 /* Set up the dirty rectangle handler. It will be added into a function 1276 * chain and gets removed when the screen is cleaned up. */ 1277 if (ShadowFBInit2(pScreen, NULL, vbvxHandleDirtyRect) != TRUE) 1278 return FALSE; 1070 1279 VBoxInitialiseSizeHints(pScrn); 1280 /* Get any screen size hints from HGSMI. Do not yet try to access X11 1281 * properties, as they are not yet set up, and nor are the clients that 1282 * might have set them. */ 1283 vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, NULL); 1071 1284 1072 1285 #ifdef VBOXVIDEO_13 … … 1104 1317 /* Set a sane minimum and maximum mode size to match what the hardware 1105 1318 * supports. */ 1106 xf86CrtcSetSizeRange(pScrn, 64, 64, 16384, 16384);1319 xf86CrtcSetSizeRange(pScrn, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL, VBOX_VIDEO_MAX_VIRTUAL); 1107 1320 1108 1321 /* Now create our initial CRTC/output configuration. */ … … 1112 1325 } 1113 1326 1114 /* Initialise randr 1.2 mode-setting functions and set first mode. 1115 * Note that the mode won't be usable until the server has resized the 1116 * framebuffer to something reasonable. */ 1327 /* Initialise randr 1.2 mode-setting functions. */ 1117 1328 if (!xf86CrtcScreenInit(pScreen)) { 1118 1329 return FALSE; 1119 1330 } 1120 1331 1121 if (!xf86SetDesiredModes(pScrn)) { 1122 return FALSE; 1123 } 1124 #else /* !VBOXVIDEO_13 */ 1125 VBoxSetUpRandR11(pScreen); 1332 #endif 1126 1333 /* set first video mode */ 1127 if (!VBOXSetMode(pScrn, 0, pScrn->currentMode->HDisplay, 1128 pScrn->currentMode->VDisplay, pScrn->frameX0, 1129 pScrn->frameY0)) 1130 return FALSE; 1131 /* Save the size in case we need to re-set it later. */ 1132 pVBox->FBSize.cx = pScrn->currentMode->HDisplay; 1133 pVBox->FBSize.cy = pScrn->currentMode->VDisplay; 1134 pVBox->pScreens[0].aScreenLocation.cx = pScrn->currentMode->HDisplay; 1135 pVBox->pScreens[0].aScreenLocation.cy = pScrn->currentMode->VDisplay; 1136 pVBox->pScreens[0].aScreenLocation.x = pScrn->frameX0; 1137 pVBox->pScreens[0].aScreenLocation.y = pScrn->frameY0; 1138 #endif /* !VBOXVIDEO_13 */ 1334 setSizesAndCursorIntegration(pScrn, true); 1335 1336 /* Register block and wake-up handlers for getting new screen size hints. */ 1337 RegisterBlockAndWakeupHandlers(updateSizeHintsBlockHandler, (WakeupHandlerProcPtr)NoopDDA, (pointer)pScrn); 1139 1338 1140 1339 /* software cursor */ … … 1187 1386 1188 1387 TRACE_ENTRY(); 1189 vboxClearVRAM(pScrn, 0, 0);1190 1388 #ifdef VBOX_DRI_OLD 1191 1389 if (pVBox->useDRI) … … 1198 1396 } 1199 1397 #endif 1398 vbvxSetUpHGSMIHeapInGuest(pVBox, pScrn->videoRam * 1024); 1200 1399 vboxEnableVbva(pScrn); 1201 /* Re-assert this in case we had a change request while switched out. */ 1202 if (pVBox->FBSize.cx && pVBox->FBSize.cy) 1203 VBOXAdjustScreenPixmap(pScrn, pVBox->FBSize.cx, pVBox->FBSize.cy); 1204 #ifdef VBOXVIDEO_13 1205 if (!xf86SetDesiredModes(pScrn)) 1206 return FALSE; 1207 #else 1208 if (!VBOXSetMode(pScrn, 0, pScrn->currentMode->HDisplay, 1209 pScrn->currentMode->VDisplay, pScrn->frameX0, 1210 pScrn->frameY0)) 1211 return FALSE; 1212 #endif 1400 /* Re-set video mode */ 1401 vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, NULL); 1402 vbvxReadSizesAndCursorIntegrationFromProperties(pScrn, NULL); 1403 setSizesAndCursorIntegration(pScrn, true); 1213 1404 #ifdef SET_HAVE_VT_PROPERTY 1214 1405 updateHasVTProperty(pScrn, TRUE); … … 1227 1418 #ifdef VBOXVIDEO_13 1228 1419 for (i = 0; i < pVBox->cScreens; ++i) 1229 vbox_ output_dpms(pVBox->pScreens[i].paOutputs, DPMSModeOff);1420 vbox_crtc_dpms(pVBox->pScreens[i].paCrtcs, DPMSModeOff); 1230 1421 #endif 1231 1422 vboxDisableVbva(pScrn); 1232 vb oxClearVRAM(pScrn, 0, 0);1423 vbvxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel / 8, 0); 1233 1424 #ifdef VBOX_DRI_OLD 1234 1425 if (pVBox->useDRI) … … 1258 1449 1259 1450 for (i = 0; i < pVBox->cScreens; ++i) 1260 vbox_ output_dpms(pVBox->pScreens[i].paOutputs, DPMSModeOff);1451 vbox_crtc_dpms(pVBox->pScreens[i].paCrtcs, DPMSModeOff); 1261 1452 #endif 1262 1453 vboxDisableVbva(pScrn); 1263 vb oxClearVRAM(pScrn, 0, 0);1454 vbvxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel / 8, 0); 1264 1455 } 1265 1456 #ifdef VBOX_DRI … … 1288 1479 pScreen->CloseScreen = pVBox->CloseScreen; 1289 1480 #if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX) 1290 VBoxCleanUpLinuxACPI(pScreen);1481 vbvxCleanUpLinuxACPI(pScreen); 1291 1482 #endif 1292 1483 #ifndef XF86_SCRN_INTERFACE … … 1300 1491 { 1301 1492 VBOXPtr pVBox; 1302 Bool rc ;1493 Bool rc = TRUE; 1303 1494 1304 1495 TRACE_LOG("HDisplay=%d, VDisplay=%d\n", pMode->HDisplay, pMode->VDisplay); 1305 #ifndef VBOXVIDEO_131306 pVBox = VBOXGetRec(pScrn);1307 /* Save the size in case we need to re-set it later. */1308 pVBox->FBSize.cx = pMode->HDisplay;1309 pVBox->FBSize.cy = pMode->VDisplay;1310 pVBox->pScreens[0].aScreenLocation.cx = pMode->HDisplay;1311 pVBox->pScreens[0].aScreenLocation.cy = pMode->VDisplay;1312 pVBox->pScreens[0].aScreenLocation.x = pScrn->frameX0;1313 pVBox->pScreens[0].aScreenLocation.y = pScrn->frameY0;1314 #endif1315 1496 if (!pScrn->vtSema) 1316 1497 { … … 1322 1503 rc = xf86SetSingleMode(pScrn, pMode, RR_Rotate_0); 1323 1504 #else 1324 VBOXAdjustScreenPixmap(pScrn, pMode->HDisplay, pMode->VDisplay); 1325 rc = VBOXSetMode(pScrn, 0, pMode->HDisplay, pMode->VDisplay, 1326 pScrn->frameX0, pScrn->frameY0); 1505 setModeRandR11(pScrn, pMode, false); 1327 1506 #endif 1328 1507 TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE"); … … 1331 1510 1332 1511 static void VBOXAdjustFrame(ScrnInfoPtr pScrn, int x, int y) 1333 { 1334 VBOXPtr pVBox = VBOXGetRec(pScrn); 1335 1336 TRACE_ENTRY(); 1337 pVBox->pScreens[0].aScreenLocation.x = x; 1338 pVBox->pScreens[0].aScreenLocation.y = y; 1339 /* Don't fiddle with the hardware if we are switched 1340 * to a virtual terminal. */ 1341 if (!pScrn->vtSema) 1342 { 1343 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1344 "We do not own the active VT, exiting.\n"); 1345 return; 1346 } 1347 VBOXSetMode(pScrn, 0, pVBox->pScreens[0].aScreenLocation.cx, 1348 pVBox->pScreens[0].aScreenLocation.cy, x, y); 1349 TRACE_EXIT(); 1350 } 1512 { (void)pScrn; (void)x; (void)y; } 1351 1513 1352 1514 static void VBOXFreeScreen(ScrnInfoPtr pScrn) -
trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
r54531 r55043 55 55 #include <VBox/VBoxVideoGuest.h> 56 56 #include <VBox/VBoxVideo.h> 57 58 #ifndef VBVA_SCREEN_F_BLANK 59 # define VBVA_SCREEN_F_BLANK 0x0004 60 #endif 57 61 58 62 #ifdef DEBUG … … 130 134 #define VBOX_MAX_DRAWABLES 256 /* At random. */ 131 135 136 #define VBOX_VIDEO_MIN_SIZE 64 137 #define VBOX_VIDEO_MAX_VIRTUAL (INT16_MAX - 1) 138 132 139 #define VBOXPTR(p) ((VBOXPtr)((p)->driverPrivate)) 133 140 … … 148 155 RTRECT2 aScreenLocation; 149 156 /** Is this CRTC enabled or in DPMS off state? */ 150 Bool fCrtcEnabled; 151 /** Is this output enabled or in DPMS low power state? */ 152 Bool fOutputEnabled; 157 Bool fPowerOn; 153 158 #ifdef VBOXVIDEO_13 154 159 /** The virtual crtcs. */ … … 163 168 /** The current preferred resolution for the screen */ 164 169 RTRECTSIZE aPreferredSize; 170 /** The current preferred location for the screen. */ 171 RTPOINT aPreferredLocation; 165 172 /** Has this screen been enabled by the host? */ 166 173 Bool afConnected; 167 /** The last mode hint data read from the X11 property.*/168 int32_t lastModeHintFromProperty;174 /** Does this screen have a preferred location? */ 175 Bool afHaveLocation; 169 176 }; 170 177 … … 183 190 /** The size of the framebuffer and the VBVA buffers at the end of it. */ 184 191 unsigned long cbView; 185 /** The current line size in bytes */186 uint32_t cbLine;187 192 /** Whether the pre-X-server mode was a VBE mode */ 188 193 bool fSavedVBEMode; … … 198 203 /** Do we currently want to use the host cursor? */ 199 204 Bool fUseHardwareCursor; 200 /** The last cursor capabilities data read from the X11 property. */201 int32_t fLastCursorCapabilitiesFromProperty;202 205 /** Number of screens attached */ 203 206 uint32_t cScreens; 204 207 /** Information about each virtual screen. */ 205 208 struct VBoxScreen *pScreens; 206 /** The last requested framebuffer size. */ 207 RTRECTSIZE FBSize; 208 #ifdef VBOXVIDEO_13 209 /** Can we get mode hint and cursor integration information from HGSMI? */ 210 bool fHaveHGSMIModeHints; 211 /** Does the host support the screen blanking flag? */ 212 bool fHostHasScreenBlankingFlag; 209 213 /** Array of structures for receiving mode hints. */ 210 214 VBVAMODEHINT *paVBVAModeHints; 215 #ifdef VBOXVIDEO_13 211 216 # ifdef RT_OS_LINUX 212 217 /** Input device file descriptor for getting ACPI hot-plug events. */ … … 215 220 void *hACPIEventHandler; 216 221 # endif 217 /** Have we read all available HGSMI mode hint data? */218 bool fHaveReadHGSMIModeHintData;219 #else220 /** The original CreateScreenResources procedure which we wrap with our own.221 */222 CreateScreenResourcesProcPtr pfnCreateScreenResources;223 222 #endif 224 223 /** HGSMI guest heap context */ … … 244 243 #define VBOXGetRec vbvxGetRec /* Temporary */ 245 244 extern int vbvxGetIntegerPropery(ScrnInfoPtr pScrn, char *pszName, size_t *pcData, int32_t **ppaData); 245 extern void vbvxSetIntegerPropery(ScrnInfoPtr pScrn, char *pszName, size_t cData, int32_t *paData, Bool fSendEvent); 246 246 extern void vbvxReprobeCursor(ScrnInfoPtr pScrn); 247 247 248 248 /* setmode.c */ 249 250 /** Structure describing the virtual frame buffer. It starts at the beginning 251 * of the video RAM. */ 252 struct vbvxFrameBuffer { 253 /** X offset of first screen in frame buffer. */ 254 int x0; 255 /** Y offset of first screen in frame buffer. */ 256 int y0; 257 /** Frame buffer virtual width. */ 258 unsigned cWidth; 259 /** Frame buffer virtual height. */ 260 unsigned cHeight; 261 /** Bits per pixel. */ 262 unsigned cBPP; 263 }; 264 265 extern void vbvxClearVRAM(ScrnInfoPtr pScrn, size_t cbOldSize, size_t cbNewSize); 266 extern void vbvxSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth, unsigned cHeight, int x, int y, bool fEnabled, 267 bool fConnected, struct vbvxFrameBuffer *pFrameBuffer); 268 extern void vbvxSetSolarisMouseRange(int width, int height); 269 270 /* pointer.c */ 249 271 extern Bool vbox_cursor_init (ScreenPtr pScreen); 250 extern void vbox_open (ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox);251 272 extern void vbox_close (ScrnInfoPtr pScrn, VBOXPtr pVBox); 252 273 274 /* vbva.c */ 275 extern void vbvxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects); 276 extern void vbvxSetUpHGSMIHeapInGuest(VBOXPtr pVBox, uint32_t cbVRAM); 253 277 extern Bool vboxEnableVbva(ScrnInfoPtr pScrn); 254 278 extern void vboxDisableVbva(ScrnInfoPtr pScrn); 255 279 256 280 /* getmode.c */ 257 extern unsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex,258 uint32_t *pcx, uint32_t *pcy);259 281 extern void vboxAddModes(ScrnInfoPtr pScrn); 260 282 extern void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn); 261 extern void VBoxUpdateSizeHints(ScrnInfoPtr pScrn); 262 #ifndef VBOXVIDEO_13 263 extern void VBoxSetUpRandR11(ScreenPtr pScreen); 264 #else 265 void VBoxSetUpLinuxACPI(ScreenPtr pScreen); 266 void VBoxCleanUpLinuxACPI(ScreenPtr pScreen); 267 #endif 283 extern void vbvxReadSizesAndCursorIntegrationFromProperties(ScrnInfoPtr pScrn, bool *pfNeedUpdate); 284 extern void vbvxReadSizesAndCursorIntegrationFromHGSMI(ScrnInfoPtr pScrn, bool *pfNeedUpdate); 285 extern void vbvxSetUpLinuxACPI(ScreenPtr pScreen); 286 extern void vbvxCleanUpLinuxACPI(ScreenPtr pScreen); 268 287 269 288 /* DRI stuff */ … … 279 298 #endif 280 299 281 /* Utilities */282 283 /** Calculate the BPP from the screen depth */284 static inline uint16_t vboxBPP(ScrnInfoPtr pScrn)285 {286 return pScrn->depth == 24 ? 32 : 16;287 }288 289 /** Calculate the scan line length for a display width */290 static inline int32_t vboxLineLength(ScrnInfoPtr pScrn, int32_t cDisplayWidth)291 {292 uint32_t cbLine = (cDisplayWidth * vboxBPP(pScrn) / 8 + 3) & ~3;293 return cbLine < INT32_MAX ? cbLine : INT32_MAX;294 }295 296 /** Calculate the display pitch from the scan line length */297 static inline int32_t vboxDisplayPitch(ScrnInfoPtr pScrn, int32_t cbLine)298 {299 return cbLine * 8 / vboxBPP(pScrn);300 }301 302 extern void vboxClearVRAM(ScrnInfoPtr pScrn, int32_t cNewX, int32_t cNewY);303 extern Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,304 unsigned cHeight, int x, int y);305 extern Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height);306 307 300 #endif /* _VBOXVIDEO_H_ */ 308 301 -
trunk/src/VBox/Additions/x11/vboxvideo/vbva.c
r54531 r55043 18 18 #include <VBox/VBoxGuestLib.h> 19 19 20 #ifndef PCIACCESS21 # include <xf86Pci.h>22 # include <Pci.h>23 #endif24 25 #include "xf86.h"26 #define NEED_XF86_TYPES27 20 #include <iprt/string.h> 28 21 #include "compiler.h" 29 30 /* ShadowFB support */31 #include "shadowfb.h"32 22 33 23 #include "vboxvideo.h" … … 51 41 * rectangles 52 42 */ 53 static void 54 vboxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects) 43 void vbvxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects) 55 44 { 56 45 VBVACMDHDR cmdHdr; … … 79 68 || aRects[i].y2 < pVBox->pScreens[j].aScreenLocation.y) 80 69 continue; 81 cmdHdr.x = (int16_t)aRects[i].x1 ;82 cmdHdr.y = (int16_t)aRects[i].y1 ;70 cmdHdr.x = (int16_t)aRects[i].x1 - pVBox->pScreens[0].aScreenLocation.x; 71 cmdHdr.y = (int16_t)aRects[i].y1 - pVBox->pScreens[0].aScreenLocation.y; 83 72 cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1); 84 73 cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1); … … 100 89 } 101 90 91 static DECLCALLBACK(void *) hgsmiEnvAlloc(void *pvEnv, HGSMISIZE cb) 92 { 93 NOREF(pvEnv); 94 return calloc(1, cb); 95 } 96 97 static DECLCALLBACK(void) hgsmiEnvFree(void *pvEnv, void *pv) 98 { 99 NOREF(pvEnv); 100 free(pv); 101 } 102 103 static HGSMIENV g_hgsmiEnv = 104 { 105 NULL, 106 hgsmiEnvAlloc, 107 hgsmiEnvFree 108 }; 109 110 /** 111 * Calculate the location in video RAM of and initialise the heap for guest to 112 * host messages. In the VirtualBox 4.3 and earlier Guest Additions this 113 * function creates the heap structures directly in guest video RAM, so it 114 * needs to be called whenever video RAM is (re-)set-up. 115 */ 116 void vbvxSetUpHGSMIHeapInGuest(VBOXPtr pVBox, uint32_t cbVRAM) 117 { 118 int rc; 119 uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory; 120 void *pvGuestHeapMemory; 121 122 VBoxHGSMIGetBaseMappingInfo(cbVRAM, &offVRAMBaseMapping, NULL, &offGuestHeapMemory, &cbGuestHeapMemory, NULL); 123 pvGuestHeapMemory = ((uint8_t *)pVBox->base) + offVRAMBaseMapping + offGuestHeapMemory; 124 rc = VBoxHGSMISetupGuestContext(&pVBox->guestCtx, pvGuestHeapMemory, cbGuestHeapMemory, 125 offVRAMBaseMapping + offGuestHeapMemory, &g_hgsmiEnv); 126 VBVXASSERT(RT_SUCCESS(rc), ("Failed to set up the guest-to-host message buffer heap, rc=%d\n", rc)); 127 pVBox->cbView = offVRAMBaseMapping; 128 } 129 102 130 /** Callback to fill in the view structures */ 103 131 static int … … 121 149 * @returns TRUE on success, FALSE on failure 122 150 */ 123 static Bool 124 vboxInitVbva(int scrnIndex, ScreenPtr pScreen, VBOXPtr pVBox) 125 { 126 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 151 static Bool vboxSetupVRAMVbva(VBOXPtr pVBox) 152 { 127 153 int rc = VINF_SUCCESS; 128 129 /* Why is this here? In case things break before we have found the real 130 * count? */ 131 pVBox->cScreens = 1; 132 if (!VBoxHGSMIIsSupported()) 133 { 134 xf86DrvMsg(scrnIndex, X_ERROR, "The graphics device does not seem to support HGSMI. Disableing video acceleration.\n"); 135 return FALSE; 136 } 137 138 /* Set up the dirty rectangle handler. It will be added into a function 139 * chain and gets removed when the screen is cleaned up. */ 140 if (ShadowFBInit2(pScreen, NULL, vboxHandleDirtyRect) != TRUE) 141 { 142 xf86DrvMsg(scrnIndex, X_ERROR, 143 "Unable to install dirty rectangle handler for VirtualBox graphics acceleration.\n"); 144 return FALSE; 145 } 146 return TRUE; 147 } 148 149 static DECLCALLBACK(void *) hgsmiEnvAlloc(void *pvEnv, HGSMISIZE cb) 150 { 151 NOREF(pvEnv); 152 return calloc(1, cb); 153 } 154 155 static DECLCALLBACK(void) hgsmiEnvFree(void *pvEnv, void *pv) 156 { 157 NOREF(pvEnv); 158 free(pv); 159 } 160 161 static HGSMIENV g_hgsmiEnv = 162 { 163 NULL, 164 hgsmiEnvAlloc, 165 hgsmiEnvFree 166 }; 167 168 /** 169 * Initialise VirtualBox's accelerated video extensions. 170 * 171 * @returns TRUE on success, FALSE on failure 172 */ 173 static Bool 174 vboxSetupVRAMVbva(ScrnInfoPtr pScrn, VBOXPtr pVBox) 175 { 176 int rc = VINF_SUCCESS; 177 unsigned i; 178 uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory; 179 void *pvGuestHeapMemory; 180 181 VBoxHGSMIGetBaseMappingInfo(pScrn->videoRam * 1024, &offVRAMBaseMapping, 182 NULL, &offGuestHeapMemory, &cbGuestHeapMemory, 183 NULL); 184 pvGuestHeapMemory = ((uint8_t *)pVBox->base) + offVRAMBaseMapping 185 + offGuestHeapMemory; 186 TRACE_LOG("video RAM: %u KB, guest heap offset: 0x%x, cbGuestHeapMemory: %u\n", 187 pScrn->videoRam, offVRAMBaseMapping + offGuestHeapMemory, 188 cbGuestHeapMemory); 189 rc = VBoxHGSMISetupGuestContext(&pVBox->guestCtx, pvGuestHeapMemory, 190 cbGuestHeapMemory, 191 offVRAMBaseMapping + offGuestHeapMemory, 192 &g_hgsmiEnv); 193 if (RT_FAILURE(rc)) 194 { 195 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up the guest-to-host communication context, rc=%d\n", rc); 196 return FALSE; 197 } 198 pVBox->cbView = pVBox->cbFBMax = offVRAMBaseMapping; 199 pVBox->cScreens = VBoxHGSMIGetMonitorCount(&pVBox->guestCtx); 200 pVBox->pScreens = calloc(pVBox->cScreens, sizeof(*pVBox->pScreens)); 201 if (pVBox->pScreens == NULL) 202 FatalError("Failed to allocate memory for screens array.\n"); 203 #ifdef VBOXVIDEO_13 204 pVBox->paVBVAModeHints = calloc(pVBox->cScreens, 205 sizeof(*pVBox->paVBVAModeHints)); 206 if (pVBox->paVBVAModeHints == NULL) 207 FatalError("Failed to allocate memory for mode hints array.\n"); 208 #endif 209 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested monitor count: %u\n", 210 pVBox->cScreens); 154 unsigned i; 155 156 pVBox->cbFBMax = pVBox->cbView; 211 157 for (i = 0; i < pVBox->cScreens; ++i) 212 158 { … … 224 170 rc = VBoxHGSMISendViewInfo(&pVBox->guestCtx, pVBox->cScreens, 225 171 vboxFillViewInfo, (void *)pVBox); 226 if (RT_FAILURE(rc)) 227 { 228 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to send the view information to the host, rc=%d\n", rc); 229 return FALSE; 230 } 172 VBVXASSERT(RT_SUCCESS(rc), ("Failed to send the view information to the host, rc=%d\n", rc)); 231 173 return TRUE; 232 174 } 233 175 234 void 235 vbox_open(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox) 236 { 237 TRACE_ENTRY(); 238 239 if (!vboxInitVbva(pScrn->scrnIndex, pScreen, pVBox)) 240 FatalError("failed to initialise vboxvideo graphics acceleration.\n"); 176 static bool haveHGSMIModeHintAndCursorReportingInterface(VBOXPtr pVBox) 177 { 178 uint32_t fModeHintReporting, fCursorReporting; 179 180 return RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_MODE_HINT_REPORTING, &fModeHintReporting)) 181 && RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING, &fCursorReporting)) 182 && fModeHintReporting == VINF_SUCCESS 183 && fCursorReporting == VINF_SUCCESS; 184 } 185 186 static bool hostHasScreenBlankingFlag(VBOXPtr pVBox) 187 { 188 uint32_t fScreenFlags; 189 190 return RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_SCREEN_FLAGS, &fScreenFlags)) 191 && fScreenFlags & VBVA_SCREEN_F_BLANK; 241 192 } 242 193 … … 252 203 { 253 204 bool rc = TRUE; 254 int scrnIndex = pScrn->scrnIndex;255 205 unsigned i; 256 206 VBOXPtr pVBox = pScrn->driverPrivate; 257 207 258 208 TRACE_ENTRY(); 259 if (!vboxSetupVRAMVbva(p Scrn, pVBox))209 if (!vboxSetupVRAMVbva(pVBox)) 260 210 return FALSE; 261 211 for (i = 0; i < pVBox->cScreens; ++i) … … 269 219 rc = FALSE; 270 220 } 271 if (!rc) 272 { 273 /* Request not accepted - disable for old hosts. */ 274 xf86DrvMsg(scrnIndex, X_ERROR, 275 "Failed to enable screen update reporting for at least one virtual monitor.\n"); 276 vboxDisableVbva(pScrn); 277 } 221 VBVXASSERT(rc, ("Failed to enable screen update reporting for at least one virtual monitor.\n")); 278 222 #ifdef VBOXVIDEO_13 279 # ifdef RT_OS_LINUX 280 if (rc && pVBox->hACPIEventHandler != NULL) 281 /* We ignore the return value as the fall-back should be active 282 * anyway. */ 283 VBoxHGSMISendCapsInfo(&pVBox->guestCtx, VBVACAPS_VIDEO_MODE_HINTS | VBVACAPS_DISABLE_CURSOR_INTEGRATION); 284 # endif 223 VBoxHGSMISendCapsInfo(&pVBox->guestCtx, VBVACAPS_VIDEO_MODE_HINTS | VBVACAPS_DISABLE_CURSOR_INTEGRATION); 224 pVBox->fHaveHGSMIModeHints = haveHGSMIModeHintAndCursorReportingInterface(pVBox); 225 pVBox->fHostHasScreenBlankingFlag = hostHasScreenBlankingFlag(pVBox); 285 226 #endif 286 227 return rc; … … 299 240 { 300 241 int rc; 301 int scrnIndex = pScrn->scrnIndex;302 242 unsigned i; 303 243 VBOXPtr pVBox = pScrn->driverPrivate;
Note:
See TracChangeset
for help on using the changeset viewer.