Changeset 55390 in vbox
- Timestamp:
- Apr 22, 2015 7:23:02 PM (10 years ago)
- Location:
- trunk/src/VBox/Additions/x11
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/undefined_xorg
r55332 r55390 106 106 __register_frame_info_bases 107 107 rename 108 RRChangeOutputProperty109 108 RRCrtcNotify 110 109 RRGetInfo -
trunk/src/VBox/Additions/x11/vboxvideo/getmode.c
r55384 r55390 23 23 24 24 #include "xf86.h" 25 #include "dixstruct.h"26 #ifdef VBOX_GUESTR3XF86MOD27 # define EXTENSION_PROC_ARGS char *name, GCPtr pGC28 #endif29 #include "extnsionst.h"30 #include "windowstr.h"31 #include <X11/extensions/randrproto.h>32 25 33 26 #ifdef XORG_7X … … 38 31 #ifdef VBOXVIDEO_13 39 32 # ifdef RT_OS_LINUX 40 # include "randrstr.h"41 # include "xf86_OSproc.h"42 33 # include <linux/input.h> 43 34 # ifndef EVIOCGRAB … … 53 44 # endif /* RT_OS_LINUX */ 54 45 #endif /* VBOXVIDEO_13 */ 46 55 47 /************************************************************************** 56 48 * Main functions * … … 155 147 } 156 148 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. */ 149 /** Set the initial values for the guest screen size hints to standard values 150 * in case nothing else is available. */ 160 151 void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn) 161 152 { … … 173 164 pScrn->modes->HDisplay = pVBox->pScreens[0].aPreferredSize.cx; 174 165 pScrn->modes->VDisplay = pVBox->pScreens[0].aPreferredSize.cy; 175 /* RandR 1.1 quirk: make sure that the initial resolution is always present176 * in the mode list as RandR will always advertise a mode of the initial177 * 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 else189 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 the196 * guest screens. A client application sets the hint information as a root197 * 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_SUCCESS212 || cDummy != 1)213 pfCursorCapabilities = NULL;214 #ifdef VBOXVIDEO_13215 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 else236 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 #endif243 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 else251 {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);266 166 } 267 167 … … 397 297 #undef COMPARE_AND_MAYBE_SET 398 298 399 #ifndef VBOXVIDEO_13400 401 /** The RandR "proc" vector, which we wrap with our own in order to notice402 * 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 support474 * swapped byte order clients. I doubt this is a big issue. */475 || !SwappedProcVector[pExt->base]476 #endif477 )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 #endif486 return TRUE;487 }488 489 /** Install our private RandR hook procedure, so that we can detect490 * GetScreenInfo requests from clients to update our dynamic mode. This works491 * by installing a wrapper around CreateScreenResources(), which will be called492 * 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 RandR494 * 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 hint497 * arrives we update the first of the two which is not the current mode with498 * the new size.499 * * RandR 1.1 always advertises a mode of the size of the initial virtual500 * resolution via GetScreenInfo(), so we make sure that a mode of that size501 * is always present in the list.502 * * RandR adds each new mode it sees to an internal array, but never removes503 * entries. This array might end up getting rather long given that we can504 * 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 518 299 #ifdef VBOXVIDEO_13 519 300 # ifdef RT_OS_LINUX 520 301 /* 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. */ 302 /** We have this for two purposes: one is to ensure that the X server is woken 303 * up when we get a video ACPI event. Two is to grab ACPI video events to 304 * prevent gnome-settings-daemon from seeing them, as older versions ignored 305 * the time stamp and handled them at the wrong time. */ 522 306 static void acpiEventHandler(int fd, void *pvData) 523 307 { -
trunk/src/VBox/Additions/x11/vboxvideo/setmode.c
r55262 r55390 91 91 } 92 92 93 /** Clear the virtual framebuffer in VRAM. Optionally also clear up to the94 * size of a new framebuffer. Framebuffer sizes larger than available VRAM95 * 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));108 }109 110 93 /** Set a graphics mode. Poke any required values into registers, do an HGSMI 111 94 * mode set and tell the host we support advanced graphics functions. … … 140 123 } 141 124 142 /** Set a graphics mode. Poke any required values into registers, do an HGSMI143 * mode set and tell the host we support advanced graphics functions. This144 * procedure is complicated by the fact that X.Org can implicitly disable a145 * screen by resizing the virtual framebuffer so that the screen is no longer146 * 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 - is161 * too large for VRAM as we sometimes have to do this - see comments in162 * VBOXPreInit. */163 if ( offStart + pVBox->cbLine * cHeight > pVBox->cbFBMax164 || pVBox->cbLine * pScrn->virtualY > pVBox->cbFBMax)165 return FALSE;166 /* Deactivate the screen if it is outside of the virtual framebuffer and167 * clamp it to lie inside if it is partly outside. */168 if (x >= pScrn->displayWidth || x + (int) cWidth <= 0)169 return FALSE;170 else171 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].fCrtcEnabled179 && pVBox->pScreens[cDisplay].fOutputEnabled;180 fFlags = VBVA_SCREEN_F_ACTIVE;181 fFlags |= (pVBox->pScreens[cDisplay].afConnected ? 0182 : 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 modes197 * (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->virtualX210 && height == pScrn->virtualY211 && 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_OLD234 if (pVBox->useDRI)235 VBOXDRIUpdateStride(pScrn, pVBox);236 #endif237 #ifdef VBOXVIDEO_13238 /* 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 #else249 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 #endif254 vbvxSetSolarisMouseRange(width, height);255 return TRUE;256 }257 258 125 /** Tell the virtual mouse device about the new virtual desktop size. */ 259 126 void vbvxSetSolarisMouseRange(int width, int height) -
trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
r55376 r55390 156 156 /** Is this CRTC enabled or in DPMS off state? */ 157 157 Bool fPowerOn; 158 /** Is this CRTC enabled or in DPMS off state? */159 Bool fCrtcEnabled;160 /** Is this output enabled or in DPMS low power state? */161 Bool fOutputEnabled;162 158 #ifdef VBOXVIDEO_13 163 159 /** The virtual crtcs. */ … … 176 172 /** Has this screen been enabled by the host? */ 177 173 Bool afConnected; 178 /** The last mode hint data read from the X11 property. */179 int32_t lastModeHintFromProperty;180 174 /** Does this screen have a preferred location? */ 181 175 Bool afHaveLocation; … … 211 205 /** Do we currently want to use the host cursor? */ 212 206 Bool fUseHardwareCursor; 213 /** The last cursor capabilities data read from the X11 property. */214 int32_t fLastCursorCapabilitiesFromProperty;215 207 /** Number of screens attached */ 216 208 uint32_t cScreens; 217 209 /** Information about each virtual screen. */ 218 210 struct VBoxScreen *pScreens; 219 /** The last requested framebuffer size. */220 RTRECTSIZE FBSize;221 211 /** Can we get mode hint and cursor integration information from HGSMI? */ 222 212 bool fHaveHGSMIModeHints; … … 232 222 void *hACPIEventHandler; 233 223 # endif 234 /** Have we read all available HGSMI mode hint data? */235 bool fHaveReadHGSMIModeHintData;236 #else237 /** The original CreateScreenResources procedure which we wrap with our own.238 */239 CreateScreenResourcesProcPtr pfnCreateScreenResources;240 224 #endif 241 225 /** HGSMI guest heap context */ … … 283 267 extern void vbvxClearVRAM(ScrnInfoPtr pScrn, size_t cbOldSize, size_t cbNewSize); 284 268 extern void vbvxSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth, unsigned cHeight, int x, int y, bool fEnabled, 285 269 bool fConnected, struct vbvxFrameBuffer *pFrameBuffer); 286 270 extern void vbvxSetSolarisMouseRange(int width, int height); 287 271 … … 298 282 extern void vboxAddModes(ScrnInfoPtr pScrn); 299 283 extern void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn); 300 extern void VBoxUpdateSizeHints(ScrnInfoPtr pScrn);301 #ifndef VBOXVIDEO_13302 extern void VBoxSetUpRandR11(ScreenPtr pScreen);303 #endif304 284 extern void vbvxReadSizesAndCursorIntegrationFromProperties(ScrnInfoPtr pScrn, bool *pfNeedUpdate); 305 285 extern void vbvxReadSizesAndCursorIntegrationFromHGSMI(ScrnInfoPtr pScrn, bool *pfNeedUpdate); … … 335 315 } 336 316 337 extern void vboxClearVRAM(ScrnInfoPtr pScrn, int32_t cNewX, int32_t cNewY);338 extern Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,339 unsigned cHeight, int x, int y);340 extern Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height);341 342 317 #endif /* _VBOXVIDEO_H_ */ 343 318 -
trunk/src/VBox/Additions/x11/vboxvideo/vbva.c
r55384 r55390 18 18 #include <VBox/VBoxGuestLib.h> 19 19 20 #ifndef PCIACCESS21 # include <xf86Pci.h>22 # include <Pci.h>23 #endif24 25 #include "xf86.h"26 #define NEED_XF86_TYPES27 20 #include <iprt/string.h> 28 21 #include "compiler.h" 29 30 /* ShadowFB support */31 #include "shadowfb.h"32 22 33 23 #include "vboxvideo.h"
Note:
See TracChangeset
for help on using the changeset viewer.