Changeset 51242 in vbox
- Timestamp:
- May 13, 2014 2:07:00 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 93679
- Location:
- trunk/src/VBox/Additions/x11/vboxvideo
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/vboxvideo/pointer.c
r50900 r51242 447 447 ) 448 448 rc = FALSE; 449 #ifndef VBOXVIDEO_13450 /* Evil hack - we use this as another way of poking the driver to update451 * our list of video modes. */452 vboxWriteHostModes(pScrn, pScrn->currentMode);453 #endif454 449 return rc; 455 450 } -
trunk/src/VBox/Additions/x11/vboxvideo/undefined
r50981 r51242 1 1 ChangeWindowProperty 2 CheckExtension 2 3 DRI2CloseScreen 3 4 DRI2ScreenInit … … 15 16 GlxSetVisualConfigs 16 17 LoaderRefSymLists 18 LookupWindow 17 19 MakeAtom 18 20 PixmapWidthPaddingInfo 21 ProcVector 19 22 RRChangeOutputProperty 23 SecurityLookupWindow 24 SwappedProcVector 20 25 ShadowFBInit2 21 26 VErrorF -
trunk/src/VBox/Additions/x11/vboxvideo/vboxutils.c
r46042 r51242 16 16 */ 17 17 18 #include <VBox/VMMDev.h> 19 #include <VBox/VBoxGuestLib.h> 20 21 #ifndef PCIACCESS 22 # include <xf86Pci.h> 23 # include <Pci.h> 24 #endif 25 26 #include "xf86.h" 18 #include "vboxvideo.h" 19 27 20 #define NEED_XF86_TYPES 28 21 #include <iprt/string.h> 29 #include "compiler.h" 30 31 #include "vboxvideo.h" 22 23 #include "xf86.h" 24 #include "dixstruct.h" 25 #include "extnsionst.h" 26 #include "windowstr.h" 27 #include <X11/extensions/randrproto.h> 28 #include <X11/Xatom.h> 32 29 33 30 #ifdef XORG_7X … … 41 38 42 39 /** 43 * Inform VBox that we are aware of advanced graphics functions44 * (i.e. dynamic resizing, seamless).45 *46 * @returns TRUE for success, FALSE for failure47 */48 Bool49 vboxEnableGraphicsCap(VBOXPtr pVBox)50 {51 TRACE_ENTRY();52 if (!pVBox->useDevice)53 return FALSE;54 return RT_SUCCESS(VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0));55 }56 57 /**58 * Inform VBox that we are no longer aware of advanced graphics functions59 * (i.e. dynamic resizing, seamless).60 *61 * @returns TRUE for success, FALSE for failure62 */63 Bool64 vboxDisableGraphicsCap(VBOXPtr pVBox)65 {66 TRACE_ENTRY();67 if (!pVBox->useDevice)68 return FALSE;69 return RT_SUCCESS(VbglR3SetGuestCaps(0, VMMDEV_GUEST_SUPPORTS_GRAPHICS));70 }71 72 /**73 * Query the last display change request.74 *75 * @returns boolean success indicator.76 * @param pScrn Pointer to the X screen info structure.77 * @param pcx Where to store the horizontal pixel resolution (0 = do not change).78 * @param pcy Where to store the vertical pixel resolution (0 = do not change).79 * @param pcBits Where to store the bits per pixel (0 = do not change).80 * @param iDisplay Where to store the display number the request was for - 0 for the81 * primary display, 1 for the first secondary, etc.82 */83 Bool84 vboxGetDisplayChangeRequest(ScrnInfoPtr pScrn, uint32_t *pcx, uint32_t *pcy,85 uint32_t *pcBits, uint32_t *piDisplay)86 {87 VBOXPtr pVBox = pScrn->driverPrivate;88 TRACE_ENTRY();89 if (!pVBox->useDevice)90 return FALSE;91 int rc = VbglR3GetDisplayChangeRequest(pcx, pcy, pcBits, piDisplay, false);92 if (RT_SUCCESS(rc))93 return TRUE;94 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to obtain the last resolution requested by the guest, rc=%d.\n", rc);95 return FALSE;96 }97 98 99 /**100 * Query the host as to whether it likes a specific video mode.101 *102 * @returns the result of the query103 * @param cx the width of the mode being queried104 * @param cy the height of the mode being queried105 * @param cBits the bpp of the mode being queried106 */107 Bool108 vboxHostLikesVideoMode(ScrnInfoPtr pScrn, uint32_t cx, uint32_t cy, uint32_t cBits)109 {110 VBOXPtr pVBox = pScrn->driverPrivate;111 TRACE_ENTRY();112 if (!pVBox->useDevice)113 return TRUE; /* If we can't ask the host then we like everything. */114 return VbglR3HostLikesVideoMode(cx, cy, cBits);115 }116 117 /**118 * Check if any seamless mode is enabled.119 * Seamless is only relevant for the newer Xorg modules.120 *121 * @returns the result of the query122 * (true = seamless enabled, false = seamless not enabled)123 * @param pScrn Screen info pointer.124 */125 Bool126 vboxGuestIsSeamless(ScrnInfoPtr pScrn)127 {128 VMMDevSeamlessMode mode;129 VBOXPtr pVBox = pScrn->driverPrivate;130 TRACE_ENTRY();131 if (!pVBox->useDevice)132 return FALSE;133 if (RT_FAILURE(VbglR3SeamlessGetLastEvent(&mode)))134 return FALSE;135 return (mode != VMMDev_Seamless_Disabled);136 }137 138 /**139 * Save video mode parameters to the registry.140 *141 * @returns iprt status value142 * @param pszName the name to save the mode parameters under143 * @param cx mode width144 * @param cy mode height145 * @param cBits bits per pixel for the mode146 */147 Bool148 vboxSaveVideoMode(ScrnInfoPtr pScrn, uint32_t cx, uint32_t cy, uint32_t cBits)149 {150 VBOXPtr pVBox = pScrn->driverPrivate;151 TRACE_ENTRY();152 if (!pVBox->useDevice)153 return FALSE;154 return RT_SUCCESS(VbglR3SaveVideoMode("SavedMode", cx, cy, cBits));155 }156 157 /**158 * Retrieve video mode parameters from the registry.159 *160 * @returns iprt status value161 * @param pszName the name under which the mode parameters are saved162 * @param pcx where to store the mode width163 * @param pcy where to store the mode height164 * @param pcBits where to store the bits per pixel for the mode165 */166 Bool167 vboxRetrieveVideoMode(ScrnInfoPtr pScrn, uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits)168 {169 VBOXPtr pVBox = pScrn->driverPrivate;170 int rc;171 TRACE_ENTRY();172 if (!pVBox->useDevice)173 rc = VERR_NOT_AVAILABLE;174 else175 rc = VbglR3RetrieveVideoMode("SavedMode", pcx, pcy, pcBits);176 if (RT_SUCCESS(rc))177 TRACE_LOG("Retrieved a video mode of %dx%dx%d\n", *pcx, *pcy, *pcBits);178 else179 TRACE_LOG("Failed to retrieve video mode, error %d\n", rc);180 return (RT_SUCCESS(rc));181 }182 183 /**184 40 * Fills a display mode M with a built-in mode of name pszName and dimensions 185 41 * cx and cy. … … 189 45 { 190 46 VBOXPtr pVBox = pScrn->driverPrivate; 47 char szName[256]; 48 DisplayModePtr pPrev = m->prev; 49 DisplayModePtr pNext = m->next; 50 51 if (!pszName) 52 { 53 sprintf(szName, "%ux%u", cx, cy); 54 pszName = szName; 55 } 191 56 TRACE_LOG("pszName=%s, cx=%u, cy=%u\n", pszName, cx, cy); 57 if (m->name) 58 free(m->name); 59 memset(m, '\0', sizeof(*m)); 60 m->prev = pPrev; 61 m->next = pNext; 192 62 m->status = MODE_OK; 193 63 m->type = M_T_BUILTIN; … … 206 76 m->VTotal = m->VDisplay + 6; 207 77 m->Clock = m->HTotal * m->VTotal * 60 / 1000; /* kHz */ 208 if (pszName) 209 { 210 if (m->name) 211 free(m->name); 212 m->name = xnfstrdup(pszName); 213 } 78 m->name = xnfstrdup(pszName); 214 79 } 215 80 … … 252 117 */ 253 118 unsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex, 254 uint32_t *pcx, uint32_t *pcy, 255 uint32_t *pcBits) 119 uint32_t *pcx, uint32_t *pcy) 256 120 { 257 121 unsigned i; … … 262 126 for (i = cIndex; i < vboxNumStdModes - 1; ++i) 263 127 { 264 uint32_t cBits = pScrn->bitsPerPixel;265 128 uint32_t cx = vboxStandardModes[i].cx; 266 129 uint32_t cy = vboxStandardModes[i].cy; 267 130 268 if (cBits != 0 && !vboxHostLikesVideoMode(pScrn, cx, cy, cBits))269 continue;270 if (vboxHostLikesVideoMode(pScrn, cx, cy, 32))271 cBits = 32;272 else if (vboxHostLikesVideoMode(pScrn, cx, cy, 16))273 cBits = 16;274 else275 continue;276 131 if (pcx) 277 132 *pcx = cx; 278 133 if (pcy) 279 134 *pcy = cy; 280 if (pcBits)281 *pcBits = cBits;282 135 return i + 1; 283 136 } … … 286 139 287 140 /** 288 * Returns the preferred video mode. The current order of preference is 289 * (from highest to least preferred): 290 * - The mode corresponding to the last size hint from the host 291 * - The video mode saved from the last session 292 * - The largest standard mode which the host likes, falling back to 293 * 640x480x32 as a worst case 294 * - If the host can't be contacted at all, we return 1024x768x32 295 * 296 * The return type is void as we guarantee we will return some mode. 297 */ 298 void vboxGetPreferredMode(ScrnInfoPtr pScrn, uint32_t iScreen, uint32_t *pcx, 299 uint32_t *pcy, uint32_t *pcBits) 300 { 301 /* Query the host for the preferred resolution and colour depth */ 302 uint32_t cx = 0, cy = 0, iScreenIn = iScreen, cBits = 32; 303 VBOXPtr pVBox = pScrn->driverPrivate; 304 305 TRACE_LOG("iScreen=%u\n", iScreen); 306 bool found = false; 307 if ( pVBox->aPreferredSize[iScreen].cx 308 && pVBox->aPreferredSize[iScreen].cy) 309 { 310 cx = pVBox->aPreferredSize[iScreen].cx; 311 cy = pVBox->aPreferredSize[iScreen].cy; 312 found = true; 313 } 314 if (pVBox->useDevice) 315 { 316 if (!found) 317 found = vboxGetDisplayChangeRequest(pScrn, &cx, &cy, &cBits, 318 &iScreenIn); 319 if ((cx == 0) || (cy == 0) || iScreenIn != iScreen) 320 found = false; 321 if (!found) 322 found = vboxRetrieveVideoMode(pScrn, &cx, &cy, &cBits); 323 if ((cx == 0) || (cy == 0)) 324 found = false; 325 if (!found) 326 found = (vboxNextStandardMode(pScrn, 0, &cx, &cy, &cBits) != 0); 327 if (!found) 328 { 329 /* Last resort */ 330 cx = 640; 331 cy = 480; 332 cBits = 32; 333 } 141 * Allocates an empty display mode and links it into the doubly linked list of 142 * modes pointed to by pScrn->modes. Returns a pointer to the newly allocated 143 * memory. 144 */ 145 static DisplayModePtr vboxAddEmptyScreenMode(ScrnInfoPtr pScrn) 146 { 147 DisplayModePtr pMode = xnfcalloc(sizeof(DisplayModeRec), 1); 148 149 TRACE_ENTRY(); 150 if (!pScrn->modes) 151 { 152 pScrn->modes = pMode; 153 pMode->next = pMode; 154 pMode->prev = pMode; 334 155 } 335 156 else 336 157 { 337 cx = 1024;338 cy = 768;339 }340 if (pcx)341 *pcx = cx;342 if (pcy)343 *pcy = cy;344 if (pcBits)345 *pcBits = cBits;346 TRACE_LOG("cx=%u, cy=%u, cBits=%u\n", cx, cy, cBits);347 }348 349 /* Move a screen mode found to the end of the list, so that RandR will give350 * it the highest priority when a mode switch is requested. Returns the mode351 * that was previously before the mode in the list in order to allow the352 * caller to continue walking the list. */353 static DisplayModePtr vboxMoveModeToFront(ScrnInfoPtr pScrn,354 DisplayModePtr pMode)355 {356 DisplayModePtr pPrev = pMode->prev;357 if (pMode != pScrn->modes)358 {359 pMode->prev->next = pMode->next;360 pMode->next->prev = pMode->prev;361 158 pMode->next = pScrn->modes; 362 159 pMode->prev = pScrn->modes->prev; 363 160 pMode->next->prev = pMode; 364 161 pMode->prev->next = pMode; 365 pScrn->modes = pMode;366 }367 return pPrev;368 }369 370 /**371 * Rewrites the first dynamic mode found which is not the current screen mode372 * to contain the host's currently preferred screen size, then moves that373 * mode to the front of the screen information structure's mode list.374 * Additionally, if the current mode is not dynamic, the second dynamic mode375 * will be set to match the current mode and also added to the front. This376 * ensures that the user can always reset the current size to kick the driver377 * to update its mode list.378 */379 void vboxWriteHostModes(ScrnInfoPtr pScrn, DisplayModePtr pCurrent)380 {381 uint32_t cx = 0, cy = 0, iDisplay = 0, cBits = 0;382 DisplayModePtr pMode;383 bool found = false;384 385 TRACE_ENTRY();386 vboxGetPreferredMode(pScrn, 0, &cx, &cy, &cBits);387 #ifdef DEBUG388 /* Count the number of modes for sanity */389 unsigned cModes = 1, cMode = 0;390 DisplayModePtr pCount;391 for (pCount = pScrn->modes; ; pCount = pCount->next, ++cModes)392 if (pCount->next == pScrn->modes)393 break;394 #endif395 for (pMode = pScrn->modes; ; pMode = pMode->next)396 {397 #ifdef DEBUG398 XF86ASSERT (cMode++ < cModes, (NULL));399 #endif400 if ( pMode != pCurrent401 && !strcmp(pMode->name, "VBoxDynamicMode"))402 {403 if (!found)404 vboxFillDisplayMode(pScrn, pMode, NULL, cx, cy);405 else if (pCurrent)406 vboxFillDisplayMode(pScrn, pMode, NULL, pCurrent->HDisplay,407 pCurrent->VDisplay);408 found = true;409 pMode = vboxMoveModeToFront(pScrn, pMode);410 }411 if (pMode->next == pScrn->modes)412 break;413 }414 XF86ASSERT (found,415 ("vboxvideo: no free dynamic mode found. Exiting.\n"));416 XF86ASSERT ( (pScrn->modes->HDisplay == (long) cx)417 || ( (pScrn->modes->HDisplay == pCurrent->HDisplay)418 && (pScrn->modes->next->HDisplay == (long) cx)),419 ("pScrn->modes->HDisplay=%u, pScrn->modes->next->HDisplay=%u\n",420 pScrn->modes->HDisplay, pScrn->modes->next->HDisplay));421 XF86ASSERT ( (pScrn->modes->VDisplay == (long) cy)422 || ( (pScrn->modes->VDisplay == pCurrent->VDisplay)423 && (pScrn->modes->next->VDisplay == (long) cy)),424 ("pScrn->modes->VDisplay=%u, pScrn->modes->next->VDisplay=%u\n",425 pScrn->modes->VDisplay, pScrn->modes->next->VDisplay));426 }427 428 /**429 * Allocates an empty display mode and links it into the doubly linked list of430 * modes pointed to by pScrn->modes. Returns a pointer to the newly allocated431 * memory.432 */433 static DisplayModePtr vboxAddEmptyScreenMode(ScrnInfoPtr pScrn)434 {435 DisplayModePtr pMode = xnfcalloc(sizeof(DisplayModeRec), 1);436 437 TRACE_ENTRY();438 if (!pScrn->modes)439 {440 pScrn->modes = pMode;441 pMode->next = pMode;442 pMode->prev = pMode;443 }444 else445 {446 pMode->next = pScrn->modes;447 pMode->prev = pScrn->modes->prev;448 pMode->next->prev = pMode;449 pMode->prev->next = pMode;450 162 } 451 163 return pMode; … … 454 166 /** 455 167 * Create display mode entries in the screen information structure for each 456 * of the initial graphics modes that we wish to support. This includes: 457 * - An initial mode, of the size requested by the caller 458 * - Two dynamic modes, one of which will be updated to match the last size 459 * hint from the host on each mode switch, but initially also of the 460 * requested size 461 * - Several standard modes, if possible ones that the host likes 462 * - Any modes that the user requested in xorg.conf/XFree86Config 463 */ 464 void vboxAddModes(ScrnInfoPtr pScrn, uint32_t cxInit, uint32_t cyInit) 168 * of the graphics modes that we wish to support, that is: 169 * - A dynamic mode in first place which will be updated by the RandR code. 170 * - Several standard modes. 171 * - Any modes that the user requested in xorg.conf/XFree86Config. 172 */ 173 void vboxAddModes(ScrnInfoPtr pScrn) 465 174 { 466 175 unsigned cx = 0, cy = 0, cIndex = 0; 467 176 unsigned i; 468 /* For reasons related to the way RandR 1.1 is implemented, we need to 469 * make sure that the initial mode (more precisely, a mode equal to the 470 * initial virtual resolution) is always present in the mode list. RandR 471 * has the assumption build in that there will either be a mode of that 472 * size present at all times, or that the first mode in the list will 473 * always be smaller than the initial virtual resolution. Since our 474 * approach to dynamic resizing isn't quite the way RandR was intended to 475 * be, and breaks the second assumption, we guarantee the first. */ 476 DisplayModePtr pMode = vboxAddEmptyScreenMode(pScrn); 477 vboxFillDisplayMode(pScrn, pMode, "VBoxInitialMode", cxInit, cyInit); 478 /* Create our two dynamic modes. */ 177 DisplayModePtr pMode; 178 179 /* Add two dynamic mode entries. When we receive a new size hint we will 180 * update whichever of these is not current. */ 479 181 pMode = vboxAddEmptyScreenMode(pScrn); 480 vboxFillDisplayMode(pScrn, pMode, "VBoxDynamicMode", cxInit, cyInit);182 vboxFillDisplayMode(pScrn, pMode, NULL, 1024, 768); 481 183 pMode = vboxAddEmptyScreenMode(pScrn); 482 vboxFillDisplayMode(pScrn, pMode, "VBoxDynamicMode", cxInit, cyInit);184 vboxFillDisplayMode(pScrn, pMode, NULL, 1024, 768); 483 185 /* Add standard modes supported by the host */ 484 186 for ( ; ; ) 485 187 { 486 char szName[256]; 487 cIndex = vboxNextStandardMode(pScrn, cIndex, &cx, &cy, NULL); 188 cIndex = vboxNextStandardMode(pScrn, cIndex, &cx, &cy); 488 189 if (cIndex == 0) 489 190 break; 490 sprintf(szName, "VBox-%ux%u", cx, cy);491 191 pMode = vboxAddEmptyScreenMode(pScrn); 492 vboxFillDisplayMode(pScrn, pMode, szName, cx, cy);192 vboxFillDisplayMode(pScrn, pMode, NULL, cx, cy); 493 193 } 494 194 /* And finally any modes specified by the user. We assume here that … … 503 203 } 504 204 } 205 206 /** Set the initial values for the guest screen size hints by reading saved 207 * values from files. */ 208 /** @todo Actually read the files instead of setting dummies. */ 209 void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn) 210 { 211 VBOXPtr pVBox = VBOXGetRec(pScrn); 212 DisplayModePtr pMode; 213 unsigned i; 214 215 for (i = 0; i < pVBox->cScreens; ++i) 216 { 217 pVBox->aPreferredSize[i].cx = 1024; 218 pVBox->aPreferredSize[i].cy = 768; 219 } 220 /* Set up the first mode correctly to match the requested initial mode. */ 221 pScrn->modes->HDisplay = pVBox->aPreferredSize[0].cx; 222 pScrn->modes->VDisplay = pVBox->aPreferredSize[0].cy; 223 /* RandR 1.1 quirk: make sure that the initial resolution is always present 224 * in the mode list as RandR will always advertise a mode of the initial 225 * virtual resolution via GetScreenInfo. */ 226 pMode = vboxAddEmptyScreenMode(pScrn); 227 vboxFillDisplayMode(pScrn, pMode, NULL, pVBox->aPreferredSize[0].cx, 228 pVBox->aPreferredSize[0].cy); 229 } 230 231 # define SIZE_HINTS_PROPERTY "VBOX_SIZE_HINTS" 232 233 /** Read in information about the most recent size hints requested for the 234 * guest screens. A client application sets the hint information as a root 235 * window property. */ 236 void VBoxUpdateSizeHints(ScrnInfoPtr pScrn) 237 { 238 VBOXPtr pVBox = VBOXGetRec(pScrn); 239 Atom atom = MakeAtom(SIZE_HINTS_PROPERTY, sizeof(SIZE_HINTS_PROPERTY) - 1, 240 FALSE); 241 PropertyPtr prop = NULL; 242 unsigned i; 243 244 /* We can get called early, before the root window is created. */ 245 if (!ROOT_WINDOW(pScrn)) 246 return; 247 if (atom != BAD_RESOURCE) 248 { 249 for (prop = wUserProps(ROOT_WINDOW(pScrn)); 250 prop != NULL && prop->propertyName != atom; prop = prop->next); 251 } 252 if (prop && prop->type == XA_INTEGER && prop->format == 32) 253 for (i = 0; i < prop->size && i < pVBox->cScreens; ++i) 254 { 255 if (!((int32_t *)prop->data)[i]) 256 continue; 257 pVBox->aPreferredSize[i].cx = ((int32_t *)prop->data)[i] >> 16; 258 pVBox->aPreferredSize[i].cy = ((int32_t *)prop->data)[i] & 0xffff; 259 } 260 } 261 262 #ifndef VBOXVIDEO_13 263 264 /** The RandR "proc" vector, which we wrap with our own in order to notice 265 * when a client sends a GetScreenInfo request. */ 266 static int (*g_pfnVBoxRandRProc)(ClientPtr) = NULL; 267 /** The swapped RandR "proc" vector. */ 268 static int (*g_pfnVBoxRandRSwappedProc)(ClientPtr) = NULL; 269 270 static void vboxRandRDispatchCore(ClientPtr pClient) 271 { 272 xRRGetScreenInfoReq *pReq = (xRRGetScreenInfoReq *)pClient->requestBuffer; 273 WindowPtr pWin; 274 ScrnInfoPtr pScrn; 275 VBOXPtr pVBox; 276 DisplayModePtr pMode; 277 278 if (pClient->req_len != sizeof(xRRGetScreenInfoReq) >> 2) 279 return; 280 pWin = (WindowPtr)SecurityLookupWindow(pReq->window, pClient, 281 SecurityReadAccess); 282 if (!pWin) 283 return; 284 pScrn = xf86Screens[pWin->drawable.pScreen->myNum]; 285 pVBox = VBOXGetRec(pScrn); 286 VBoxUpdateSizeHints(pScrn); 287 pMode = pScrn->modes; 288 if (pScrn->currentMode == pMode) 289 pMode = pMode->next; 290 pMode->HDisplay = pVBox->aPreferredSize[0].cx; 291 pMode->VDisplay = pVBox->aPreferredSize[0].cy; 292 } 293 294 static int vboxRandRDispatch(ClientPtr pClient) 295 { 296 xReq *pReq = (xReq *)pClient->requestBuffer; 297 298 if (pReq->data == X_RRGetScreenInfo) 299 vboxRandRDispatchCore(pClient); 300 return g_pfnVBoxRandRProc(pClient); 301 } 302 303 static int vboxRandRSwappedDispatch(ClientPtr pClient) 304 { 305 xReq *pReq = (xReq *)pClient->requestBuffer; 306 307 if (pReq->data == X_RRGetScreenInfo) 308 vboxRandRDispatchCore(pClient); 309 return g_pfnVBoxRandRSwappedProc(pClient); 310 } 311 312 static Bool vboxRandRCreateScreenResources(ScreenPtr pScreen) 313 { 314 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 315 VBOXPtr pVBox = VBOXGetRec(pScrn); 316 ExtensionEntry *pExt; 317 318 pScreen->CreateScreenResources = pVBox->pfnCreateScreenResources; 319 if (!pScreen->CreateScreenResources(pScreen)) 320 return FALSE; 321 /* I doubt we can be loaded twice - should I fail here? */ 322 if (g_pfnVBoxRandRProc) 323 return TRUE; 324 pExt = CheckExtension(RANDR_NAME); 325 if (!pExt) 326 { 327 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 328 "RandR extension not found, disabling dynamic resizing.\n"); 329 return TRUE; 330 } 331 if ( !ProcVector[pExt->base] 332 #if !defined(XF86_VERSION_CURRENT) \ 333 || XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4, 3, 99, 0, 0) 334 /* SwappedProcVector is not exported in XFree86, so we will not support 335 * swapped byte order clients. I doubt this is a big issue. */ 336 || !SwappedProcVector[pExt->base] 337 #endif 338 ) 339 FatalError("RandR \"proc\" vector not initialised\n"); 340 g_pfnVBoxRandRProc = ProcVector[pExt->base]; 341 ProcVector[pExt->base] = vboxRandRDispatch; 342 #if !defined(XF86_VERSION_CURRENT) \ 343 || XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4, 3, 99, 0, 0) 344 g_pfnVBoxRandRSwappedProc = SwappedProcVector[pExt->base]; 345 SwappedProcVector[pExt->base] = vboxRandRSwappedDispatch; 346 #endif 347 return TRUE; 348 } 349 350 /** Install our private RandR hook procedure, so that we can detect 351 * GetScreenInfo requests from clients to update our dynamic mode. This works 352 * by installing a wrapper around CreateScreenResources(), which will be called 353 * after RandR is initialised. The wrapper then in turn wraps the RandR "proc" 354 * vectors with its own handlers which will get called on any client RandR 355 * request. This should not be used in conjunction with RandR 1.2 or later. 356 * A couple of points of interest in our RandR 1.1 support: 357 * * We use the first two screen modes as dynamic modes. When a new mode hint 358 * arrives we update the first of the two which is not the current mode with 359 * the new size. 360 * * RandR 1.1 always advertises a mode of the size of the initial virtual 361 * resolution via GetScreenInfo(), so we make sure that a mode of that size 362 * is always present in the list. 363 * * RandR adds each new mode it sees to an internal array, but never removes 364 * entries. This array might end up getting rather long given that we can 365 * report a lot more modes than physical hardware. 366 */ 367 void VBoxSetUpRandR11(ScreenPtr pScreen) 368 { 369 VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]); 370 371 if (!pScreen->CreateScreenResources) 372 FatalError("called to early: CreateScreenResources not yet initialised\n"); 373 pVBox->pfnCreateScreenResources = pScreen->CreateScreenResources; 374 pScreen->CreateScreenResources = vboxRandRCreateScreenResources; 375 } 376 377 #endif /* !VBOXVIDEO_13 */ -
trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
r50981 r51242 340 340 pVBox->aScreenLocation[cDisplay].x = x; 341 341 pVBox->aScreenLocation[cDisplay].y = y; 342 /* Don't remember any modes set while we are seamless, as they are343 * just temporary. */344 if (!vboxGuestIsSeamless(crtc->scrn))345 vboxSaveVideoMode(crtc->scrn, adjusted_mode->HDisplay,346 adjusted_mode->VDisplay, crtc->scrn->bitsPerPixel);347 342 /* Don't fiddle with the hardware if we are switched 348 343 * to a virtual terminal. */ … … 400 395 vbox_output_mode_valid (xf86OutputPtr output, DisplayModePtr mode) 401 396 { 402 ScrnInfoPtr pScrn = output->scrn; 403 int rc = MODE_OK; 404 TRACE_LOG("HDisplay=%d, VDisplay=%d\n", mode->HDisplay, mode->VDisplay); 405 /* We always like modes specified by the user in the configuration 406 * file and modes requested by the host, as doing otherwise is likely to 407 * annoy people. */ 408 if ( !(mode->type & M_T_USERDEF) 409 && !(mode->type & M_T_PREFERRED) 410 && vbox_device_available(VBOXGetRec(pScrn)) 411 && !vboxHostLikesVideoMode(pScrn, mode->HDisplay, mode->VDisplay, 412 pScrn->bitsPerPixel) 413 ) 414 rc = MODE_BAD; 415 TRACE_LOG("returning %s\n", MODE_OK == rc ? "MODE_OK" : "MODE_BAD"); 416 return rc; 397 return MODE_OK; 417 398 } 418 399 … … 481 462 482 463 TRACE_ENTRY(); 483 uint32_t x, y, bpp,iScreen;464 uint32_t x, y, iScreen; 484 465 iScreen = (uintptr_t)output->driver_private; 485 vboxGetPreferredMode(pScrn, iScreen, &x, &y, &bpp); 486 pMode = vbox_output_add_mode(pVBox, &pModes, NULL, x, y, TRUE, FALSE); 466 VBoxUpdateSizeHints(pScrn); 467 pMode = vbox_output_add_mode(pVBox, &pModes, NULL, 468 pVBox->aPreferredSize[iScreen].cx, 469 pVBox->aPreferredSize[iScreen].cy, TRUE, 470 FALSE); 487 471 VBOXEDIDSet(output, pMode); 488 472 /* Add standard modes supported by the host */ 489 473 for ( ; ; ) 490 474 { 491 cIndex = vboxNextStandardMode(pScrn, cIndex, &x, &y , NULL);475 cIndex = vboxNextStandardMode(pScrn, cIndex, &x, &y); 492 476 if (cIndex == 0) 493 477 break; … … 898 882 pScrn->clockRanges->ClockDivFactor = 1; 899 883 900 /* Query the host for the preferred colour depth */ 901 { 902 uint32_t cx = 0, cy = 0, cBits = 0; 903 904 vboxGetPreferredMode(pScrn, 0, &cx, &cy, &cBits); 905 /* We only support 16 and 24 bits depth (i.e. 16 and 32bpp) */ 906 if (cBits != 16) 907 cBits = 24; 908 if (!xf86SetDepthBpp(pScrn, cBits, 0, 0, Support32bppFb)) 909 return FALSE; 910 vboxAddModes(pScrn, cx, cy); 911 } 884 if (!xf86SetDepthBpp(pScrn, 24, 0, 0, Support32bppFb)) 885 return FALSE; 886 /* We only support 16 and 24 bits depth (i.e. 16 and 32bpp) */ 912 887 if (pScrn->bitsPerPixel != 32 && pScrn->bitsPerPixel != 16) 913 888 { … … 917 892 } 918 893 xf86PrintDepthBpp(pScrn); 894 vboxAddModes(pScrn); 919 895 920 896 #ifdef VBOXVIDEO_13 … … 988 964 } 989 965 990 # ifdef SET_HAVE_VT_PROPERTY991 # define HAS_VT_ATOM_NAME "XFree86_has_VT"966 #define HAS_VT_ATOM_NAME "XFree86_has_VT" 967 #define VBOXVIDEO_DRIVER_ATOM_NAME "VBOXVIDEO_DRIVER_IN_USE" 992 968 /* The memory storing the initial value of the XFree86_has_VT root window 993 969 * property. This has to remain available until server start-up, so we just 994 970 * use a global. */ 995 static CARD32 HasVTValue = 1;971 static CARD32 InitialPropertyValue = 1; 996 972 997 973 /** Initialise a flag property on the root window to say whether the server VT 998 974 * is currently the active one as some clients need to know this. */ 999 static void initialiseHasVTProperty(ScrnInfoPtr pScrn) 1000 { 1001 Atom HasVTAtom = -1; 1002 CARD32 *HasVT = &HasVTValue; 1003 HasVTAtom = MakeAtom(HAS_VT_ATOM_NAME, sizeof(HAS_VT_ATOM_NAME) - 1, TRUE); 1004 if (!xf86RegisterRootWindowProperty(pScrn->scrnIndex, HasVTAtom, XA_INTEGER, 1005 32, 1, HasVT)) 975 static void initialiseProperties(ScrnInfoPtr pScrn) 976 { 977 Atom atom = -1; 978 CARD32 *PropertyValue = &InitialPropertyValue; 979 #ifdef SET_HAVE_VT_PROPERTY 980 atom = MakeAtom(HAS_VT_ATOM_NAME, sizeof(HAS_VT_ATOM_NAME) - 1, TRUE); 981 if (!xf86RegisterRootWindowProperty(pScrn->scrnIndex, atom, XA_INTEGER, 982 32, 1, PropertyValue)) 1006 983 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1007 984 "Failed to register VT property\n"); 1008 } 1009 1010 /** Helper to work round different ways of getting the root window in different 1011 * server versions. */ 1012 #if defined(XORG_VERSION_CURRENT) && XORG_VERSION_CURRENT < 700000000 \ 1013 && XORG_VERSION_CURRENT >= 100900000 1014 # define ROOT_WINDOW(pScrn) xf86ScrnToScreen(pScrn)->root 1015 #else 1016 # define ROOT_WINDOW(pScrn) WindowTable[xf86ScrnToScreen(pScrn)->myNum] 1017 #endif 1018 985 #endif /* SET_HAVE_VT_PROPERTY */ 986 atom = MakeAtom(VBOXVIDEO_DRIVER_ATOM_NAME, 987 sizeof(VBOXVIDEO_DRIVER_ATOM_NAME) - 1, TRUE); 988 if (!xf86RegisterRootWindowProperty(pScrn->scrnIndex, atom, XA_INTEGER, 989 32, 1, PropertyValue)) 990 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 991 "Failed to register driver in use property\n"); 992 } 993 994 #ifdef SET_HAVE_VT_PROPERTY 1019 995 /** Update a flag property on the root window to say whether the server VT 1020 996 * is currently the active one as some clients need to know this. */ … … 1109 1085 vboxEnableVbva(pScrn); 1110 1086 } 1087 VBoxInitialiseSizeHints(pScrn); 1111 1088 1112 1089 #ifdef VBOXVIDEO_13 … … 1178 1155 } 1179 1156 #else /* !VBOXVIDEO_13 */ 1157 VBoxSetUpRandR11(pScreen); 1180 1158 /* set first video mode */ 1181 1159 if (!VBOXSetMode(pScrn, 0, pScrn->currentMode->HDisplay, … … 1190 1168 pVBox->aScreenLocation[0].x = pScrn->frameX0; 1191 1169 pVBox->aScreenLocation[0].y = pScrn->frameY0; 1192 /* And make sure that a non-current dynamic mode is at the front of the1193 * list */1194 vboxWriteHostModes(pScrn, pScrn->currentMode);1195 1170 #endif /* !VBOXVIDEO_13 */ 1196 1171 … … 1234 1209 #endif 1235 1210 1236 #ifdef SET_HAVE_VT_PROPERTY 1237 initialiseHasVTProperty(pScrn); 1238 #endif 1211 initialiseProperties(pScrn); 1239 1212 1240 1213 return (TRUE); … … 1371 1344 rc = VBOXSetMode(pScrn, 0, pMode->HDisplay, pMode->VDisplay, 1372 1345 pScrn->frameX0, pScrn->frameY0); 1373 if (rc)1374 {1375 vboxWriteHostModes(pScrn, pMode);1376 xf86PrintModes(pScrn);1377 }1378 if (rc && !vboxGuestIsSeamless(pScrn))1379 vboxSaveVideoMode(pScrn, pMode->HDisplay, pMode->VDisplay,1380 pScrn->bitsPerPixel);1381 1346 #endif 1382 1347 TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE"); -
trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
r49628 r51242 132 132 133 133 #define VBOXPTR(p) ((VBOXPtr)((p)->driverPrivate)) 134 135 /** Helper to work round different ways of getting the root window in different 136 * server versions. */ 137 #if defined(XORG_VERSION_CURRENT) && XORG_VERSION_CURRENT < 700000000 \ 138 && XORG_VERSION_CURRENT >= 100900000 139 # define ROOT_WINDOW(pScrn) screenInfo.screens[(pScrn)->scrnIndex]->root 140 #else 141 # define ROOT_WINDOW(pScrn) WindowTable[(pScrn)->scrnIndex] 142 #endif 134 143 135 144 /*XXX*/ … … 181 190 struct _xf86Crtc *paCrtcs[VBOX_VIDEO_MAX_SCREENS]; 182 191 struct _xf86Output *paOutputs[VBOX_VIDEO_MAX_SCREENS]; 192 #else 193 /** The original CreateScreenResources procedure which we wrap with our own. 194 */ 195 CreateScreenResourcesProcPtr pfnCreateScreenResources; 183 196 #endif 184 197 /** Offsets of VBVA buffers in video RAM */ … … 212 225 extern void vboxDisableVbva(ScrnInfoPtr pScrn); 213 226 214 extern Bool vboxEnableGraphicsCap(VBOXPtr pVBox);215 extern Bool vboxDisableGraphicsCap(VBOXPtr pVBox);216 extern Bool vboxGuestIsSeamless(ScrnInfoPtr pScrn);217 218 extern Bool vboxGetDisplayChangeRequest(ScrnInfoPtr pScrn, uint32_t *pcx,219 uint32_t *pcy, uint32_t *pcBits,220 uint32_t *piDisplay);221 extern Bool vboxHostLikesVideoMode(ScrnInfoPtr pScrn, uint32_t cx, uint32_t cy, uint32_t cBits);222 extern Bool vboxSaveVideoMode(ScrnInfoPtr pScrn, uint32_t cx, uint32_t cy, uint32_t cBits);223 extern Bool vboxRetrieveVideoMode(ScrnInfoPtr pScrn, uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits);224 227 extern unsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex, 225 uint32_t *pcx, uint32_t *pcy, 226 uint32_t *pcBits); 227 extern void vboxGetPreferredMode(ScrnInfoPtr pScrn, uint32_t iScreen, 228 uint32_t *pcx, uint32_t *pcy, 229 uint32_t *pcBits); 230 extern void vboxWriteHostModes(ScrnInfoPtr pScrn, DisplayModePtr pCurrent); 231 extern void vboxAddModes(ScrnInfoPtr pScrn, uint32_t cxInit, 232 uint32_t cyInit); 228 uint32_t *pcx, uint32_t *pcy); 229 extern void vboxAddModes(ScrnInfoPtr pScrn); 230 extern void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn); 231 extern void VBoxUpdateSizeHints(ScrnInfoPtr pScrn); 232 #ifndef VBOXVIDEO_13 233 extern void VBoxSetUpRandR11(ScreenPtr pScreen); 234 #endif 233 235 234 236 /* DRI stuff */
Note:
See TracChangeset
for help on using the changeset viewer.