Changeset 55262 in vbox for trunk/src/VBox/Additions/x11/vboxvideo
- Timestamp:
- Apr 15, 2015 5:34:05 AM (10 years ago)
- Location:
- trunk/src/VBox/Additions/x11/vboxvideo
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/vboxvideo/README.testing
r55250 r55262 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
r55250 r55262 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 * … … 154 155 } 155 156 156 /** Set the initial values for the guest screen size hints to standard values 157 * in case nothing else is available. */ 157 /** Set the initial values for the guest screen size hints by reading saved 158 * values from files. */ 159 /** @todo Actually read the files instead of setting dummies. */ 158 160 void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn) 159 161 { … … 171 173 pScrn->modes->HDisplay = pVBox->pScreens[0].aPreferredSize.cx; 172 174 pScrn->modes->VDisplay = pVBox->pScreens[0].aPreferredSize.cy; 175 /* RandR 1.1 quirk: make sure that the initial resolution is always present 176 * in the mode list as RandR will always advertise a mode of the initial 177 * virtual resolution via GetScreenInfo. */ 178 pMode = vboxAddEmptyScreenMode(pScrn); 179 vboxFillDisplayMode(pScrn, pMode, NULL, pVBox->pScreens[0].aPreferredSize.cx, 180 pVBox->pScreens[0].aPreferredSize.cy); 181 } 182 183 static void updateUseHardwareCursor(VBOXPtr pVBox, uint32_t fCursorCapabilities) 184 { 185 if ( !(fCursorCapabilities & VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER) 186 && (fCursorCapabilities & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE)) 187 pVBox->fUseHardwareCursor = true; 188 else 189 pVBox->fUseHardwareCursor = false; 190 } 191 192 # define SIZE_HINTS_PROPERTY "VBOX_SIZE_HINTS" 193 # define MOUSE_CAPABILITIES_PROPERTY "VBOX_MOUSE_CAPABILITIES" 194 195 /** Read in information about the most recent size hints requested for the 196 * guest screens. A client application sets the hint information as a root 197 * window property. */ 198 /* TESTING: dynamic resizing and absolute pointer toggling work on old guest X servers and recent ones on Linux at the log-in screen. */ 199 /** @note we try to maximise code coverage by typically using all code paths (HGSMI and properties) in a single X session. */ 200 void VBoxUpdateSizeHints(ScrnInfoPtr pScrn) 201 { 202 VBOXPtr pVBox = VBOXGetRec(pScrn); 203 size_t cModesFromProperty, cDummy; 204 int32_t *paModeHints, *pfCursorCapabilities; 205 unsigned i; 206 uint32_t fCursorCapabilities; 207 bool fOldUseHardwareCursor = pVBox->fUseHardwareCursor; 208 209 if (vbvxGetIntegerPropery(pScrn, SIZE_HINTS_PROPERTY, &cModesFromProperty, &paModeHints) != VINF_SUCCESS) 210 paModeHints = NULL; 211 if ( vbvxGetIntegerPropery(pScrn, MOUSE_CAPABILITIES_PROPERTY, &cDummy, &pfCursorCapabilities) != VINF_SUCCESS 212 || cDummy != 1) 213 pfCursorCapabilities = NULL; 214 #ifdef VBOXVIDEO_13 215 if (!pVBox->fHaveReadHGSMIModeHintData && RT_SUCCESS(VBoxHGSMIGetModeHints(&pVBox->guestCtx, pVBox->cScreens, 216 pVBox->paVBVAModeHints))) 217 { 218 for (i = 0; i < pVBox->cScreens; ++i) 219 { 220 if (pVBox->paVBVAModeHints[i].magic == VBVAMODEHINT_MAGIC) 221 { 222 pVBox->pScreens[i].aPreferredSize.cx = pVBox->paVBVAModeHints[i].cx; 223 pVBox->pScreens[i].aPreferredSize.cy = pVBox->paVBVAModeHints[i].cy; 224 pVBox->pScreens[i].afConnected = pVBox->paVBVAModeHints[i].fEnabled; 225 /* Do not re-read this if we have data from HGSMI. */ 226 if (paModeHints != NULL && i < cModesFromProperty) 227 pVBox->pScreens[i].lastModeHintFromProperty = paModeHints[i]; 228 } 229 } 230 } 231 if (!pVBox->fHaveReadHGSMIModeHintData) 232 { 233 if (RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &fCursorCapabilities))) 234 updateUseHardwareCursor(pVBox, fCursorCapabilities); 235 else 236 pVBox->fUseHardwareCursor = false; 237 /* Do not re-read this if we have data from HGSMI. */ 238 if (pfCursorCapabilities != NULL) 239 pVBox->fLastCursorCapabilitiesFromProperty = *pfCursorCapabilities; 240 } 241 pVBox->fHaveReadHGSMIModeHintData = true; 242 #endif 243 if (paModeHints != NULL) 244 for (i = 0; i < cModesFromProperty && i < pVBox->cScreens; ++i) 245 { 246 if (paModeHints[i] != 0 && paModeHints[i] != pVBox->pScreens[i].lastModeHintFromProperty) 247 { 248 if (paModeHints[i] == -1) 249 pVBox->pScreens[i].afConnected = false; 250 else 251 { 252 pVBox->pScreens[i].aPreferredSize.cx = paModeHints[i] >> 16; 253 pVBox->pScreens[i].aPreferredSize.cy = paModeHints[i] & 0x8fff; 254 pVBox->pScreens[i].afConnected = true; 255 } 256 pVBox->pScreens[i].lastModeHintFromProperty = paModeHints[i]; 257 } 258 } 259 if (pfCursorCapabilities != NULL && *pfCursorCapabilities != pVBox->fLastCursorCapabilitiesFromProperty) 260 { 261 updateUseHardwareCursor(pVBox, (uint32_t)*pfCursorCapabilities); 262 pVBox->fLastCursorCapabilitiesFromProperty = *pfCursorCapabilities; 263 } 264 if (pVBox->fUseHardwareCursor != fOldUseHardwareCursor) 265 vbvxReprobeCursor(pScrn); 173 266 } 174 267 … … 304 397 #undef COMPARE_AND_MAYBE_SET 305 398 399 #ifndef VBOXVIDEO_13 400 401 /** The RandR "proc" vector, which we wrap with our own in order to notice 402 * when a client sends a GetScreenInfo request. */ 403 static int (*g_pfnVBoxRandRProc)(ClientPtr) = NULL; 404 /** The swapped RandR "proc" vector. */ 405 static int (*g_pfnVBoxRandRSwappedProc)(ClientPtr) = NULL; 406 407 /* TESTING: dynamic resizing and toggling cursor integration work with older guest X servers (1.2 and older). */ 408 static void vboxRandRDispatchCore(ClientPtr pClient) 409 { 410 xRRGetScreenInfoReq *pReq = (xRRGetScreenInfoReq *)pClient->requestBuffer; 411 WindowPtr pWin; 412 ScrnInfoPtr pScrn; 413 VBOXPtr pVBox; 414 DisplayModePtr pMode; 415 416 if (pClient->req_len != sizeof(xRRGetScreenInfoReq) >> 2) 417 return; 418 pWin = (WindowPtr)SecurityLookupWindow(pReq->window, pClient, 419 SecurityReadAccess); 420 if (!pWin) 421 return; 422 pScrn = xf86Screens[pWin->drawable.pScreen->myNum]; 423 pVBox = VBOXGetRec(pScrn); 424 TRACE_LOG("pVBox->fUseHardwareCursor=%u\n", pVBox->fUseHardwareCursor); 425 VBoxUpdateSizeHints(pScrn); 426 pMode = pScrn->modes; 427 if (pScrn->currentMode == pMode) 428 pMode = pMode->next; 429 pMode->HDisplay = pVBox->pScreens[0].aPreferredSize.cx; 430 pMode->VDisplay = pVBox->pScreens[0].aPreferredSize.cy; 431 } 432 433 static int vboxRandRDispatch(ClientPtr pClient) 434 { 435 xReq *pReq = (xReq *)pClient->requestBuffer; 436 437 if (pReq->data == X_RRGetScreenInfo) 438 vboxRandRDispatchCore(pClient); 439 return g_pfnVBoxRandRProc(pClient); 440 } 441 442 static int vboxRandRSwappedDispatch(ClientPtr pClient) 443 { 444 xReq *pReq = (xReq *)pClient->requestBuffer; 445 446 if (pReq->data == X_RRGetScreenInfo) 447 vboxRandRDispatchCore(pClient); 448 return g_pfnVBoxRandRSwappedProc(pClient); 449 } 450 451 static Bool vboxRandRCreateScreenResources(ScreenPtr pScreen) 452 { 453 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 454 VBOXPtr pVBox = VBOXGetRec(pScrn); 455 ExtensionEntry *pExt; 456 457 pScreen->CreateScreenResources = pVBox->pfnCreateScreenResources; 458 if (!pScreen->CreateScreenResources(pScreen)) 459 return FALSE; 460 /* I doubt we can be loaded twice - should I fail here? */ 461 if (g_pfnVBoxRandRProc) 462 return TRUE; 463 pExt = CheckExtension(RANDR_NAME); 464 if (!pExt) 465 { 466 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 467 "RandR extension not found, disabling dynamic resizing.\n"); 468 return TRUE; 469 } 470 if ( !ProcVector[pExt->base] 471 #if !defined(XF86_VERSION_CURRENT) \ 472 || XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4, 3, 99, 0, 0) 473 /* SwappedProcVector is not exported in XFree86, so we will not support 474 * swapped byte order clients. I doubt this is a big issue. */ 475 || !SwappedProcVector[pExt->base] 476 #endif 477 ) 478 FatalError("RandR \"proc\" vector not initialised\n"); 479 g_pfnVBoxRandRProc = ProcVector[pExt->base]; 480 ProcVector[pExt->base] = vboxRandRDispatch; 481 #if !defined(XF86_VERSION_CURRENT) \ 482 || XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4, 3, 99, 0, 0) 483 g_pfnVBoxRandRSwappedProc = SwappedProcVector[pExt->base]; 484 SwappedProcVector[pExt->base] = vboxRandRSwappedDispatch; 485 #endif 486 return TRUE; 487 } 488 489 /** Install our private RandR hook procedure, so that we can detect 490 * GetScreenInfo requests from clients to update our dynamic mode. This works 491 * by installing a wrapper around CreateScreenResources(), which will be called 492 * after RandR is initialised. The wrapper then in turn wraps the RandR "proc" 493 * vectors with its own handlers which will get called on any client RandR 494 * request. This should not be used in conjunction with RandR 1.2 or later. 495 * A couple of points of interest in our RandR 1.1 support: 496 * * We use the first two screen modes as dynamic modes. When a new mode hint 497 * arrives we update the first of the two which is not the current mode with 498 * the new size. 499 * * RandR 1.1 always advertises a mode of the size of the initial virtual 500 * resolution via GetScreenInfo(), so we make sure that a mode of that size 501 * is always present in the list. 502 * * RandR adds each new mode it sees to an internal array, but never removes 503 * entries. This array might end up getting rather long given that we can 504 * report a lot more modes than physical hardware. 505 */ 506 void VBoxSetUpRandR11(ScreenPtr pScreen) 507 { 508 VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]); 509 510 if (!pScreen->CreateScreenResources) 511 FatalError("called to early: CreateScreenResources not yet initialised\n"); 512 pVBox->pfnCreateScreenResources = pScreen->CreateScreenResources; 513 pScreen->CreateScreenResources = vboxRandRCreateScreenResources; 514 } 515 516 #endif /* !VBOXVIDEO_13 */ 517 306 518 #ifdef VBOXVIDEO_13 307 519 # 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. */ 520 /* TESTING: dynamic resizing works on recent Linux guest X servers at the log-in screen. */ 521 /** @note to maximise code coverage we only read data from HGSMI once, and only when responding to an ACPI event. */ 312 522 static void acpiEventHandler(int fd, void *pvData) 313 523 { … … 317 527 ssize_t rc; 318 528 529 pVBox->fHaveReadHGSMIModeHintData = false; 530 RRGetInfo(pScreen 531 # if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5 532 , TRUE 533 # endif 534 ); 535 VBVXASSERT(pVBox->fHaveReadHGSMIModeHintData == true, ("fHaveReadHGSMIModeHintData not set.\n")); 319 536 do 320 537 rc = read(fd, &event, sizeof(event)); … … 324 541 } 325 542 326 void vbvxSetUpLinuxACPI(ScreenPtr pScreen)543 void VBoxSetUpLinuxACPI(ScreenPtr pScreen) 327 544 { 328 545 VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]); … … 374 591 } 375 592 376 void vbvxCleanUpLinuxACPI(ScreenPtr pScreen)593 void VBoxCleanUpLinuxACPI(ScreenPtr pScreen) 377 594 { 378 595 VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]); … … 385 602 # endif /* RT_OS_LINUX */ 386 603 #endif /* VBOXVIDEO_13 */ 387 -
trunk/src/VBox/Additions/x11/vboxvideo/helpers.c
r55250 r55262 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 { -
trunk/src/VBox/Additions/x11/vboxvideo/setmode.c
r55250 r55262 89 89 cbNewSize = pVBox->cbFBMax; 90 90 memset(pVBox->base, 0, max(cbOldSize, cbNewSize)); 91 } 92 93 /** Clear the virtual framebuffer in VRAM. Optionally also clear up to the 94 * size of a new framebuffer. Framebuffer sizes larger than available VRAM 95 * be treated as zero and passed over. */ 96 void vboxClearVRAM(ScrnInfoPtr pScrn, int32_t cNewX, int32_t cNewY) 97 { 98 VBOXPtr pVBox = VBOXGetRec(pScrn); 99 uint64_t cbOldFB, cbNewFB; 100 101 cbOldFB = pVBox->cbLine * pScrn->virtualX; 102 cbNewFB = vboxLineLength(pScrn, cNewX) * cNewY; 103 if (cbOldFB > (uint64_t)pVBox->cbFBMax) 104 cbOldFB = 0; 105 if (cbNewFB > (uint64_t)pVBox->cbFBMax) 106 cbNewFB = 0; 107 memset(pVBox->base, 0, max(cbOldFB, cbNewFB)); 91 108 } 92 109 … … 123 140 } 124 141 142 /** Set a graphics mode. Poke any required values into registers, do an HGSMI 143 * mode set and tell the host we support advanced graphics functions. This 144 * procedure is complicated by the fact that X.Org can implicitly disable a 145 * screen by resizing the virtual framebuffer so that the screen is no longer 146 * inside it. We have to spot and handle this. 147 */ 148 Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth, 149 unsigned cHeight, int x, int y) 150 { 151 VBOXPtr pVBox = VBOXGetRec(pScrn); 152 uint32_t offStart, cwReal = cWidth; 153 bool fEnabled; 154 uint16_t fFlags; 155 int rc; 156 157 TRACE_LOG("cDisplay=%u, cWidth=%u, cHeight=%u, x=%d, y=%d, displayWidth=%d\n", 158 cDisplay, cWidth, cHeight, x, y, pScrn->displayWidth); 159 offStart = y * pVBox->cbLine + x * vboxBPP(pScrn) / 8; 160 /* Deactivate the screen if the mode - specifically the virtual width - is 161 * too large for VRAM as we sometimes have to do this - see comments in 162 * VBOXPreInit. */ 163 if ( offStart + pVBox->cbLine * cHeight > pVBox->cbFBMax 164 || pVBox->cbLine * pScrn->virtualY > pVBox->cbFBMax) 165 return FALSE; 166 /* Deactivate the screen if it is outside of the virtual framebuffer and 167 * clamp it to lie inside if it is partly outside. */ 168 if (x >= pScrn->displayWidth || x + (int) cWidth <= 0) 169 return FALSE; 170 else 171 cwReal = RT_MIN((int) cWidth, pScrn->displayWidth - x); 172 TRACE_LOG("pVBox->pScreens[%u].fCrtcEnabled=%d, fOutputEnabled=%d\n", 173 cDisplay, (int)pVBox->pScreens[cDisplay].fCrtcEnabled, 174 (int)pVBox->pScreens[cDisplay].fOutputEnabled); 175 if (cDisplay == 0) 176 VBoxVideoSetModeRegisters(cwReal, cHeight, pScrn->displayWidth, 177 vboxBPP(pScrn), 0, x, y); 178 fEnabled = pVBox->pScreens[cDisplay].fCrtcEnabled 179 && pVBox->pScreens[cDisplay].fOutputEnabled; 180 fFlags = VBVA_SCREEN_F_ACTIVE; 181 fFlags |= (pVBox->pScreens[cDisplay].afConnected ? 0 182 : VBVA_SCREEN_F_DISABLED); 183 VBoxHGSMIProcessDisplayInfo(&pVBox->guestCtx, cDisplay, x, y, 184 offStart, pVBox->cbLine, cwReal, cHeight, 185 fEnabled ? vboxBPP(pScrn) : 0, fFlags); 186 if (cDisplay == 0) 187 { 188 rc = VBoxHGSMIUpdateInputMapping(&pVBox->guestCtx, 0 - pVBox->pScreens[0].aScreenLocation.x, 189 0 - pVBox->pScreens[0].aScreenLocation.y, pScrn->virtualX, pScrn->virtualY); 190 if (RT_FAILURE(rc)) 191 FatalError("Failed to update the input mapping.\n"); 192 } 193 return TRUE; 194 } 195 196 /** Resize the virtual framebuffer. After resizing we reset all modes 197 * (X.Org 1.3+) to adjust them to the new framebuffer. 198 */ 199 Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height) 200 { 201 ScreenPtr pScreen = pScrn->pScreen; 202 PixmapPtr pPixmap = pScreen->GetScreenPixmap(pScreen); 203 VBOXPtr pVBox = VBOXGetRec(pScrn); 204 uint64_t cbLine = vboxLineLength(pScrn, width); 205 int displayWidth = vboxDisplayPitch(pScrn, cbLine); 206 int rc; 207 208 TRACE_LOG("width=%d, height=%d\n", width, height); 209 if ( width == pScrn->virtualX 210 && height == pScrn->virtualY 211 && displayWidth == pScrn->displayWidth) 212 return TRUE; 213 if (!pPixmap) { 214 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 215 "Failed to get the screen pixmap.\n"); 216 return FALSE; 217 } 218 if (cbLine > UINT32_MAX || cbLine * height >= pVBox->cbFBMax) 219 { 220 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 221 "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", 222 width, height, pVBox->cbFBMax / 1024, pScrn->videoRam); 223 return FALSE; 224 } 225 pScreen->ModifyPixmapHeader(pPixmap, width, height, 226 pScrn->depth, vboxBPP(pScrn), cbLine, 227 pVBox->base); 228 vboxClearVRAM(pScrn, width, height); 229 pScrn->virtualX = width; 230 pScrn->virtualY = height; 231 pScrn->displayWidth = displayWidth; 232 pVBox->cbLine = cbLine; 233 #ifdef VBOX_DRI_OLD 234 if (pVBox->useDRI) 235 VBOXDRIUpdateStride(pScrn, pVBox); 236 #endif 237 #ifdef VBOXVIDEO_13 238 /* Write the new values to the hardware */ 239 /** @todo why is this only for VBOXVIDEO_13? */ 240 { 241 unsigned i; 242 for (i = 0; i < pVBox->cScreens; ++i) 243 VBOXSetMode(pScrn, i, pVBox->pScreens[i].aScreenLocation.cx, 244 pVBox->pScreens[i].aScreenLocation.cy, 245 pVBox->pScreens[i].aScreenLocation.x, 246 pVBox->pScreens[i].aScreenLocation.y); 247 } 248 #else 249 rc = VBoxHGSMIUpdateInputMapping(&pVBox->guestCtx, 0 - pVBox->pScreens[0].aScreenLocation.x, 250 0 - pVBox->pScreens[0].aScreenLocation.y, pScrn->virtualX, pScrn->virtualY); 251 if (RT_FAILURE(rc)) 252 FatalError("Failed to update the input mapping.\n"); 253 #endif 254 vbvxSetSolarisMouseRange(width, height); 255 return TRUE; 256 } 257 125 258 /** Tell the virtual mouse device about the new virtual desktop size. */ 126 259 void vbvxSetSolarisMouseRange(int width, int height) -
trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
r55250 r55262 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);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 TRACE_LOG("pPixmap=%p adjustedWidth=%d height=%d pScrn->depth=%d pScrn->bitsPerPixel=%d cbLine=%d pVBox->base=%p pPixmap->drawable.width=%d pPixmap->drawable.height=%d\n",292 pPixmap, adjustedWidth, height, pScrn->depth, pScrn->bitsPerPixel, cbLine, pVBox->base, pPixmap->drawable.width,293 pPixmap->drawable.height);294 if ( adjustedWidth != pPixmap->drawable.width295 || height != pPixmap->drawable.height)296 {297 if ( adjustedWidth > VBOX_VIDEO_MAX_VIRTUAL || height > VBOX_VIDEO_MAX_VIRTUAL298 || (unsigned)cbLine * (unsigned)height >= pVBox->cbFBMax)299 {300 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,301 "Virtual framebuffer %dx%d too large. For information, video memory: %u Kb.\n",302 adjustedWidth, height, (unsigned) pVBox->cbFBMax / 1024);303 return FALSE;304 }305 vbvxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel / 8,306 adjustedWidth * height * pScrn->bitsPerPixel / 8);307 pScreen->ModifyPixmapHeader(pPixmap, adjustedWidth, height, pScrn->depth, pScrn->bitsPerPixel, cbLine, pVBox->base);308 }309 pScrn->displayWidth = pScrn->virtualX = adjustedWidth;310 pScrn->virtualY = height;311 #ifdef VBOX_DRI_OLD312 if (pVBox->useDRI)313 VBOXDRIUpdateStride(pScrn, pVBox);314 #endif315 return TRUE;316 }317 318 /** Set a video mode to the hardware, RandR 1.1 version. Since we no longer do319 * virtual frame buffers, adjust the screen pixmap dimensions to match. */320 static void setModeRandR11(ScrnInfoPtr pScrn, DisplayModePtr pMode, bool fLimitedContext)321 {322 VBOXPtr pVBox = VBOXGetRec(pScrn);323 struct vbvxFrameBuffer frameBuffer = { 0, 0, pMode->HDisplay, pMode->VDisplay, pScrn->bitsPerPixel};324 325 pVBox->pScreens[0].aScreenLocation.cx = pMode->HDisplay;326 pVBox->pScreens[0].aScreenLocation.cy = pMode->VDisplay;327 if (fLimitedContext)328 {329 pScrn->displayWidth = pScrn->virtualX = pMode->HDisplay;330 pScrn->virtualY = pMode->VDisplay;331 }332 else333 adjustScreenPixmap(pScrn, pMode->HDisplay, pMode->VDisplay);334 if (pMode->HDisplay != 0 && pMode->VDisplay != 0)335 vbvxSetMode(pScrn, 0, pMode->HDisplay, pMode->VDisplay, 0, 0, true, true, &frameBuffer);336 pScrn->currentMode = pMode;337 }338 339 264 #ifdef VBOXVIDEO_13 340 265 /* X.org 1.3+ mode-setting support ******************************************/ 341 342 /** Set a video mode to the hardware, RandR 1.2 version. If this is the first343 * screen, re-set the current mode for all others (the offset for the first344 * screen is always treated as zero by the hardware, so all other screens need345 * to be changed to compensate for any changes!). The mode to set is taken346 * from the X.Org Crtc structure. */347 static void setModeRandR12(ScrnInfoPtr pScrn, unsigned cScreen)348 {349 VBOXPtr pVBox = VBOXGetRec(pScrn);350 unsigned i;351 struct vbvxFrameBuffer frameBuffer = { pVBox->pScreens[0].paCrtcs->x, pVBox->pScreens[0].paCrtcs->y, pScrn->virtualX,352 pScrn->virtualY, pScrn->bitsPerPixel };353 unsigned cFirst = cScreen;354 unsigned cLast = cScreen != 0 ? cScreen + 1 : pVBox->cScreens;355 356 for (i = cFirst; i < cLast; ++i)357 if (pVBox->pScreens[i].paCrtcs->mode.HDisplay != 0 && pVBox->pScreens[i].paCrtcs->mode.VDisplay != 0)358 vbvxSetMode(pScrn, i, pVBox->pScreens[i].paCrtcs->mode.HDisplay, pVBox->pScreens[i].paCrtcs->mode.VDisplay,359 pVBox->pScreens[i].paCrtcs->x, pVBox->pScreens[i].paCrtcs->y, pVBox->pScreens[i].fPowerOn,360 pVBox->pScreens[i].paOutputs->status == XF86OutputStatusConnected, &frameBuffer);361 }362 363 /** Wrapper around setModeRandR12() to avoid exposing non-obvious semantics.364 */365 static void setAllModesRandR12(ScrnInfoPtr pScrn)366 {367 setModeRandR12(pScrn, 0);368 }369 266 370 267 /* For descriptions of these functions and structures, see … … 375 272 { 376 273 VBOXPtr pVBox = VBOXGetRec(pScrn); 377 Bool rc;378 unsigned i;379 380 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; 381 278 /* Don't fiddle with the hardware if we are switched 382 279 * to a virtual terminal. */ … … 386 283 return TRUE; 387 284 } 388 rc = adjustScreenPixmap(pScrn, cw, ch); 389 /* Power-on all screens (the server expects this) and set the new pitch to them. */ 390 for (i = 0; i < pVBox->cScreens; ++i) 391 pVBox->pScreens[i].fPowerOn = true; 392 setAllModesRandR12(pScrn); 393 vbvxSetSolarisMouseRange(cw, ch); 394 return rc; 285 return VBOXAdjustScreenPixmap(pScrn, cw, ch); 395 286 } 396 287 … … 402 293 vbox_crtc_dpms(xf86CrtcPtr crtc, int mode) 403 294 { 404 ScrnInfoPtr pScrn = crtc->scrn; 405 VBOXPtr pVBox = VBOXGetRec(pScrn); 295 VBOXPtr pVBox = VBOXGetRec(crtc->scrn); 406 296 unsigned cDisplay = (uintptr_t)crtc->driver_private; 407 408 TRACE_LOG("mode=%d\n", mode); 409 pVBox->pScreens[cDisplay].fPowerOn = (mode != DPMSModeOff); 410 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); 411 315 } 412 316 … … 441 345 TRACE_LOG("name=%s, HDisplay=%d, VDisplay=%d, x=%d, y=%d\n", adjusted_mode->name, 442 346 adjusted_mode->HDisplay, adjusted_mode->VDisplay, x, y); 443 pVBox->pScreens[cDisplay].fPowerOn = true; 347 pVBox->pScreens[cDisplay].fCrtcEnabled = true; 348 pVBox->pScreens[cDisplay].fOutputEnabled = true; 444 349 pVBox->pScreens[cDisplay].aScreenLocation.cx = adjusted_mode->HDisplay; 445 350 pVBox->pScreens[cDisplay].aScreenLocation.cy = adjusted_mode->VDisplay; … … 454 359 return; 455 360 } 456 setModeRandR12(crtc->scrn, cDisplay); 361 VBOXSetMode(crtc->scrn, cDisplay, adjusted_mode->HDisplay, 362 adjusted_mode->VDisplay, x, y); 457 363 } 458 364 … … 496 402 vbox_output_dpms (xf86OutputPtr output, int mode) 497 403 { 498 (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); 499 424 } 500 425 … … 573 498 uint32_t x, y, iScreen; 574 499 iScreen = (uintptr_t)output->driver_private; 575 pMode = vbox_output_add_mode(pVBox, &pModes, NULL, 576 RT_CLAMP(pVBox->pScreens[iScreen].aPreferredSize.cx, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL), 577 RT_CLAMP(pVBox->pScreens[iScreen].aPreferredSize.cy, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL), 578 TRUE, FALSE); 579 // 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); 580 503 TRACE_EXIT(); 581 504 return pModes; … … 677 600 678 601 #ifndef XF86_SCRN_INTERFACE 602 # define xf86ScreenToScrn(pScreen) xf86Screens[(pScreen)->myNum] 603 # define xf86ScrnToScreen(pScrn) screenInfo.screens[(pScrn)->scrnIndex] 679 604 # define SCRNINDEXAPI(pfn) pfn ## Index 680 605 static Bool VBOXScreenInitIndex(int scrnIndex, ScreenPtr pScreen, int argc, … … 947 872 948 873 /* Set the right virtual resolution. */ 949 pScrn->virtualX = pScrn-> bitsPerPixel == 16 ? (pScrn->currentMode->HDisplay + 1) & ~1 : pScrn->currentMode->HDisplay;874 pScrn->virtualX = pScrn->currentMode->HDisplay; 950 875 pScrn->virtualY = pScrn->currentMode->VDisplay; 951 876 … … 953 878 954 879 /* Needed before we initialise DRI. */ 955 pScrn->displayWidth = pScrn->virtualX; 880 pVBox->cbLine = vboxLineLength(pScrn, pScrn->virtualX); 881 pScrn->displayWidth = vboxDisplayPitch(pScrn, pVBox->cbLine); 956 882 957 883 xf86PrintModes(pScrn); … … 1049 975 #endif /* SET_HAVE_VT_PROPERTY */ 1050 976 1051 #ifdef VBOXVIDEO_131052 1053 static void setVirtualSizeRandR12(ScrnInfoPtr pScrn, bool fLimitedContext)1054 {1055 VBOXPtr pVBox = VBOXGetRec(pScrn);1056 unsigned i;1057 unsigned cx = 0;1058 unsigned cy = 0;1059 1060 for (i = 0; i < pVBox->cScreens; ++i)1061 {1062 if ( pVBox->fHaveHGSMIModeHints && pVBox->pScreens[i].afHaveLocation)1063 {1064 pVBox->pScreens[i].paCrtcs->x = pVBox->pScreens[i].aPreferredLocation.x;1065 pVBox->pScreens[i].paCrtcs->y = pVBox->pScreens[i].aPreferredLocation.y;1066 }1067 if ( pVBox->pScreens[i].paOutputs->status == XF86OutputStatusConnected1068 && pVBox->pScreens[i].paCrtcs->x + pVBox->pScreens[i].aPreferredSize.cx < VBOX_VIDEO_MAX_VIRTUAL1069 && pVBox->pScreens[i].paCrtcs->y + pVBox->pScreens[i].aPreferredSize.cy < VBOX_VIDEO_MAX_VIRTUAL)1070 {1071 cx = max(cx, pVBox->pScreens[i].paCrtcs->x + pVBox->pScreens[i].aPreferredSize.cx);1072 cy = max(cy, pVBox->pScreens[i].paCrtcs->y + pVBox->pScreens[i].aPreferredSize.cy);1073 }1074 }1075 if (cx != 0 && cy != 0)1076 {1077 if (fLimitedContext)1078 {1079 pScrn->virtualX = cx;1080 pScrn->virtualY = cy;1081 }1082 else1083 {1084 TRACE_LOG("cx=%u, cy=%u\n", cx, cy);1085 xf86ScrnToScreen(pScrn)->width = cx;1086 xf86ScrnToScreen(pScrn)->height = cy;1087 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 141088 xf86UpdateDesktopDimensions();1089 #elif GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 121090 screenInfo.width = cx;1091 screenInfo.height = cy;1092 #endif1093 adjustScreenPixmap(pScrn, cx, cy);1094 }1095 }1096 }1097 1098 static void setScreenSizesRandR12(ScrnInfoPtr pScrn, bool fLimitedContext)1099 {1100 VBOXPtr pVBox = VBOXGetRec(pScrn);1101 unsigned i;1102 1103 for (i = 0; i < pVBox->cScreens; ++i)1104 {1105 if (!pVBox->pScreens[i].afConnected)1106 continue;1107 /* The Crtc can get "unset" if the screen was disconnected previously.1108 * I couldn't find an API to re-set it which did not have side-effects.1109 */1110 pVBox->pScreens[i].paOutputs->crtc = pVBox->pScreens[i].paCrtcs;1111 xf86CrtcSetMode(pVBox->pScreens[i].paCrtcs, pVBox->pScreens[i].paOutputs->probed_modes, RR_Rotate_0,1112 pVBox->pScreens[i].paCrtcs->x, pVBox->pScreens[i].paCrtcs->y);1113 if (!fLimitedContext)1114 RRCrtcNotify(pVBox->pScreens[i].paCrtcs->randr_crtc, pVBox->pScreens[i].paOutputs->randr_output->modes[0],1115 pVBox->pScreens[i].paCrtcs->x, pVBox->pScreens[i].paCrtcs->y, RR_Rotate_0,1116 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 51117 NULL,1118 #endif1119 1, &pVBox->pScreens[i].paOutputs->randr_output);1120 }1121 }1122 1123 static void setSizesRandR12(ScrnInfoPtr pScrn, bool fLimitedContext)1124 {1125 VBOXPtr pVBox = VBOXGetRec(pScrn);1126 1127 # if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 51128 RRGetInfo(xf86ScrnToScreen(pScrn), TRUE);1129 # else1130 RRGetInfo(xf86ScrnToScreen(pScrn));1131 # endif1132 setVirtualSizeRandR12(pScrn, fLimitedContext);1133 setScreenSizesRandR12(pScrn, fLimitedContext);1134 if (!fLimitedContext)1135 {1136 RRScreenSizeNotify(xf86ScrnToScreen(pScrn));1137 RRTellChanged(xf86ScrnToScreen(pScrn));1138 }1139 }1140 1141 #else1142 1143 static void setSizesRandR11(ScrnInfoPtr pScrn, bool fLimitedContext)1144 {1145 VBOXPtr pVBox = VBOXGetRec(pScrn);1146 DisplayModePtr pNewMode;1147 1148 pNewMode = pScrn->modes != pScrn->currentMode ? pScrn->modes : pScrn->modes->next;1149 pNewMode->HDisplay = RT_CLAMP(pVBox->pScreens[0].aPreferredSize.cx, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL);1150 pNewMode->VDisplay = RT_CLAMP(pVBox->pScreens[0].aPreferredSize.cy, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL);1151 setModeRandR11(pScrn, pNewMode, fLimitedContext);1152 }1153 1154 #endif1155 1156 static void setSizesAndCursorIntegration(ScrnInfoPtr pScrn, bool fScreenInitTime)1157 {1158 VBOXPtr pVBox = VBOXGetRec(pScrn);1159 1160 TRACE_LOG("fScreenInitTime=%d\n", (int)fScreenInitTime);1161 #ifdef VBOXVIDEO_131162 setSizesRandR12(pScrn, fScreenInitTime);1163 #else1164 setSizesRandR11(pScrn, fScreenInitTime);1165 #endif1166 if (pScrn->vtSema)1167 vbvxReprobeCursor(pScrn);1168 }1169 1170 /* We update the size hints from the X11 property set by VBoxClient every time1171 * that the X server goes to sleep (to catch the property change request).1172 * Although this is far more often than necessary it should not have real-life1173 * performance consequences and allows us to simplify the code quite a bit. */1174 static void updateSizeHintsBlockHandler(pointer pData, OSTimePtr pTimeout, pointer pReadmask)1175 {1176 ScrnInfoPtr pScrn = (ScrnInfoPtr)pData;1177 VBOXPtr pVBox = VBOXGetRec(pScrn);1178 bool fNeedUpdate = false;1179 1180 (void)pTimeout;1181 (void)pReadmask;1182 if (!pScrn->vtSema)1183 return;1184 vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, &fNeedUpdate);1185 if (ROOT_WINDOW(pScrn) != NULL)1186 vbvxReadSizesAndCursorIntegrationFromProperties(pScrn, &fNeedUpdate);1187 if (fNeedUpdate)1188 setSizesAndCursorIntegration(pScrn, false);1189 }1190 1191 977 /* 1192 978 * QUOTE from the XFree86 DESIGN document: … … 1262 1048 1263 1049 #if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX) 1264 vbvxSetUpLinuxACPI(pScreen); 1265 #endif 1266 1267 if (!VBoxHGSMIIsSupported()) 1268 { 1269 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Graphics device too old to support.\n"); 1270 return FALSE; 1271 } 1272 vbvxSetUpHGSMIHeapInGuest(pVBox, pScrn->videoRam * 1024); 1273 pVBox->cScreens = VBoxHGSMIGetMonitorCount(&pVBox->guestCtx); 1274 pVBox->pScreens = xnfcalloc(pVBox->cScreens, sizeof(*pVBox->pScreens)); 1275 pVBox->paVBVAModeHints = xnfcalloc(pVBox->cScreens, sizeof(*pVBox->paVBVAModeHints)); 1276 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested monitor count: %u\n", pVBox->cScreens); 1050 VBoxSetUpLinuxACPI(pScreen); 1051 #endif 1052 1053 vbox_open (pScrn, pScreen, pVBox); 1277 1054 vboxEnableVbva(pScrn); 1278 /* Set up the dirty rectangle handler. It will be added into a function1279 * chain and gets removed when the screen is cleaned up. */1280 if (ShadowFBInit2(pScreen, NULL, vbvxHandleDirtyRect) != TRUE)1281 return FALSE;1282 1055 VBoxInitialiseSizeHints(pScrn); 1283 /* Get any screen size hints from HGSMI. Do not yet try to access X111284 * properties, as they are not yet set up, and nor are the clients that1285 * might have set them. */1286 vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, NULL);1287 1056 1288 1057 #ifdef VBOXVIDEO_13 … … 1328 1097 } 1329 1098 1330 /* Initialise randr 1.2 mode-setting functions. */ 1099 /* Initialise randr 1.2 mode-setting functions and set first mode. 1100 * Note that the mode won't be usable until the server has resized the 1101 * framebuffer to something reasonable. */ 1331 1102 if (!xf86CrtcScreenInit(pScreen)) { 1332 1103 return FALSE; 1333 1104 } 1334 1105 1335 #endif 1106 if (!xf86SetDesiredModes(pScrn)) { 1107 return FALSE; 1108 } 1109 #else /* !VBOXVIDEO_13 */ 1110 VBoxSetUpRandR11(pScreen); 1336 1111 /* set first video mode */ 1337 setSizesAndCursorIntegration(pScrn, true); 1338 1339 /* Register block and wake-up handlers for getting new screen size hints. */ 1340 RegisterBlockAndWakeupHandlers(updateSizeHintsBlockHandler, (WakeupHandlerProcPtr)NoopDDA, (pointer)pScrn); 1112 if (!VBOXSetMode(pScrn, 0, pScrn->currentMode->HDisplay, 1113 pScrn->currentMode->VDisplay, pScrn->frameX0, 1114 pScrn->frameY0)) 1115 return FALSE; 1116 /* Save the size in case we need to re-set it later. */ 1117 pVBox->FBSize.cx = pScrn->currentMode->HDisplay; 1118 pVBox->FBSize.cy = pScrn->currentMode->VDisplay; 1119 pVBox->pScreens[0].aScreenLocation.cx = pScrn->currentMode->HDisplay; 1120 pVBox->pScreens[0].aScreenLocation.cy = pScrn->currentMode->VDisplay; 1121 pVBox->pScreens[0].aScreenLocation.x = pScrn->frameX0; 1122 pVBox->pScreens[0].aScreenLocation.y = pScrn->frameY0; 1123 #endif /* !VBOXVIDEO_13 */ 1341 1124 1342 1125 /* software cursor */ … … 1399 1182 } 1400 1183 #endif 1401 vbvxSetUpHGSMIHeapInGuest(pVBox, pScrn->videoRam * 1024);1402 1184 vboxEnableVbva(pScrn); 1403 /* Re-set video mode */ 1404 vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, NULL); 1405 vbvxReadSizesAndCursorIntegrationFromProperties(pScrn, NULL); 1406 /* This prevents a crash in CentOS 3. I was unable to debug it to 1407 * satisfaction, partly due to the lack of symbols. My guess is that 1408 * pScrn->ModifyPixmapHeader() expects certain things to be set up when 1409 * it sees pScrn->vtSema set to true which are not quite done at this 1410 * point of the VT switch. */ 1411 pScrn->vtSema = FALSE; 1412 setSizesAndCursorIntegration(pScrn, false); 1413 pScrn->vtSema = TRUE; 1185 /* Re-assert this in case we had a change request while switched out. */ 1186 if (pVBox->FBSize.cx && pVBox->FBSize.cy) 1187 VBOXAdjustScreenPixmap(pScrn, pVBox->FBSize.cx, pVBox->FBSize.cy); 1188 #ifdef VBOXVIDEO_13 1189 if (!xf86SetDesiredModes(pScrn)) 1190 return FALSE; 1191 #else 1192 if (!VBOXSetMode(pScrn, 0, pScrn->currentMode->HDisplay, 1193 pScrn->currentMode->VDisplay, pScrn->frameX0, 1194 pScrn->frameY0)) 1195 return FALSE; 1196 #endif 1414 1197 #ifdef SET_HAVE_VT_PROPERTY 1415 1198 updateHasVTProperty(pScrn, TRUE); … … 1428 1211 #ifdef VBOXVIDEO_13 1429 1212 for (i = 0; i < pVBox->cScreens; ++i) 1430 vbox_ crtc_dpms(pVBox->pScreens[i].paCrtcs, DPMSModeOff);1213 vbox_output_dpms(pVBox->pScreens[i].paOutputs, DPMSModeOff); 1431 1214 #endif 1432 1215 vboxDisableVbva(pScrn); 1433 vb vxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel / 8, 0);1216 vboxClearVRAM(pScrn, 0, 0); 1434 1217 #ifdef VBOX_DRI_OLD 1435 1218 if (pVBox->useDRI) … … 1459 1242 1460 1243 for (i = 0; i < pVBox->cScreens; ++i) 1461 vbox_ crtc_dpms(pVBox->pScreens[i].paCrtcs, DPMSModeOff);1244 vbox_output_dpms(pVBox->pScreens[i].paOutputs, DPMSModeOff); 1462 1245 #endif 1463 1246 vboxDisableVbva(pScrn); 1464 vb vxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel / 8, 0);1247 vboxClearVRAM(pScrn, 0, 0); 1465 1248 } 1466 1249 #ifdef VBOX_DRI … … 1489 1272 pScreen->CloseScreen = pVBox->CloseScreen; 1490 1273 #if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX) 1491 vbvxCleanUpLinuxACPI(pScreen);1274 VBoxCleanUpLinuxACPI(pScreen); 1492 1275 #endif 1493 1276 #ifndef XF86_SCRN_INTERFACE … … 1501 1284 { 1502 1285 VBOXPtr pVBox; 1503 Bool rc = TRUE;1286 Bool rc; 1504 1287 1505 1288 TRACE_LOG("HDisplay=%d, VDisplay=%d\n", pMode->HDisplay, pMode->VDisplay); 1289 #ifndef VBOXVIDEO_13 1290 pVBox = VBOXGetRec(pScrn); 1291 /* Save the size in case we need to re-set it later. */ 1292 pVBox->FBSize.cx = pMode->HDisplay; 1293 pVBox->FBSize.cy = pMode->VDisplay; 1294 pVBox->pScreens[0].aScreenLocation.cx = pMode->HDisplay; 1295 pVBox->pScreens[0].aScreenLocation.cy = pMode->VDisplay; 1296 pVBox->pScreens[0].aScreenLocation.x = pScrn->frameX0; 1297 pVBox->pScreens[0].aScreenLocation.y = pScrn->frameY0; 1298 #endif 1506 1299 if (!pScrn->vtSema) 1507 1300 { … … 1513 1306 rc = xf86SetSingleMode(pScrn, pMode, RR_Rotate_0); 1514 1307 #else 1515 setModeRandR11(pScrn, pMode, false); 1308 VBOXAdjustScreenPixmap(pScrn, pMode->HDisplay, pMode->VDisplay); 1309 rc = VBOXSetMode(pScrn, 0, pMode->HDisplay, pMode->VDisplay, 1310 pScrn->frameX0, pScrn->frameY0); 1516 1311 #endif 1517 1312 TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE"); … … 1520 1315 1521 1316 static void VBOXAdjustFrame(ScrnInfoPtr pScrn, int x, int y) 1522 { (void)pScrn; (void)x; (void)y; } 1317 { 1318 VBOXPtr pVBox = VBOXGetRec(pScrn); 1319 1320 TRACE_ENTRY(); 1321 pVBox->pScreens[0].aScreenLocation.x = x; 1322 pVBox->pScreens[0].aScreenLocation.y = y; 1323 /* Don't fiddle with the hardware if we are switched 1324 * to a virtual terminal. */ 1325 if (!pScrn->vtSema) 1326 { 1327 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1328 "We do not own the active VT, exiting.\n"); 1329 return; 1330 } 1331 VBOXSetMode(pScrn, 0, pVBox->pScreens[0].aScreenLocation.cx, 1332 pVBox->pScreens[0].aScreenLocation.cy, x, y); 1333 TRACE_EXIT(); 1334 } 1523 1335 1524 1336 static void VBOXFreeScreen(ScrnInfoPtr pScrn) -
trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
r55250 r55262 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 … … 155 151 RTRECT2 aScreenLocation; 156 152 /** Is this CRTC enabled or in DPMS off state? */ 157 Bool fPowerOn; 153 Bool fCrtcEnabled; 154 /** Is this output enabled or in DPMS low power state? */ 155 Bool fOutputEnabled; 158 156 #ifdef VBOXVIDEO_13 159 157 /** The virtual crtcs. */ … … 172 170 /** Has this screen been enabled by the host? */ 173 171 Bool afConnected; 172 /** The last mode hint data read from the X11 property. */ 173 int32_t lastModeHintFromProperty; 174 174 /** Does this screen have a preferred location? */ 175 175 Bool afHaveLocation; … … 190 190 /** The size of the framebuffer and the VBVA buffers at the end of it. */ 191 191 unsigned long cbView; 192 /** The current line size in bytes */ 193 uint32_t cbLine; 192 194 /** Whether the pre-X-server mode was a VBE mode */ 193 195 bool fSavedVBEMode; … … 203 205 /** Do we currently want to use the host cursor? */ 204 206 Bool fUseHardwareCursor; 207 /** The last cursor capabilities data read from the X11 property. */ 208 int32_t fLastCursorCapabilitiesFromProperty; 205 209 /** Number of screens attached */ 206 210 uint32_t cScreens; 207 211 /** Information about each virtual screen. */ 208 212 struct VBoxScreen *pScreens; 213 /** The last requested framebuffer size. */ 214 RTRECTSIZE FBSize; 209 215 /** Can we get mode hint and cursor integration information from HGSMI? */ 210 216 bool fHaveHGSMIModeHints; … … 220 226 void *hACPIEventHandler; 221 227 # endif 228 /** Have we read all available HGSMI mode hint data? */ 229 bool fHaveReadHGSMIModeHintData; 230 #else 231 /** The original CreateScreenResources procedure which we wrap with our own. 232 */ 233 CreateScreenResourcesProcPtr pfnCreateScreenResources; 222 234 #endif 223 235 /** HGSMI guest heap context */ … … 263 275 }; 264 276 277 extern void vbvxSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth, unsigned cHeight, int x, int y, bool fEnabled, 278 bool fConnected, struct vbvxFrameBuffer *pFrameBuffer); 265 279 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 280 extern void vbvxSetSolarisMouseRange(int width, int height); 269 281 270 /* pointer.c */271 282 extern Bool vbox_cursor_init (ScreenPtr pScreen); 283 extern void vbox_open (ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox); 272 284 extern void vbox_close (ScrnInfoPtr pScrn, VBOXPtr pVBox); 273 285 274 /* vbva.c */275 extern void vbvxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects);276 extern void vbvxSetUpHGSMIHeapInGuest(VBOXPtr pVBox, uint32_t cbVRAM);277 286 extern Bool vboxEnableVbva(ScrnInfoPtr pScrn); 278 287 extern void vboxDisableVbva(ScrnInfoPtr pScrn); … … 281 290 extern void vboxAddModes(ScrnInfoPtr pScrn); 282 291 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); 292 extern void VBoxUpdateSizeHints(ScrnInfoPtr pScrn); 293 #ifndef VBOXVIDEO_13 294 extern void VBoxSetUpRandR11(ScreenPtr pScreen); 295 #else 296 void VBoxSetUpLinuxACPI(ScreenPtr pScreen); 297 void VBoxCleanUpLinuxACPI(ScreenPtr pScreen); 298 #endif 287 299 288 300 /* DRI stuff */ … … 293 305 extern void VBOXDRICloseScreen(ScreenPtr pScreen, VBOXPtr pVBox); 294 306 307 /* Utilities */ 308 309 /** Calculate the BPP from the screen depth */ 310 static inline uint16_t vboxBPP(ScrnInfoPtr pScrn) 311 { 312 return pScrn->depth == 24 ? 32 : 16; 313 } 314 315 /** Calculate the scan line length for a display width */ 316 static inline int32_t vboxLineLength(ScrnInfoPtr pScrn, int32_t cDisplayWidth) 317 { 318 uint32_t cbLine = (cDisplayWidth * vboxBPP(pScrn) / 8 + 3) & ~3; 319 return cbLine < INT32_MAX ? cbLine : INT32_MAX; 320 } 321 322 /** Calculate the display pitch from the scan line length */ 323 static inline int32_t vboxDisplayPitch(ScrnInfoPtr pScrn, int32_t cbLine) 324 { 325 return cbLine * 8 / vboxBPP(pScrn); 326 } 327 328 extern void vboxClearVRAM(ScrnInfoPtr pScrn, int32_t cNewX, int32_t cNewY); 329 extern Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth, 330 unsigned cHeight, int x, int y); 331 extern Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height); 332 295 333 #endif /* _VBOXVIDEO_H_ */ 296 334 -
trunk/src/VBox/Additions/x11/vboxvideo/vbva.c
r55250 r55262 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.