Changeset 35932 in vbox for trunk/src/VBox/Additions/x11
- Timestamp:
- Feb 10, 2011 5:10:00 PM (14 years ago)
- Location:
- trunk/src/VBox/Additions/x11/vboxvideo
- Files:
-
- 2 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
r35843 r35932 75 75 vboxutils.c \ 76 76 vboxvideo.c \ 77 vbva.c \ 77 78 $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp \ 78 79 $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp \ -
trunk/src/VBox/Additions/x11/vboxvideo/vboxutils.c
r35843 r35932 33 33 * Main functions * 34 34 **************************************************************************/ 35 36 /**37 * Callback function called by the X server to tell us about dirty38 * rectangles in the video buffer.39 *40 * @param pScreen pointer to the information structure for the current41 * screen42 * @param iRects Number of dirty rectangles to update43 * @param aRects Array of structures containing the coordinates of the44 * rectangles45 */46 static void47 vboxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects)48 {49 VBVACMDHDR cmdHdr;50 VBOXPtr pVBox;51 int i;52 unsigned j;53 54 pVBox = pScrn->driverPrivate;55 if (pVBox->fHaveHGSMI == FALSE || pVBox->vtSwitch)56 return;57 58 for (i = 0; i < iRects; ++i)59 for (j = 0; j < pVBox->cScreens; ++j)60 {61 /* Just continue quietly if VBVA is not currently active. */62 struct VBVABUFFER *pVBVA = pVBox->aVbvaCtx[j].pVBVA;63 if ( !pVBVA64 || !(pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))65 continue;66 if ( aRects[i].x1 > pVBox->aScreenLocation[j].x67 + pVBox->aScreenLocation[j].cx68 || aRects[i].y1 > pVBox->aScreenLocation[j].y69 + pVBox->aScreenLocation[j].cy70 || aRects[i].x2 < pVBox->aScreenLocation[j].x71 || aRects[i].y2 < pVBox->aScreenLocation[j].y)72 continue;73 cmdHdr.x = (int16_t)aRects[i].x1;74 cmdHdr.y = (int16_t)aRects[i].y1;75 cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1);76 cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1);77 78 #if 079 TRACE_LOG("display=%u, x=%d, y=%d, w=%d, h=%d\n",80 j, cmdHdr.x, cmdHdr.y, cmdHdr.w, cmdHdr.h);81 #endif82 83 if (VBoxVBVABufferBeginUpdate(&pVBox->aVbvaCtx[j],84 &pVBox->guestCtx))85 {86 VBoxVBVAWrite(&pVBox->aVbvaCtx[j], &pVBox->guestCtx, &cmdHdr,87 sizeof(cmdHdr));88 VBoxVBVABufferEndUpdate(&pVBox->aVbvaCtx[j]);89 }90 }91 }92 93 /** Callback to fill in the view structures */94 static int95 vboxFillViewInfo(void *pvVBox, struct VBVAINFOVIEW *pViews, uint32_t cViews)96 {97 VBOXPtr pVBox = (VBOXPtr)pvVBox;98 unsigned i;99 for (i = 0; i < cViews; ++i)100 {101 pViews[i].u32ViewIndex = i;102 pViews[i].u32ViewOffset = 0;103 pViews[i].u32ViewSize = pVBox->cbView;104 pViews[i].u32MaxScreenSize = pVBox->cbFBMax;105 }106 return VINF_SUCCESS;107 }108 109 /**110 * Initialise VirtualBox's accelerated video extensions.111 *112 * @returns TRUE on success, FALSE on failure113 */114 static Bool115 vboxInitVbva(int scrnIndex, ScreenPtr pScreen, VBOXPtr pVBox)116 {117 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];118 int rc = VINF_SUCCESS;119 120 pVBox->cScreens = 1;121 if (!VBoxHGSMIIsSupported())122 {123 xf86DrvMsg(scrnIndex, X_ERROR, "The graphics device does not seem to support HGSMI. Disableing video acceleration.\n");124 return FALSE;125 }126 127 /* Set up the dirty rectangle handler. It will be added into a function128 * chain and gets removed when the screen is cleaned up. */129 if (ShadowFBInit2(pScreen, NULL, vboxHandleDirtyRect) != TRUE)130 {131 xf86DrvMsg(scrnIndex, X_ERROR,132 "Unable to install dirty rectangle handler for VirtualBox graphics acceleration.\n");133 return FALSE;134 }135 return TRUE;136 }137 138 /**139 * Initialise VirtualBox's accelerated video extensions.140 *141 * @returns TRUE on success, FALSE on failure142 */143 static Bool144 vboxSetupVRAMVbva(ScrnInfoPtr pScrn, VBOXPtr pVBox)145 {146 int rc = VINF_SUCCESS;147 unsigned i;148 uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory;149 void *pvGuestHeapMemory;150 151 if (!pVBox->fHaveHGSMI)152 return FALSE;153 VBoxHGSMIGetBaseMappingInfo(pScrn->videoRam * 1024, &offVRAMBaseMapping,154 NULL, &offGuestHeapMemory, &cbGuestHeapMemory,155 NULL);156 pvGuestHeapMemory = ((uint8_t *)pVBox->base) + offVRAMBaseMapping157 + offGuestHeapMemory;158 TRACE_LOG("video RAM: %u KB, guest heap offset: 0x%x, cbGuestHeapMemory: %u\n",159 pScrn->videoRam, offVRAMBaseMapping + offGuestHeapMemory,160 cbGuestHeapMemory);161 rc = VBoxHGSMISetupGuestContext(&pVBox->guestCtx, pvGuestHeapMemory,162 cbGuestHeapMemory,163 offVRAMBaseMapping + offGuestHeapMemory);164 if (RT_FAILURE(rc))165 {166 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up the guest-to-host communication context, rc=%d\n", rc);167 return FALSE;168 }169 pVBox->cbView = pVBox->cbFBMax = offVRAMBaseMapping;170 pVBox->cScreens = VBoxHGSMIGetMonitorCount(&pVBox->guestCtx);171 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested monitor count: %u\n",172 pVBox->cScreens);173 for (i = 0; i < pVBox->cScreens; ++i)174 {175 pVBox->cbFBMax -= VBVA_MIN_BUFFER_SIZE;176 pVBox->aoffVBVABuffer[i] = pVBox->cbFBMax;177 TRACE_LOG("VBVA buffer offset for screen %u: 0x%lx\n", i,178 (unsigned long) pVBox->cbFBMax);179 VBoxVBVASetupBufferContext(&pVBox->aVbvaCtx[i],180 pVBox->aoffVBVABuffer[i],181 VBVA_MIN_BUFFER_SIZE);182 }183 TRACE_LOG("Maximum framebuffer size: %lu (0x%lx)\n",184 (unsigned long) pVBox->cbFBMax,185 (unsigned long) pVBox->cbFBMax);186 rc = VBoxHGSMISendViewInfo(&pVBox->guestCtx, pVBox->cScreens,187 vboxFillViewInfo, (void *)pVBox);188 if (RT_FAILURE(rc))189 {190 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to send the view information to the host, rc=%d\n", rc);191 return FALSE;192 }193 return TRUE;194 }195 196 Bool197 vbox_open(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox)198 {199 TRACE_ENTRY();200 201 pVBox->fHaveHGSMI = vboxInitVbva(pScrn->scrnIndex, pScreen, pVBox);202 return pVBox->fHaveHGSMI;203 }204 205 Bool206 vbox_device_available(VBOXPtr pVBox)207 {208 return pVBox->useDevice;209 }210 211 /**212 * Inform VBox that we will supply it with dirty rectangle information213 * and install the dirty rectangle handler.214 *215 * @returns TRUE for success, FALSE for failure216 * @param pScrn Pointer to a structure describing the X screen in use217 */218 Bool219 vboxEnableVbva(ScrnInfoPtr pScrn)220 {221 bool rc = TRUE;222 int scrnIndex = pScrn->scrnIndex;223 unsigned i;224 VBOXPtr pVBox = pScrn->driverPrivate;225 226 TRACE_ENTRY();227 if (!vboxSetupVRAMVbva(pScrn, pVBox))228 return FALSE;229 for (i = 0; i < pVBox->cScreens; ++i)230 {231 struct VBVABUFFER *pVBVA;232 233 pVBVA = (struct VBVABUFFER *) ( ((uint8_t *)pVBox->base)234 + pVBox->aoffVBVABuffer[i]);235 if (!VBoxVBVAEnable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, pVBVA, i))236 rc = FALSE;237 }238 if (!rc)239 {240 /* Request not accepted - disable for old hosts. */241 xf86DrvMsg(scrnIndex, X_ERROR,242 "Failed to enable screen update reporting for at least one virtual monitor.\n");243 vboxDisableVbva(pScrn);244 }245 return rc;246 }247 248 /**249 * Inform VBox that we will stop supplying it with dirty rectangle250 * information. This function is intended to be called when an X251 * virtual terminal is disabled, or the X server is terminated.252 *253 * @returns TRUE for success, FALSE for failure254 * @param pScrn Pointer to a structure describing the X screen in use255 */256 void257 vboxDisableVbva(ScrnInfoPtr pScrn)258 {259 int rc;260 int scrnIndex = pScrn->scrnIndex;261 unsigned i;262 VBOXPtr pVBox = pScrn->driverPrivate;263 264 TRACE_ENTRY();265 if (!pVBox->fHaveHGSMI) /* Ths function should not have been called */266 return;267 for (i = 0; i < pVBox->cScreens; ++i)268 VBoxVBVADisable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, i);269 }270 35 271 36 /** -
trunk/src/VBox/Additions/x11/vboxvideo/vbva.c
r35872 r35932 1 1 /** @file 2 * VirtualBox X11 Additions graphics driver utilityfunctions2 * VirtualBox X11 Additions graphics driver 2D acceleration functions 3 3 */ 4 4 … … 268 268 VBoxVBVADisable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, i); 269 269 } 270 271 /**272 * Inform VBox that we are aware of advanced graphics functions273 * (i.e. dynamic resizing, seamless).274 *275 * @returns TRUE for success, FALSE for failure276 */277 Bool278 vboxEnableGraphicsCap(VBOXPtr pVBox)279 {280 TRACE_ENTRY();281 if (!pVBox->useDevice)282 return FALSE;283 return RT_SUCCESS(VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0));284 }285 286 /**287 * Inform VBox that we are no longer aware of advanced graphics functions288 * (i.e. dynamic resizing, seamless).289 *290 * @returns TRUE for success, FALSE for failure291 */292 Bool293 vboxDisableGraphicsCap(VBOXPtr pVBox)294 {295 TRACE_ENTRY();296 if (!pVBox->useDevice)297 return FALSE;298 return RT_SUCCESS(VbglR3SetGuestCaps(0, VMMDEV_GUEST_SUPPORTS_GRAPHICS));299 }300 301 /**302 * Query the last display change request.303 *304 * @returns boolean success indicator.305 * @param pScrn Pointer to the X screen info structure.306 * @param pcx Where to store the horizontal pixel resolution (0 = do not change).307 * @param pcy Where to store the vertical pixel resolution (0 = do not change).308 * @param pcBits Where to store the bits per pixel (0 = do not change).309 * @param iDisplay Where to store the display number the request was for - 0 for the310 * primary display, 1 for the first secondary, etc.311 */312 Bool313 vboxGetDisplayChangeRequest(ScrnInfoPtr pScrn, uint32_t *pcx, uint32_t *pcy,314 uint32_t *pcBits, uint32_t *piDisplay)315 {316 VBOXPtr pVBox = pScrn->driverPrivate;317 TRACE_ENTRY();318 if (!pVBox->useDevice)319 return FALSE;320 int rc = VbglR3GetDisplayChangeRequest(pcx, pcy, pcBits, piDisplay, false);321 if (RT_SUCCESS(rc))322 return TRUE;323 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to obtain the last resolution requested by the guest, rc=%d.\n", rc);324 return FALSE;325 }326 327 328 /**329 * Query the host as to whether it likes a specific video mode.330 *331 * @returns the result of the query332 * @param cx the width of the mode being queried333 * @param cy the height of the mode being queried334 * @param cBits the bpp of the mode being queried335 */336 Bool337 vboxHostLikesVideoMode(ScrnInfoPtr pScrn, uint32_t cx, uint32_t cy, uint32_t cBits)338 {339 VBOXPtr pVBox = pScrn->driverPrivate;340 TRACE_ENTRY();341 if (!pVBox->useDevice)342 return TRUE; /* If we can't ask the host then we like everything. */343 return VbglR3HostLikesVideoMode(cx, cy, cBits);344 }345 346 /**347 * Check if any seamless mode is enabled.348 * Seamless is only relevant for the newer Xorg modules.349 *350 * @returns the result of the query351 * (true = seamless enabled, false = seamless not enabled)352 * @param pScrn Screen info pointer.353 */354 Bool355 vboxGuestIsSeamless(ScrnInfoPtr pScrn)356 {357 VMMDevSeamlessMode mode;358 VBOXPtr pVBox = pScrn->driverPrivate;359 TRACE_ENTRY();360 if (!pVBox->useDevice)361 return FALSE;362 if (RT_FAILURE(VbglR3SeamlessGetLastEvent(&mode)))363 return FALSE;364 return (mode != VMMDev_Seamless_Disabled);365 }366 367 /**368 * Save video mode parameters to the registry.369 *370 * @returns iprt status value371 * @param pszName the name to save the mode parameters under372 * @param cx mode width373 * @param cy mode height374 * @param cBits bits per pixel for the mode375 */376 Bool377 vboxSaveVideoMode(ScrnInfoPtr pScrn, uint32_t cx, uint32_t cy, uint32_t cBits)378 {379 VBOXPtr pVBox = pScrn->driverPrivate;380 TRACE_ENTRY();381 if (!pVBox->useDevice)382 return FALSE;383 return RT_SUCCESS(VbglR3SaveVideoMode("SavedMode", cx, cy, cBits));384 }385 386 /**387 * Retrieve video mode parameters from the registry.388 *389 * @returns iprt status value390 * @param pszName the name under which the mode parameters are saved391 * @param pcx where to store the mode width392 * @param pcy where to store the mode height393 * @param pcBits where to store the bits per pixel for the mode394 */395 Bool396 vboxRetrieveVideoMode(ScrnInfoPtr pScrn, uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits)397 {398 VBOXPtr pVBox = pScrn->driverPrivate;399 TRACE_ENTRY();400 if (!pVBox->useDevice)401 return FALSE;402 int rc = VbglR3RetrieveVideoMode("SavedMode", pcx, pcy, pcBits);403 if (RT_SUCCESS(rc))404 TRACE_LOG("Retrieved a video mode of %dx%dx%d\n", *pcx, *pcy, *pcBits);405 else406 TRACE_LOG("Failed to retrieve video mode, error %d\n", rc);407 return (RT_SUCCESS(rc));408 }409 410 /**411 * Fills a display mode M with a built-in mode of name pszName and dimensions412 * cx and cy.413 */414 static void vboxFillDisplayMode(ScrnInfoPtr pScrn, DisplayModePtr m,415 const char *pszName, unsigned cx, unsigned cy)416 {417 VBOXPtr pVBox = pScrn->driverPrivate;418 TRACE_LOG("pszName=%s, cx=%u, cy=%u\n", pszName, cx, cy);419 m->status = MODE_OK;420 m->type = M_T_BUILTIN;421 /* Older versions of VBox only support screen widths which are a multiple422 * of 8 */423 if (pVBox->fAnyX)424 m->HDisplay = cx;425 else426 m->HDisplay = cx & ~7;427 m->HSyncStart = m->HDisplay + 2;428 m->HSyncEnd = m->HDisplay + 4;429 m->HTotal = m->HDisplay + 6;430 m->VDisplay = cy;431 m->VSyncStart = m->VDisplay + 2;432 m->VSyncEnd = m->VDisplay + 4;433 m->VTotal = m->VDisplay + 6;434 m->Clock = m->HTotal * m->VTotal * 60 / 1000; /* kHz */435 if (pszName)436 {437 if (m->name)438 free(m->name);439 m->name = xnfstrdup(pszName);440 }441 }442 443 /** vboxvideo's list of standard video modes */444 struct445 {446 /** mode width */447 uint32_t cx;448 /** mode height */449 uint32_t cy;450 } vboxStandardModes[] =451 {452 { 1600, 1200 },453 { 1440, 1050 },454 { 1280, 960 },455 { 1024, 768 },456 { 800, 600 },457 { 640, 480 },458 { 0, 0 }459 };460 enum461 {462 vboxNumStdModes = sizeof(vboxStandardModes) / sizeof(vboxStandardModes[0])463 };464 465 /**466 * Returns a standard mode which the host likes. Can be called multiple467 * times with the index returned by the previous call to get a list of modes.468 * @returns the index of the mode in the list, or 0 if no more modes are469 * available470 * @param pScrn the screen information structure471 * @param pScrn->bitsPerPixel472 * if this is non-null, only modes with this BPP will be473 * returned474 * @param cIndex the index of the last mode queried, or 0 to query the475 * first mode available. Note: the first index is 1476 * @param pcx where to store the mode's width477 * @param pcy where to store the mode's height478 * @param pcBits where to store the mode's BPP479 */480 unsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex,481 uint32_t *pcx, uint32_t *pcy,482 uint32_t *pcBits)483 {484 XF86ASSERT(cIndex < vboxNumStdModes,485 ("cIndex = %d, vboxNumStdModes = %d\n", cIndex,486 vboxNumStdModes));487 for (unsigned i = cIndex; i < vboxNumStdModes - 1; ++i)488 {489 uint32_t cBits = pScrn->bitsPerPixel;490 uint32_t cx = vboxStandardModes[i].cx;491 uint32_t cy = vboxStandardModes[i].cy;492 493 if (cBits != 0 && !vboxHostLikesVideoMode(pScrn, cx, cy, cBits))494 continue;495 if (vboxHostLikesVideoMode(pScrn, cx, cy, 32))496 cBits = 32;497 else if (vboxHostLikesVideoMode(pScrn, cx, cy, 16))498 cBits = 16;499 else500 continue;501 if (pcx)502 *pcx = cx;503 if (pcy)504 *pcy = cy;505 if (pcBits)506 *pcBits = cBits;507 return i + 1;508 }509 return 0;510 }511 512 /**513 * Returns the preferred video mode. The current order of preference is514 * (from highest to least preferred):515 * - The mode corresponding to the last size hint from the host516 * - The video mode saved from the last session517 * - The largest standard mode which the host likes, falling back to518 * 640x480x32 as a worst case519 * - If the host can't be contacted at all, we return 1024x768x32520 *521 * The return type is void as we guarantee we will return some mode.522 */523 void vboxGetPreferredMode(ScrnInfoPtr pScrn, uint32_t iScreen, uint32_t *pcx,524 uint32_t *pcy, uint32_t *pcBits)525 {526 /* Query the host for the preferred resolution and colour depth */527 uint32_t cx = 0, cy = 0, iScreenIn = iScreen, cBits = 32;528 VBOXPtr pVBox = pScrn->driverPrivate;529 530 TRACE_LOG("iScreen=%u\n", iScreen);531 bool found = false;532 if ( pVBox->aPreferredSize[iScreen].cx533 && pVBox->aPreferredSize[iScreen].cy)534 {535 cx = pVBox->aPreferredSize[iScreen].cx;536 cy = pVBox->aPreferredSize[iScreen].cy;537 found = true;538 }539 if (pVBox->useDevice)540 {541 if (!found)542 found = vboxGetDisplayChangeRequest(pScrn, &cx, &cy, &cBits,543 &iScreenIn);544 if ((cx == 0) || (cy == 0) || iScreenIn != iScreen)545 found = false;546 if (!found)547 found = vboxRetrieveVideoMode(pScrn, &cx, &cy, &cBits);548 if ((cx == 0) || (cy == 0))549 found = false;550 if (!found)551 found = (vboxNextStandardMode(pScrn, 0, &cx, &cy, &cBits) != 0);552 if (!found)553 {554 /* Last resort */555 cx = 640;556 cy = 480;557 cBits = 32;558 }559 }560 else561 {562 cx = 1024;563 cy = 768;564 }565 if (pcx)566 *pcx = cx;567 if (pcy)568 *pcy = cy;569 if (pcBits)570 *pcBits = cBits;571 TRACE_LOG("cx=%u, cy=%u, cBits=%u\n", cx, cy, cBits);572 }573 574 /* Move a screen mode found to the end of the list, so that RandR will give575 * it the highest priority when a mode switch is requested. Returns the mode576 * that was previously before the mode in the list in order to allow the577 * caller to continue walking the list. */578 static DisplayModePtr vboxMoveModeToFront(ScrnInfoPtr pScrn,579 DisplayModePtr pMode)580 {581 DisplayModePtr pPrev = pMode->prev;582 if (pMode != pScrn->modes)583 {584 pMode->prev->next = pMode->next;585 pMode->next->prev = pMode->prev;586 pMode->next = pScrn->modes;587 pMode->prev = pScrn->modes->prev;588 pMode->next->prev = pMode;589 pMode->prev->next = pMode;590 pScrn->modes = pMode;591 }592 return pPrev;593 }594 595 /**596 * Rewrites the first dynamic mode found which is not the current screen mode597 * to contain the host's currently preferred screen size, then moves that598 * mode to the front of the screen information structure's mode list.599 * Additionally, if the current mode is not dynamic, the second dynamic mode600 * will be set to match the current mode and also added to the front. This601 * ensures that the user can always reset the current size to kick the driver602 * to update its mode list.603 */604 void vboxWriteHostModes(ScrnInfoPtr pScrn, DisplayModePtr pCurrent)605 {606 uint32_t cx = 0, cy = 0, iDisplay = 0, cBits = 0;607 DisplayModePtr pMode;608 bool found = false;609 610 TRACE_ENTRY();611 vboxGetPreferredMode(pScrn, 0, &cx, &cy, &cBits);612 #ifdef DEBUG613 /* Count the number of modes for sanity */614 unsigned cModes = 1, cMode = 0;615 DisplayModePtr pCount;616 for (pCount = pScrn->modes; ; pCount = pCount->next, ++cModes)617 if (pCount->next == pScrn->modes)618 break;619 #endif620 for (pMode = pScrn->modes; ; pMode = pMode->next)621 {622 #ifdef DEBUG623 XF86ASSERT (cMode++ < cModes, (NULL));624 #endif625 if ( pMode != pCurrent626 && !strcmp(pMode->name, "VBoxDynamicMode"))627 {628 if (!found)629 vboxFillDisplayMode(pScrn, pMode, NULL, cx, cy);630 else if (pCurrent)631 vboxFillDisplayMode(pScrn, pMode, NULL, pCurrent->HDisplay,632 pCurrent->VDisplay);633 found = true;634 pMode = vboxMoveModeToFront(pScrn, pMode);635 }636 if (pMode->next == pScrn->modes)637 break;638 }639 XF86ASSERT (found,640 ("vboxvideo: no free dynamic mode found. Exiting.\n"));641 XF86ASSERT ( (pScrn->modes->HDisplay == (long) cx)642 || ( (pScrn->modes->HDisplay == pCurrent->HDisplay)643 && (pScrn->modes->next->HDisplay == (long) cx)),644 ("pScrn->modes->HDisplay=%u, pScrn->modes->next->HDisplay=%u\n",645 pScrn->modes->HDisplay, pScrn->modes->next->HDisplay));646 XF86ASSERT ( (pScrn->modes->VDisplay == (long) cy)647 || ( (pScrn->modes->VDisplay == pCurrent->VDisplay)648 && (pScrn->modes->next->VDisplay == (long) cy)),649 ("pScrn->modes->VDisplay=%u, pScrn->modes->next->VDisplay=%u\n",650 pScrn->modes->VDisplay, pScrn->modes->next->VDisplay));651 }652 653 /**654 * Allocates an empty display mode and links it into the doubly linked list of655 * modes pointed to by pScrn->modes. Returns a pointer to the newly allocated656 * memory.657 */658 static DisplayModePtr vboxAddEmptyScreenMode(ScrnInfoPtr pScrn)659 {660 DisplayModePtr pMode = xnfcalloc(sizeof(DisplayModeRec), 1);661 662 TRACE_ENTRY();663 if (!pScrn->modes)664 {665 pScrn->modes = pMode;666 pMode->next = pMode;667 pMode->prev = pMode;668 }669 else670 {671 pMode->next = pScrn->modes;672 pMode->prev = pScrn->modes->prev;673 pMode->next->prev = pMode;674 pMode->prev->next = pMode;675 }676 return pMode;677 }678 679 /**680 * Create display mode entries in the screen information structure for each681 * of the initial graphics modes that we wish to support. This includes:682 * - An initial mode, of the size requested by the caller683 * - Two dynamic modes, one of which will be updated to match the last size684 * hint from the host on each mode switch, but initially also of the685 * requested size686 * - Several standard modes, if possible ones that the host likes687 * - Any modes that the user requested in xorg.conf/XFree86Config688 */689 void vboxAddModes(ScrnInfoPtr pScrn, uint32_t cxInit, uint32_t cyInit)690 {691 unsigned cx = 0, cy = 0, cIndex = 0;692 /* For reasons related to the way RandR 1.1 is implemented, we need to693 * make sure that the initial mode (more precisely, a mode equal to the694 * initial virtual resolution) is always present in the mode list. RandR695 * has the assumption build in that there will either be a mode of that696 * size present at all times, or that the first mode in the list will697 * always be smaller than the initial virtual resolution. Since our698 * approach to dynamic resizing isn't quite the way RandR was intended to699 * be, and breaks the second assumption, we guarantee the first. */700 DisplayModePtr pMode = vboxAddEmptyScreenMode(pScrn);701 vboxFillDisplayMode(pScrn, pMode, "VBoxInitialMode", cxInit, cyInit);702 /* Create our two dynamic modes. */703 pMode = vboxAddEmptyScreenMode(pScrn);704 vboxFillDisplayMode(pScrn, pMode, "VBoxDynamicMode", cxInit, cyInit);705 pMode = vboxAddEmptyScreenMode(pScrn);706 vboxFillDisplayMode(pScrn, pMode, "VBoxDynamicMode", cxInit, cyInit);707 /* Add standard modes supported by the host */708 for ( ; ; )709 {710 char szName[256];711 cIndex = vboxNextStandardMode(pScrn, cIndex, &cx, &cy, NULL);712 if (cIndex == 0)713 break;714 sprintf(szName, "VBox-%ux%u", cx, cy);715 pMode = vboxAddEmptyScreenMode(pScrn);716 vboxFillDisplayMode(pScrn, pMode, szName, cx, cy);717 }718 /* And finally any modes specified by the user. We assume here that719 * the mode names reflect the mode sizes. */720 for (unsigned i = 0; pScrn->display->modes != NULL721 && pScrn->display->modes[i] != NULL; i++)722 {723 if (sscanf(pScrn->display->modes[i], "%ux%u", &cx, &cy) == 2)724 {725 pMode = vboxAddEmptyScreenMode(pScrn);726 vboxFillDisplayMode(pScrn, pMode, pScrn->display->modes[i], cx, cy);727 }728 }729 }
Note:
See TracChangeset
for help on using the changeset viewer.