Changeset 55191 in vbox
- Timestamp:
- Apr 10, 2015 4:48:50 PM (10 years ago)
- Location:
- trunk/src/VBox/Additions
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp
r55043 r55191 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 488 468 /** 489 469 * Query the host for an HGSMI configuration parameter via an HGSMI command. … … 501 481 LogFunc(("u32Index = %d\n", u32Index)); 502 482 503 rc = testQueryConf(pCtx);504 if (RT_FAILURE(rc))505 return rc;506 483 /* Allocate the IO buffer. */ 507 484 p = (VBVACONF32 *)VBoxHGSMIBufferAlloc(pCtx, … … 512 489 /* Prepare data to be sent to the host. */ 513 490 p->u32Index = u32Index; 514 p->u32Value = UINT32_MAX;491 p->u32Value = 0; 515 492 rc = VBoxHGSMIBufferSubmit(pCtx, p); 516 493 if (RT_SUCCESS(rc)) -
trunk/src/VBox/Additions/x11/VBoxClient/display.cpp
r55043 r55191 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( bool fDisableEvents)88 static int disableEventsAndCaps() 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 if (fDisableEvents)97 rc = VbglR3CtlFilterMask(0, VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED| VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST);96 rc = VbglR3CtlFilterMask(0, VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED 97 | 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) * 2);176 long *paSizeHints = (long *)RTMemTmpAllocZ(pState->cScreensTracked * sizeof(long)); 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) << 16185 183 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 186 else if (pState->paScreenInformation[i].cx != 0 && pState->paScreenInformation[i].cy != 0) 187 paSizeHints[2 * i] = -1; 188 if ( pState->paScreenInformation[i].fEnabled 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; 187 paSizeHints[i] = -1; 194 188 } 195 189 XChangeProperty(pState->pDisplay, DefaultRootWindow(pState->pDisplay), XInternAtom(pState->pDisplay, "VBOX_SIZE_HINTS", 0), 196 XA_INTEGER, 32, PropModeReplace, (unsigned char *)paSizeHints, pState->cScreensTracked * 2);190 XA_INTEGER, 32, PropModeReplace, (unsigned char *)paSizeHints, pState->cScreensTracked); 197 191 XFlush(pState->pDisplay); 198 192 RTMemTmpFree(paSizeHints); 199 193 } 200 194 201 static void notifyXServer RandR11(struct DISPLAYSTATE *pState)195 static void notifyXServer(struct DISPLAYSTATE *pState) 202 196 { 203 197 char szCommand[256]; 198 unsigned i; 199 bool fUpdateInformation = false; 204 200 205 201 /** @note The xrandr command can fail if something else accesses RandR at 206 202 * the same time. We just ignore failure for now and let the user try 207 203 * again as we do not know what someone else is doing. */ 208 if ( pState->paScreenInformation[0].fUpdateSize 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 209 208 && pState->paScreenInformation[0].cx > 0 && pState->paScreenInformation[0].cy > 0) 210 209 { … … 213 212 system(szCommand); 214 213 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 else 232 { 233 RTStrPrintf(szCommand, sizeof(szCommand), "%s", pState->pcszXrandr); 234 system(szCommand); 215 235 } 216 236 } … … 230 250 (unsigned char *)&fFeatures, 1); 231 251 XFlush(pState->pDisplay); 252 if (pState->fHaveRandR12) 253 for (i = 0; i < pState->cScreensTracked; ++i) 254 pState->paScreenInformation[i].fUpdateSize = true; 255 else 256 pState->paScreenInformation[0].fUpdateSize = true; 232 257 } 233 258 … … 269 294 updateMouseCapabilities(pState); 270 295 updateSizeHintsProperty(pState); 271 if (!pState->fHaveRandR12) 272 notifyXServerRandR11(pState); 296 notifyXServer(pState); 273 297 do 274 298 rc = VbglR3WaitEvent( VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST … … 361 385 if (!pSelf->mfInit) 362 386 return VERR_WRONG_ORDER; 363 return disableEventsAndCaps( false);387 return disableEventsAndCaps(); 364 388 } 365 389 … … 376 400 { 377 401 NOREF(ppInterface); 378 disableEventsAndCaps( true);402 disableEventsAndCaps(); 379 403 VbglR3Term(); 380 404 } -
trunk/src/VBox/Additions/x11/undefined_xorg
r55043 r55191 106 106 __register_frame_info_bases 107 107 rename 108 RRC rtcNotify108 RRChangeOutputProperty 109 109 RRGetInfo 110 RRScreenSizeNotify111 RRTellChanged112 110 setenv 113 111 ShadowFBInit2 … … 159 157 xf86CrtcCreate 160 158 xf86CrtcScreenInit 161 xf86CrtcSetMode162 159 xf86CrtcSetSizeRange 163 160 xf86DestroyCursorInfoRec … … 177 174 xf86SetModeDefaultName 178 175 xf86SetSingleMode 179 xf86UpdateDesktopDimensions180 176 __xstat64 -
trunk/src/VBox/Additions/x11/vboxvideo/README.testing
r55043 r55191 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 ( VBoxManage in 4.3).9 * Disabling and enabling virtual screens (only possible as of 4.4). 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 (seamless currently only works properly with VBoxClient 13 running). 12 seamless modes. 14 13 * Test switching directly between normal, full-screen, seamless and scaled 15 14 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 (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. 18 later. 24 19 * Shutting down and re-starting a virtual machine should restore the last size 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. 20 for all monitors (note: currently only after log-in). -
trunk/src/VBox/Additions/x11/vboxvideo/getmode.c
r55043 r55191 38 38 #ifdef VBOXVIDEO_13 39 39 # ifdef RT_OS_LINUX 40 # include "randrstr.h" 41 # include "xf86_OSproc.h" 40 42 # include <linux/input.h> 41 43 # ifndef EVIOCGRAB … … 51 53 # endif /* RT_OS_LINUX */ 52 54 #endif /* VBOXVIDEO_13 */ 53 54 55 /************************************************************************** 55 56 * Main functions * … … 98 99 } 99 100 101 /** vboxvideo's list of standard video modes */ 102 struct 103 { 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 enum 119 { 120 vboxNumStdModes = sizeof(vboxStandardModes) / sizeof(vboxStandardModes[0]) 121 }; 122 123 /** 124 * Returns a standard mode which the host likes. Can be called multiple 125 * 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 are 127 * available 128 * @param pScrn the screen information structure 129 * @param pScrn->bitsPerPixel 130 * if this is non-null, only modes with this BPP will be 131 * returned 132 * @param cIndex the index of the last mode queried, or 0 to query the 133 * first mode available. Note: the first index is 1 134 * @param pcx where to store the mode's width 135 * @param pcy where to store the mode's height 136 * @param pcBits where to store the mode's BPP 137 */ 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 100 160 /** 101 161 * Allocates an empty display mode and links it into the doubly linked list of … … 128 188 * of the graphics modes that we wish to support, that is: 129 189 * - A dynamic mode in first place which will be updated by the RandR code. 190 * - Several standard modes. 130 191 * - Any modes that the user requested in xorg.conf/XFree86Config. 131 192 */ … … 142 203 pMode = vboxAddEmptyScreenMode(pScrn); 143 204 vboxFillDisplayMode(pScrn, pMode, NULL, 1024, 768); 144 /* Add any modes specified by the user. We assume here that the mode names 145 * reflect the mode sizes. */ 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. */ 146 216 for (i = 0; pScrn->display->modes && pScrn->display->modes[i]; i++) 147 217 { … … 154 224 } 155 225 156 /** Set the initial values for the guest screen size hints to standard values 157 * in case nothing else is available. */ 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. */ 158 229 void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn) 159 230 { … … 171 242 pScrn->modes->HDisplay = pVBox->pScreens[0].aPreferredSize.cx; 172 243 pScrn->modes->VDisplay = pVBox->pScreens[0].aPreferredSize.cy; 173 } 174 175 static bool useHardwareCursor(uint32_t fCursorCapabilities) 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) 176 253 { 177 254 if ( !(fCursorCapabilities & VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER) 178 255 && (fCursorCapabilities & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE)) 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) 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) 209 270 { 210 271 VBOXPtr pVBox = VBOXGetRec(pScrn); 211 size_t cPropertyElements, cDummy; 212 int32_t *paModeHints, *pfCursorCapabilities; 213 int rc; 272 size_t cModesFromProperty, cDummy; 273 int32_t *paModeHints, *pfCursorCapabilities; 214 274 unsigned i; 215 bool fChanged; 216 bool fNeedUpdate = false; 217 int32_t fSizeMismatch = false; 218 219 if (vbvxGetIntegerPropery(pScrn, SIZE_HINTS_PROPERTY, &cPropertyElements, &paModeHints) != VINF_SUCCESS) 275 uint32_t fCursorCapabilities; 276 bool fOldUseHardwareCursor = pVBox->fUseHardwareCursor; 277 278 if (vbvxGetIntegerPropery(pScrn, SIZE_HINTS_PROPERTY, &cModesFromProperty, &paModeHints) != VINF_SUCCESS) 220 279 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) 288 { 289 if (pVBox->paVBVAModeHints[i].magic == VBVAMODEHINT_MAGIC) 290 { 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]; 297 } 298 } 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 221 312 if (paModeHints != NULL) 222 for (i = 0; i < c PropertyElements / 2&& i < pVBox->cScreens; ++i)313 for (i = 0; i < cModesFromProperty && i < pVBox->cScreens; ++i) 223 314 { 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) 315 if (paModeHints[i] != 0 && paModeHints[i] != pVBox->pScreens[i].lastModeHintFromProperty) 231 316 { 232 if ( iSizeHint== -1)233 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afConnected, false, &fChanged, fNoHGSMI);317 if (paModeHints[i] == -1) 318 pVBox->pScreens[i].afConnected = false; 234 319 else 235 320 { 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);321 pVBox->pScreens[i].aPreferredSize.cx = paModeHints[i] >> 16; 322 pVBox->pScreens[i].aPreferredSize.cy = paModeHints[i] & 0x8fff; 323 pVBox->pScreens[i].afConnected = true; 239 324 } 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; 325 pVBox->pScreens[i].lastModeHintFromProperty = paModeHints[i]; 253 326 } 254 327 } 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 { 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]; 272 392 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) 284 { 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); 296 } 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 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 */ 305 455 306 456 #ifdef VBOXVIDEO_13 307 457 # ifdef RT_OS_LINUX 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. */ 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. */ 312 460 static void acpiEventHandler(int fd, void *pvData) 313 461 { … … 317 465 ssize_t rc; 318 466 467 pVBox->fHaveReadHGSMIModeHintData = false; 468 RRGetInfo(pScreen 469 # if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5 470 , TRUE 471 # endif 472 ); 473 VBVXASSERT(pVBox->fHaveReadHGSMIModeHintData == true, ("fHaveReadHGSMIModeHintData not set.\n")); 319 474 do 320 475 rc = read(fd, &event, sizeof(event)); … … 324 479 } 325 480 326 void vbvxSetUpLinuxACPI(ScreenPtr pScreen)481 void VBoxSetUpLinuxACPI(ScreenPtr pScreen) 327 482 { 328 483 VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]); … … 374 529 } 375 530 376 void vbvxCleanUpLinuxACPI(ScreenPtr pScreen)531 void VBoxCleanUpLinuxACPI(ScreenPtr pScreen) 377 532 { 378 533 VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]); … … 385 540 # endif /* RT_OS_LINUX */ 386 541 #endif /* VBOXVIDEO_13 */ 387 -
trunk/src/VBox/Additions/x11/vboxvideo/helpers.c
r55043 r55191 55 55 } 56 56 57 /* TESTING: if this is broken, dynamic resizing will not work on old X servers (1.2 and older). */ 57 58 int vbvxGetIntegerPropery(ScrnInfoPtr pScrn, char *pszName, size_t *pcData, int32_t **ppaData) 58 59 { … … 63 64 if (!ROOT_WINDOW(pScrn)) 64 65 return VERR_NOT_FOUND; 65 atom = MakeAtom(pszName, strlen(pszName), TRUE);66 atom = MakeAtom(pszName, strlen(pszName), FALSE); 66 67 if (atom == BAD_RESOURCE) 67 68 return VERR_NOT_FOUND; … … 75 76 *ppaData = (int32_t *)prop->data; 76 77 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);87 78 } 88 79 -
trunk/src/VBox/Additions/x11/vboxvideo/setmode.c
r55043 r55191 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 vxClearVRAM(ScrnInfoPtr pScrn, size_t cbOldSize, size_t cbNewSize)77 void vboxClearVRAM(ScrnInfoPtr pScrn, int32_t cNewX, int32_t cNewY) 78 78 { 79 79 VBOXPtr pVBox = VBOXGetRec(pScrn); 80 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)); 80 uint64_t cbOldFB, cbNewFB; 81 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)); 91 89 } 92 90 93 91 /** Set a graphics mode. Poke any required values into registers, do an HGSMI 94 * mode set and tell the host we support advanced graphics functions. 95 */ 96 void vbvxSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth, unsigned cHeight, int x, int y, bool fEnabled, 97 bool fConnected, struct vbvxFrameBuffer *pFrameBuffer) 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. 96 */ 97 Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth, 98 unsigned cHeight, int x, int y) 98 99 { 99 100 VBOXPtr pVBox = VBOXGetRec(pScrn); 100 uint32_t offStart; 101 uint32_t offStart, cwReal = cWidth; 102 bool fEnabled; 101 103 uint16_t fFlags; 102 104 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; 106 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); 105 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; 114 129 fFlags = VBVA_SCREEN_F_ACTIVE; 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); 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; 143 } 144 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) 149 { 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); 155 int rc; 156 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) 168 { 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); 196 } 197 #else 198 rc = VBoxHGSMIUpdateInputMapping(&pVBox->guestCtx, 0 - pVBox->pScreens[0].aScreenLocation.x, 199 0 - pVBox->pScreens[0].aScreenLocation.y, pScrn->virtualX, pScrn->virtualY); 121 200 if (RT_FAILURE(rc)) 122 201 FatalError("Failed to update the input mapping.\n"); 202 #endif 203 #ifdef RT_OS_SOLARIS 204 /* 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 #endif 218 return TRUE; 123 219 } 124 125 /** Tell the virtual mouse device about the new virtual desktop size. */126 void vbvxSetSolarisMouseRange(int width, int height)127 {128 #ifdef RT_OS_SOLARIS129 int rc;130 int hMouse = open("/dev/mouse", O_RDWR);131 132 if (hMouse >= 0)133 {134 do {135 Ms_screen_resolution Res = { height, width };136 rc = ioctl(hMouse, MSIOSRESOLUTION, &Res);137 } while ((rc != 0) && (errno == EINTR));138 close(hMouse);139 }140 #else141 (void)width; (void)height;142 #endif143 } -
trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
r55064 r55191 80 80 81 81 #include "fb.h" 82 #include "os.h"83 82 84 83 #include "vboxvideo.h" 85 84 #include <VBox/VBoxGuest.h> 86 #include <VBox/Hardware/VBoxVideoVBE.h>87 85 #include "version-generated.h" 88 86 #include "product-generated.h" … … 100 98 /* #define DPMS_SERVER 101 99 #include "extensions/dpms.h" */ 102 103 /* ShadowFB support */104 #include "shadowfb.h"105 100 106 101 /* VGA hardware functions for setting and restoring text mode */ … … 150 145 static void VBOXSaveMode(ScrnInfoPtr pScrn); 151 146 static void VBOXRestoreMode(ScrnInfoPtr pScrn); 152 static void setSizesAndCursorIntegration(ScrnInfoPtr pScrn, bool fScreenInitTime, bool fVTSwitchTime);153 154 #ifndef XF86_SCRN_INTERFACE155 # define xf86ScreenToScrn(pScreen) xf86Screens[(pScreen)->myNum]156 # define xf86ScrnToScreen(pScrn) screenInfo.screens[(pScrn)->scrnIndex]157 #endif158 147 159 148 static inline void VBOXSetRec(ScrnInfoPtr pScrn) … … 273 262 #endif /* !XORG_7X */ 274 263 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.width292 || height != pPixmap->drawable.height)293 {294 if ( adjustedWidth > VBOX_VIDEO_MAX_VIRTUAL || height > VBOX_VIDEO_MAX_VIRTUAL295 || (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_OLD309 if (pVBox->useDRI)310 VBOXDRIUpdateStride(pScrn, pVBox);311 #endif312 return TRUE;313 }314 315 /** Set a video mode to the hardware, RandR 1.1 version. Since we no longer do316 * 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 else330 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 336 264 #ifdef VBOXVIDEO_13 337 265 /* X.org 1.3+ mode-setting support ******************************************/ 338 339 /** Set a video mode to the hardware, RandR 1.2 version. If this is the first340 * screen, re-set the current mode for all others (the offset for the first341 * screen is always treated as zero by the hardware, so all other screens need342 * to be changed to compensate for any changes!). The mode to set is taken343 * 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 }366 266 367 267 /* For descriptions of these functions and structures, see … … 372 272 { 373 273 VBOXPtr pVBox = VBOXGetRec(pScrn); 374 Bool rc;375 unsigned i;376 377 274 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; 378 278 /* Don't fiddle with the hardware if we are switched 379 279 * to a virtual terminal. */ … … 383 283 return TRUE; 384 284 } 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; 285 return VBOXAdjustScreenPixmap(pScrn, cw, ch); 392 286 } 393 287 … … 399 293 vbox_crtc_dpms(xf86CrtcPtr crtc, int mode) 400 294 { 401 ScrnInfoPtr pScrn = crtc->scrn; 402 VBOXPtr pVBox = VBOXGetRec(pScrn); 295 VBOXPtr pVBox = VBOXGetRec(crtc->scrn); 403 296 unsigned cDisplay = (uintptr_t)crtc->driver_private; 404 405 TRACE_LOG("mode=%d\n", mode); 406 pVBox->pScreens[cDisplay].fPowerOn = (mode != DPMSModeOff); 407 setModeRandR12(pScrn, cDisplay); 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); 408 315 } 409 316 … … 438 345 TRACE_LOG("name=%s, HDisplay=%d, VDisplay=%d, x=%d, y=%d\n", adjusted_mode->name, 439 346 adjusted_mode->HDisplay, adjusted_mode->VDisplay, x, y); 440 pVBox->pScreens[cDisplay].fPowerOn = true; 347 pVBox->pScreens[cDisplay].fCrtcEnabled = true; 348 pVBox->pScreens[cDisplay].fOutputEnabled = true; 441 349 pVBox->pScreens[cDisplay].aScreenLocation.cx = adjusted_mode->HDisplay; 442 350 pVBox->pScreens[cDisplay].aScreenLocation.cy = adjusted_mode->VDisplay; … … 451 359 return; 452 360 } 453 setModeRandR12(crtc->scrn, cDisplay); 361 VBOXSetMode(crtc->scrn, cDisplay, adjusted_mode->HDisplay, 362 adjusted_mode->VDisplay, x, y); 454 363 } 455 364 … … 493 402 vbox_output_dpms (xf86OutputPtr output, int mode) 494 403 { 495 (void)output; (void)mode; 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); 496 424 } 497 425 … … 570 498 uint32_t x, y, iScreen; 571 499 iScreen = (uintptr_t)output->driver_private; 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); 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 } 577 520 TRACE_EXIT(); 578 521 return pModes; … … 674 617 675 618 #ifndef XF86_SCRN_INTERFACE 619 # define xf86ScreenToScrn(pScreen) xf86Screens[(pScreen)->myNum] 620 # define xf86ScrnToScreen(pScrn) screenInfo.screens[(pScrn)->scrnIndex] 676 621 # define SCRNINDEXAPI(pfn) pfn ## Index 677 622 static Bool VBOXScreenInitIndex(int scrnIndex, ScreenPtr pScreen, int argc, … … 935 880 * took the first valid values set to these two as maxima over the 936 881 * server lifetime. */ 937 pScrn->virtualX = VBOX_VIDEO_MAX_VIRTUAL;938 pScrn->virtualY = VBOX_VIDEO_MAX_VIRTUAL;882 pScrn->virtualX = 32000; 883 pScrn->virtualY = 32000; 939 884 #else 940 885 /* We don't validate with xf86ValidateModes and xf86PruneModes as we … … 944 889 945 890 /* Set the right virtual resolution. */ 946 pScrn->virtualX = pScrn-> bitsPerPixel == 16 ? (pScrn->currentMode->HDisplay + 1) & ~1 : pScrn->currentMode->HDisplay;891 pScrn->virtualX = pScrn->currentMode->HDisplay; 947 892 pScrn->virtualY = pScrn->currentMode->VDisplay; 948 893 … … 950 895 951 896 /* Needed before we initialise DRI. */ 952 pScrn->displayWidth = pScrn->virtualX; 897 pVBox->cbLine = vboxLineLength(pScrn, pScrn->virtualX); 898 pScrn->displayWidth = vboxDisplayPitch(pScrn, pVBox->cbLine); 953 899 954 900 xf86PrintModes(pScrn); … … 1039 985 if (property_name == BAD_RESOURCE) 1040 986 FatalError("Failed to retrieve \"HAS_VT\" atom\n"); 1041 if (ROOT_WINDOW(pScrn) == NULL)1042 return;1043 987 ChangeWindowProperty(ROOT_WINDOW(pScrn), property_name, XA_INTEGER, 32, 1044 988 PropModeReplace, 1, &value, TRUE); 1045 989 } 1046 990 #endif /* SET_HAVE_VT_PROPERTY */ 1047 1048 #ifdef VBOXVIDEO_131049 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 == XF86OutputStatusConnected1065 && pVBox->pScreens[i].paCrtcs->x + pVBox->pScreens[i].aPreferredSize.cx < VBOX_VIDEO_MAX_VIRTUAL1066 && 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 else1080 {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) >= 141085 xf86UpdateDesktopDimensions();1086 #elif GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 121087 screenInfo.width = cx;1088 screenInfo.height = cy;1089 #endif1090 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) >= 51114 NULL,1115 #endif1116 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) >= 51125 RRGetInfo(xf86ScrnToScreen(pScrn), TRUE);1126 # else1127 RRGetInfo(xf86ScrnToScreen(pScrn));1128 # endif1129 setVirtualSizeRandR12(pScrn, fLimitedContext);1130 setScreenSizesRandR12(pScrn, fLimitedContext);1131 if (!fLimitedContext)1132 {1133 RRScreenSizeNotify(xf86ScrnToScreen(pScrn));1134 RRTellChanged(xf86ScrnToScreen(pScrn));1135 }1136 }1137 1138 #else1139 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, pNewMode, fLimitedContext);1149 }1150 1151 #endif1152 1153 static void setSizesAndCursorIntegration(ScrnInfoPtr pScrn, bool fScreenInitTime, bool fVTSwitchTime)1154 {1155 VBOXPtr pVBox = VBOXGetRec(pScrn);1156 1157 TRACE_LOG("fScreenInitTime=%d, fVTSwitchTime=%d\n", (int)fScreenInitTime, (int)fVTSwitchTime);1158 #ifdef VBOXVIDEO_131159 setSizesRandR12(pScrn, fScreenInitTime);1160 #else1161 setSizesRandR11(pScrn, fScreenInitTime);1162 #endif1163 if (!fVTSwitchTime)1164 vbvxReprobeCursor(pScrn);1165 }1166 1167 /* We update the size hints from the X11 property set by VBoxClient every time1168 * 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-life1170 * 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, false);1186 }1187 991 1188 992 /* … … 1259 1063 1260 1064 #if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX) 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); 1065 VBoxSetUpLinuxACPI(pScreen); 1066 #endif 1067 1068 vbox_open (pScrn, pScreen, pVBox); 1274 1069 vboxEnableVbva(pScrn); 1275 /* Set up the dirty rectangle handler. It will be added into a function1276 * chain and gets removed when the screen is cleaned up. */1277 if (ShadowFBInit2(pScreen, NULL, vbvxHandleDirtyRect) != TRUE)1278 return FALSE;1279 1070 VBoxInitialiseSizeHints(pScrn); 1280 /* Get any screen size hints from HGSMI. Do not yet try to access X111281 * properties, as they are not yet set up, and nor are the clients that1282 * might have set them. */1283 vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, NULL);1284 1071 1285 1072 #ifdef VBOXVIDEO_13 … … 1317 1104 /* Set a sane minimum and maximum mode size to match what the hardware 1318 1105 * supports. */ 1319 xf86CrtcSetSizeRange(pScrn, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL, VBOX_VIDEO_MAX_VIRTUAL);1106 xf86CrtcSetSizeRange(pScrn, 64, 64, 16384, 16384); 1320 1107 1321 1108 /* Now create our initial CRTC/output configuration. */ … … 1325 1112 } 1326 1113 1327 /* Initialise randr 1.2 mode-setting functions. */ 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. */ 1328 1117 if (!xf86CrtcScreenInit(pScreen)) { 1329 1118 return FALSE; 1330 1119 } 1331 1120 1332 #endif 1121 if (!xf86SetDesiredModes(pScrn)) { 1122 return FALSE; 1123 } 1124 #else /* !VBOXVIDEO_13 */ 1125 VBoxSetUpRandR11(pScreen); 1333 1126 /* set first video mode */ 1334 setSizesAndCursorIntegration(pScrn, true, false); 1335 1336 /* Register block and wake-up handlers for getting new screen size hints. */ 1337 RegisterBlockAndWakeupHandlers(updateSizeHintsBlockHandler, (WakeupHandlerProcPtr)NoopDDA, (pointer)pScrn); 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 */ 1338 1139 1339 1140 /* software cursor */ … … 1386 1187 1387 1188 TRACE_ENTRY(); 1189 vboxClearVRAM(pScrn, 0, 0); 1388 1190 #ifdef VBOX_DRI_OLD 1389 1191 if (pVBox->useDRI) … … 1396 1198 } 1397 1199 #endif 1398 vbvxSetUpHGSMIHeapInGuest(pVBox, pScrn->videoRam * 1024);1399 1200 vboxEnableVbva(pScrn); 1400 /* Re-set video mode */ 1401 vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, NULL); 1402 vbvxReadSizesAndCursorIntegrationFromProperties(pScrn, NULL); 1403 setSizesAndCursorIntegration(pScrn, false, true); 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 1404 1213 #ifdef SET_HAVE_VT_PROPERTY 1405 1214 updateHasVTProperty(pScrn, TRUE); … … 1418 1227 #ifdef VBOXVIDEO_13 1419 1228 for (i = 0; i < pVBox->cScreens; ++i) 1420 vbox_ crtc_dpms(pVBox->pScreens[i].paCrtcs, DPMSModeOff);1229 vbox_output_dpms(pVBox->pScreens[i].paOutputs, DPMSModeOff); 1421 1230 #endif 1422 1231 vboxDisableVbva(pScrn); 1423 vb vxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel / 8, 0);1232 vboxClearVRAM(pScrn, 0, 0); 1424 1233 #ifdef VBOX_DRI_OLD 1425 1234 if (pVBox->useDRI) … … 1449 1258 1450 1259 for (i = 0; i < pVBox->cScreens; ++i) 1451 vbox_ crtc_dpms(pVBox->pScreens[i].paCrtcs, DPMSModeOff);1260 vbox_output_dpms(pVBox->pScreens[i].paOutputs, DPMSModeOff); 1452 1261 #endif 1453 1262 vboxDisableVbva(pScrn); 1454 vb vxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel / 8, 0);1263 vboxClearVRAM(pScrn, 0, 0); 1455 1264 } 1456 1265 #ifdef VBOX_DRI … … 1479 1288 pScreen->CloseScreen = pVBox->CloseScreen; 1480 1289 #if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX) 1481 vbvxCleanUpLinuxACPI(pScreen);1290 VBoxCleanUpLinuxACPI(pScreen); 1482 1291 #endif 1483 1292 #ifndef XF86_SCRN_INTERFACE … … 1491 1300 { 1492 1301 VBOXPtr pVBox; 1493 Bool rc = TRUE;1302 Bool rc; 1494 1303 1495 1304 TRACE_LOG("HDisplay=%d, VDisplay=%d\n", pMode->HDisplay, pMode->VDisplay); 1305 #ifndef VBOXVIDEO_13 1306 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 #endif 1496 1315 if (!pScrn->vtSema) 1497 1316 { … … 1503 1322 rc = xf86SetSingleMode(pScrn, pMode, RR_Rotate_0); 1504 1323 #else 1505 setModeRandR11(pScrn, pMode, false); 1324 VBOXAdjustScreenPixmap(pScrn, pMode->HDisplay, pMode->VDisplay); 1325 rc = VBOXSetMode(pScrn, 0, pMode->HDisplay, pMode->VDisplay, 1326 pScrn->frameX0, pScrn->frameY0); 1506 1327 #endif 1507 1328 TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE"); … … 1510 1331 1511 1332 static void VBOXAdjustFrame(ScrnInfoPtr pScrn, int x, int y) 1512 { (void)pScrn; (void)x; (void)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 } 1513 1351 1514 1352 static void VBOXFreeScreen(ScrnInfoPtr pScrn) -
trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
r55043 r55191 55 55 #include <VBox/VBoxVideoGuest.h> 56 56 #include <VBox/VBoxVideo.h> 57 58 #ifndef VBVA_SCREEN_F_BLANK59 # define VBVA_SCREEN_F_BLANK 0x000460 #endif61 57 62 58 #ifdef DEBUG … … 134 130 #define VBOX_MAX_DRAWABLES 256 /* At random. */ 135 131 136 #define VBOX_VIDEO_MIN_SIZE 64137 #define VBOX_VIDEO_MAX_VIRTUAL (INT16_MAX - 1)138 139 132 #define VBOXPTR(p) ((VBOXPtr)((p)->driverPrivate)) 140 133 … … 155 148 RTRECT2 aScreenLocation; 156 149 /** Is this CRTC enabled or in DPMS off state? */ 157 Bool fPowerOn; 150 Bool fCrtcEnabled; 151 /** Is this output enabled or in DPMS low power state? */ 152 Bool fOutputEnabled; 158 153 #ifdef VBOXVIDEO_13 159 154 /** The virtual crtcs. */ … … 168 163 /** The current preferred resolution for the screen */ 169 164 RTRECTSIZE aPreferredSize; 170 /** The current preferred location for the screen. */171 RTPOINT aPreferredLocation;172 165 /** Has this screen been enabled by the host? */ 173 166 Bool afConnected; 174 /** Does this screen have a preferred location?*/175 Bool afHaveLocation;167 /** The last mode hint data read from the X11 property. */ 168 int32_t lastModeHintFromProperty; 176 169 }; 177 170 … … 190 183 /** The size of the framebuffer and the VBVA buffers at the end of it. */ 191 184 unsigned long cbView; 185 /** The current line size in bytes */ 186 uint32_t cbLine; 192 187 /** Whether the pre-X-server mode was a VBE mode */ 193 188 bool fSavedVBEMode; … … 203 198 /** Do we currently want to use the host cursor? */ 204 199 Bool fUseHardwareCursor; 200 /** The last cursor capabilities data read from the X11 property. */ 201 int32_t fLastCursorCapabilitiesFromProperty; 205 202 /** Number of screens attached */ 206 203 uint32_t cScreens; 207 204 /** Information about each virtual screen. */ 208 205 struct VBoxScreen *pScreens; 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; 206 /** The last requested framebuffer size. */ 207 RTRECTSIZE FBSize; 208 #ifdef VBOXVIDEO_13 213 209 /** Array of structures for receiving mode hints. */ 214 210 VBVAMODEHINT *paVBVAModeHints; 215 #ifdef VBOXVIDEO_13216 211 # ifdef RT_OS_LINUX 217 212 /** Input device file descriptor for getting ACPI hot-plug events. */ … … 220 215 void *hACPIEventHandler; 221 216 # endif 217 /** Have we read all available HGSMI mode hint data? */ 218 bool fHaveReadHGSMIModeHintData; 219 #else 220 /** The original CreateScreenResources procedure which we wrap with our own. 221 */ 222 CreateScreenResourcesProcPtr pfnCreateScreenResources; 222 223 #endif 223 224 /** HGSMI guest heap context */ … … 243 244 #define VBOXGetRec vbvxGetRec /* Temporary */ 244 245 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 beginning251 * 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 */271 249 extern Bool vbox_cursor_init (ScreenPtr pScreen); 250 extern void vbox_open (ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox); 272 251 extern void vbox_close (ScrnInfoPtr pScrn, VBOXPtr pVBox); 273 252 274 /* vbva.c */275 extern void vbvxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects);276 extern void vbvxSetUpHGSMIHeapInGuest(VBOXPtr pVBox, uint32_t cbVRAM);277 253 extern Bool vboxEnableVbva(ScrnInfoPtr pScrn); 278 254 extern void vboxDisableVbva(ScrnInfoPtr pScrn); 279 255 280 256 /* getmode.c */ 257 extern unsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex, 258 uint32_t *pcx, uint32_t *pcy); 281 259 extern void vboxAddModes(ScrnInfoPtr pScrn); 282 260 extern void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn); 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); 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 287 268 288 269 /* DRI stuff */ … … 298 279 #endif 299 280 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 300 307 #endif /* _VBOXVIDEO_H_ */ 301 308 -
trunk/src/VBox/Additions/x11/vboxvideo/vbva.c
r55043 r55191 18 18 #include <VBox/VBoxGuestLib.h> 19 19 20 #ifndef PCIACCESS 21 # include <xf86Pci.h> 22 # include <Pci.h> 23 #endif 24 25 #include "xf86.h" 26 #define NEED_XF86_TYPES 20 27 #include <iprt/string.h> 21 28 #include "compiler.h" 29 30 /* ShadowFB support */ 31 #include "shadowfb.h" 22 32 23 33 #include "vboxvideo.h" … … 41 51 * rectangles 42 52 */ 43 void vbvxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects) 53 static void 54 vboxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects) 44 55 { 45 56 VBVACMDHDR cmdHdr; … … 68 79 || aRects[i].y2 < pVBox->pScreens[j].aScreenLocation.y) 69 80 continue; 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;81 cmdHdr.x = (int16_t)aRects[i].x1; 82 cmdHdr.y = (int16_t)aRects[i].y1; 72 83 cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1); 73 84 cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1); … … 89 100 } 90 101 102 /** Callback to fill in the view structures */ 103 static int 104 vboxFillViewInfo(void *pvVBox, struct VBVAINFOVIEW *pViews, uint32_t cViews) 105 { 106 VBOXPtr pVBox = (VBOXPtr)pvVBox; 107 unsigned i; 108 for (i = 0; i < cViews; ++i) 109 { 110 pViews[i].u32ViewIndex = i; 111 pViews[i].u32ViewOffset = 0; 112 pViews[i].u32ViewSize = pVBox->cbView; 113 pViews[i].u32MaxScreenSize = pVBox->cbFBMax; 114 } 115 return VINF_SUCCESS; 116 } 117 118 /** 119 * Initialise VirtualBox's accelerated video extensions. 120 * 121 * @returns TRUE on success, FALSE on failure 122 */ 123 static Bool 124 vboxInitVbva(int scrnIndex, ScreenPtr pScreen, VBOXPtr pVBox) 125 { 126 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 127 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 91 149 static DECLCALLBACK(void *) hgsmiEnvAlloc(void *pvEnv, HGSMISIZE cb) 92 150 { … … 109 167 110 168 /** 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; 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; 119 178 uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory; 120 179 void *pvGuestHeapMemory; 121 180 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 130 /** Callback to fill in the view structures */ 131 static int 132 vboxFillViewInfo(void *pvVBox, struct VBVAINFOVIEW *pViews, uint32_t cViews) 133 { 134 VBOXPtr pVBox = (VBOXPtr)pvVBox; 135 unsigned i; 136 for (i = 0; i < cViews; ++i) 137 { 138 pViews[i].u32ViewIndex = i; 139 pViews[i].u32ViewOffset = 0; 140 pViews[i].u32ViewSize = pVBox->cbView; 141 pViews[i].u32MaxScreenSize = pVBox->cbFBMax; 142 } 143 return VINF_SUCCESS; 144 } 145 146 /** 147 * Initialise VirtualBox's accelerated video extensions. 148 * 149 * @returns TRUE on success, FALSE on failure 150 */ 151 static Bool vboxSetupVRAMVbva(VBOXPtr pVBox) 152 { 153 int rc = VINF_SUCCESS; 154 unsigned i; 155 156 pVBox->cbFBMax = pVBox->cbView; 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); 157 211 for (i = 0; i < pVBox->cScreens; ++i) 158 212 { … … 170 224 rc = VBoxHGSMISendViewInfo(&pVBox->guestCtx, pVBox->cScreens, 171 225 vboxFillViewInfo, (void *)pVBox); 172 VBVXASSERT(RT_SUCCESS(rc), ("Failed to send the view information to the host, rc=%d\n", rc)); 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 } 173 231 return TRUE; 174 232 } 175 233 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; 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"); 192 241 } 193 242 … … 203 252 { 204 253 bool rc = TRUE; 254 int scrnIndex = pScrn->scrnIndex; 205 255 unsigned i; 206 256 VBOXPtr pVBox = pScrn->driverPrivate; 207 257 208 258 TRACE_ENTRY(); 209 if (!vboxSetupVRAMVbva(p VBox))259 if (!vboxSetupVRAMVbva(pScrn, pVBox)) 210 260 return FALSE; 211 261 for (i = 0; i < pVBox->cScreens; ++i) … … 219 269 rc = FALSE; 220 270 } 221 VBVXASSERT(rc, ("Failed to enable screen update reporting for at least one virtual monitor.\n")); 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 } 222 278 #ifdef VBOXVIDEO_13 223 VBoxHGSMISendCapsInfo(&pVBox->guestCtx, VBVACAPS_VIDEO_MODE_HINTS | VBVACAPS_DISABLE_CURSOR_INTEGRATION); 224 pVBox->fHaveHGSMIModeHints = haveHGSMIModeHintAndCursorReportingInterface(pVBox); 225 pVBox->fHostHasScreenBlankingFlag = hostHasScreenBlankingFlag(pVBox); 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 226 285 #endif 227 286 return rc; … … 240 299 { 241 300 int rc; 301 int scrnIndex = pScrn->scrnIndex; 242 302 unsigned i; 243 303 VBOXPtr pVBox = pScrn->driverPrivate;
Note:
See TracChangeset
for help on using the changeset viewer.