Changeset 54531 in vbox
- Timestamp:
- Feb 26, 2015 2:05:57 PM (10 years ago)
- Location:
- trunk/src/VBox/Additions/x11
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/undefined_xorg
r54530 r54531 106 106 __register_frame_info_bases 107 107 rename 108 RRC rtcSet108 RRChangeOutputProperty 109 109 RRGetInfo 110 RRScreenSizeSet111 110 setenv 112 111 ShadowFBInit2 … … 158 157 xf86CrtcCreate 159 158 xf86CrtcScreenInit 160 xf86CrtcSetMode161 159 xf86CrtcSetSizeRange 162 160 xf86DestroyCursorInfoRec -
trunk/src/VBox/Additions/x11/vboxvideo/README.testing
r54530 r54531 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. 20 for all monitors (note: currently only after log-in). -
trunk/src/VBox/Additions/x11/vboxvideo/getmode.c
r54530 r54531 36 36 #endif 37 37 38 #ifdef VBOXVIDEO_13 39 # ifdef RT_OS_LINUX 40 # include "randrstr.h" 41 # include "xf86_OSproc.h" 42 # include <linux/input.h> 43 # ifndef EVIOCGRAB 44 # define EVIOCGRAB _IOW('E', 0x90, int) 45 # endif 46 # ifndef KEY_SWITCHVIDEOMODE 47 # define KEY_SWITCHVIDEOMODE 227 48 # endif 49 # include <dirent.h> 50 # include <errno.h> 51 # include <fcntl.h> 52 # include <unistd.h> 53 # endif /* RT_OS_LINUX */ 54 #endif /* VBOXVIDEO_13 */ 38 55 /************************************************************************** 39 56 * Main functions * … … 82 99 } 83 100 101 /** vboxvideo's list of standard video modes */ 102 struct 103 { 104 /** mode width */ 105 uint32_t cx; 106 /** mode height */ 107 uint32_t cy; 108 } vboxStandardModes[] = 109 { 110 { 1600, 1200 }, 111 { 1440, 1050 }, 112 { 1280, 960 }, 113 { 1024, 768 }, 114 { 800, 600 }, 115 { 640, 480 }, 116 { 0, 0 } 117 }; 118 enum 119 { 120 vboxNumStdModes = sizeof(vboxStandardModes) / sizeof(vboxStandardModes[0]) 121 }; 122 123 /** 124 * Returns a standard mode which the host likes. Can be called multiple 125 * times with the index returned by the previous call to get a list of modes. 126 * @returns the index of the mode in the list, or 0 if no more modes are 127 * available 128 * @param pScrn the screen information structure 129 * @param pScrn->bitsPerPixel 130 * if this is non-null, only modes with this BPP will be 131 * returned 132 * @param cIndex the index of the last mode queried, or 0 to query the 133 * first mode available. Note: the first index is 1 134 * @param pcx where to store the mode's width 135 * @param pcy where to store the mode's height 136 * @param pcBits where to store the mode's BPP 137 */ 138 unsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex, 139 uint32_t *pcx, uint32_t *pcy) 140 { 141 unsigned i; 142 143 VBVXASSERT(cIndex < vboxNumStdModes, 144 ("cIndex = %d, vboxNumStdModes = %d\n", cIndex, 145 vboxNumStdModes)); 146 for (i = cIndex; i < vboxNumStdModes - 1; ++i) 147 { 148 uint32_t cx = vboxStandardModes[i].cx; 149 uint32_t cy = vboxStandardModes[i].cy; 150 151 if (pcx) 152 *pcx = cx; 153 if (pcy) 154 *pcy = cy; 155 return i + 1; 156 } 157 return 0; 158 } 159 84 160 /** 85 161 * Allocates an empty display mode and links it into the doubly linked list of … … 112 188 * of the graphics modes that we wish to support, that is: 113 189 * - A dynamic mode in first place which will be updated by the RandR code. 190 * - Several standard modes. 114 191 * - Any modes that the user requested in xorg.conf/XFree86Config. 115 192 */ … … 126 203 pMode = vboxAddEmptyScreenMode(pScrn); 127 204 vboxFillDisplayMode(pScrn, pMode, NULL, 1024, 768); 128 /* Add any modes specified by the user. We assume here that the mode names 129 * reflect the mode sizes. */ 205 /* Add standard modes supported by the host */ 206 for ( ; ; ) 207 { 208 cIndex = vboxNextStandardMode(pScrn, cIndex, &cx, &cy); 209 if (cIndex == 0) 210 break; 211 pMode = vboxAddEmptyScreenMode(pScrn); 212 vboxFillDisplayMode(pScrn, pMode, NULL, cx, cy); 213 } 214 /* And finally any modes specified by the user. We assume here that 215 * the mode names reflect the mode sizes. */ 130 216 for (i = 0; pScrn->display->modes && pScrn->display->modes[i]; i++) 131 217 { … … 138 224 } 139 225 140 /** Set the initial values for the guest screen size hints to standard values 141 * in case nothing else is available. */ 226 /** Set the initial values for the guest screen size hints by reading saved 227 * values from files. */ 228 /** @todo Actually read the files instead of setting dummies. */ 142 229 void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn) 143 230 { … … 155 242 pScrn->modes->HDisplay = pVBox->pScreens[0].aPreferredSize.cx; 156 243 pScrn->modes->VDisplay = pVBox->pScreens[0].aPreferredSize.cy; 157 } 158 159 static bool useHardwareCursor(uint32_t fCursorCapabilities) 244 /* RandR 1.1 quirk: make sure that the initial resolution is always present 245 * in the mode list as RandR will always advertise a mode of the initial 246 * virtual resolution via GetScreenInfo. */ 247 pMode = vboxAddEmptyScreenMode(pScrn); 248 vboxFillDisplayMode(pScrn, pMode, NULL, pVBox->pScreens[0].aPreferredSize.cx, 249 pVBox->pScreens[0].aPreferredSize.cy); 250 } 251 252 static void updateUseHardwareCursor(VBOXPtr pVBox, uint32_t fCursorCapabilities) 160 253 { 161 254 if ( !(fCursorCapabilities & VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER) 162 255 && (fCursorCapabilities & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE)) 163 return true; 164 return false; 165 } 166 167 static void compareAndMaybeSetUseHardwareCursor(VBOXPtr pVBox, uint32_t fCursorCapabilities, bool *pfChanged, bool fSet) 168 { 169 if (pVBox->fUseHardwareCursor != useHardwareCursor(fCursorCapabilities)) 170 *pfChanged = true; 171 if (fSet) 172 pVBox->fUseHardwareCursor = useHardwareCursor(fCursorCapabilities); 173 } 174 175 #define SIZE_HINTS_PROPERTY "VBOX_SIZE_HINTS" 176 #define SIZE_HINTS_MISMATCH_PROPERTY "VBOX_SIZE_HINTS_MISMATCH" 177 #define MOUSE_CAPABILITIES_PROPERTY "VBOX_MOUSE_CAPABILITIES" 178 179 #define COMPARE_AND_MAYBE_SET(pDest, src, pfChanged, fSet) \ 180 do { \ 181 if (*(pDest) != (src)) \ 182 { \ 183 if (fSet) \ 184 *(pDest) = (src); \ 185 *(pfChanged) = true; \ 186 } \ 187 } while(0) 188 189 /** Read in information about the most recent size hints and cursor 190 * capabilities requested for the guest screens from a root window property set 191 * by an X11 client. Information obtained via HGSMI takes priority. */ 192 void vbvxReadSizesAndCursorIntegrationFromProperties(ScrnInfoPtr pScrn, bool *pfNeedUpdate) 256 pVBox->fUseHardwareCursor = true; 257 else 258 pVBox->fUseHardwareCursor = false; 259 } 260 261 # define SIZE_HINTS_PROPERTY "VBOX_SIZE_HINTS" 262 # define MOUSE_CAPABILITIES_PROPERTY "VBOX_MOUSE_CAPABILITIES" 263 264 /** Read in information about the most recent size hints requested for the 265 * guest screens. A client application sets the hint information as a root 266 * window property. */ 267 /* TESTING: dynamic resizing and absolute pointer toggling work on old guest X servers and recent ones on Linux at the log-in screen. */ 268 /** @note we try to maximise code coverage by typically using all code paths (HGSMI and properties) in a single X session. */ 269 void VBoxUpdateSizeHints(ScrnInfoPtr pScrn) 193 270 { 194 271 VBOXPtr pVBox = VBOXGetRec(pScrn); 195 272 size_t cModesFromProperty, cDummy; 196 int32_t *paModeHints, *pfCursorCapabilities; 197 int rc; 273 int32_t *paModeHints, *pfCursorCapabilities; 198 274 unsigned i; 199 bool fChanged = false;200 int32_t fSizeMismatch;275 uint32_t fCursorCapabilities; 276 bool fOldUseHardwareCursor = pVBox->fUseHardwareCursor; 201 277 202 278 if (vbvxGetIntegerPropery(pScrn, SIZE_HINTS_PROPERTY, &cModesFromProperty, &paModeHints) != VINF_SUCCESS) 203 279 paModeHints = NULL; 280 if ( vbvxGetIntegerPropery(pScrn, MOUSE_CAPABILITIES_PROPERTY, &cDummy, &pfCursorCapabilities) != VINF_SUCCESS 281 || cDummy != 1) 282 pfCursorCapabilities = NULL; 283 #ifdef VBOXVIDEO_13 284 if (!pVBox->fHaveReadHGSMIModeHintData && RT_SUCCESS(VBoxHGSMIGetModeHints(&pVBox->guestCtx, pVBox->cScreens, 285 pVBox->paVBVAModeHints))) 286 { 287 for (i = 0; i < pVBox->cScreens; ++i) 288 { 289 if (pVBox->paVBVAModeHints[i].magic == VBVAMODEHINT_MAGIC) 290 { 291 pVBox->pScreens[i].aPreferredSize.cx = pVBox->paVBVAModeHints[i].cx; 292 pVBox->pScreens[i].aPreferredSize.cy = pVBox->paVBVAModeHints[i].cy; 293 pVBox->pScreens[i].afConnected = pVBox->paVBVAModeHints[i].fEnabled; 294 /* Do not re-read this if we have data from HGSMI. */ 295 if (paModeHints != NULL && i < cModesFromProperty) 296 pVBox->pScreens[i].lastModeHintFromProperty = paModeHints[i]; 297 } 298 } 299 } 300 if (!pVBox->fHaveReadHGSMIModeHintData) 301 { 302 if (RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &fCursorCapabilities))) 303 updateUseHardwareCursor(pVBox, fCursorCapabilities); 304 else 305 pVBox->fUseHardwareCursor = false; 306 /* Do not re-read this if we have data from HGSMI. */ 307 if (pfCursorCapabilities != NULL) 308 pVBox->fLastCursorCapabilitiesFromProperty = *pfCursorCapabilities; 309 } 310 pVBox->fHaveReadHGSMIModeHintData = true; 311 #endif 204 312 if (paModeHints != NULL) 205 313 for (i = 0; i < cModesFromProperty && i < pVBox->cScreens; ++i) 206 if (paModeHints[i] != 0) 314 { 315 if (paModeHints[i] != 0 && paModeHints[i] != pVBox->pScreens[i].lastModeHintFromProperty) 207 316 { 208 317 if (paModeHints[i] == -1) 209 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afConnected, false, &fChanged, !pVBox->fHaveHGSMIModeHints);318 pVBox->pScreens[i].afConnected = false; 210 319 else 211 320 { 212 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cx, (paModeHints[i] >> 16) & 0x8fff, &fChanged, 213 !pVBox->fHaveHGSMIModeHints); 214 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cy, paModeHints[i] & 0x8fff, &fChanged, 215 !pVBox->fHaveHGSMIModeHints); 216 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afConnected, true, &fChanged, !pVBox->fHaveHGSMIModeHints); 321 pVBox->pScreens[i].aPreferredSize.cx = paModeHints[i] >> 16; 322 pVBox->pScreens[i].aPreferredSize.cy = paModeHints[i] & 0x8fff; 323 pVBox->pScreens[i].afConnected = true; 217 324 } 325 pVBox->pScreens[i].lastModeHintFromProperty = paModeHints[i]; 218 326 } 219 if ( vbvxGetIntegerPropery(pScrn, MOUSE_CAPABILITIES_PROPERTY, &cDummy, &pfCursorCapabilities) == VINF_SUCCESS 220 && cDummy == 1) 221 compareAndMaybeSetUseHardwareCursor(pVBox, *pfCursorCapabilities, &fChanged, !pVBox->fHaveHGSMIModeHints); 222 fSizeMismatch = pVBox->fHaveHGSMIModeHints && fChanged; 223 vbvxSetIntegerPropery(pScrn, SIZE_HINTS_MISMATCH_PROPERTY, 1, &fSizeMismatch, false); 224 if (pfNeedUpdate != NULL) 225 *pfNeedUpdate = !pVBox->fHaveHGSMIModeHints && fChanged; 226 } 227 228 /** Read in information about the most recent size hints and cursor 229 * capabilities requested for the guest screens from HGSMI. */ 230 void vbvxReadSizesAndCursorIntegrationFromHGSMI(ScrnInfoPtr pScrn, bool *pfNeedUpdate) 231 { 327 } 328 if (pfCursorCapabilities != NULL && *pfCursorCapabilities != pVBox->fLastCursorCapabilitiesFromProperty) 329 { 330 updateUseHardwareCursor(pVBox, (uint32_t)*pfCursorCapabilities); 331 pVBox->fLastCursorCapabilitiesFromProperty = *pfCursorCapabilities; 332 } 333 if (pVBox->fUseHardwareCursor != fOldUseHardwareCursor) 334 vbvxReprobeCursor(pScrn); 335 } 336 337 #ifndef VBOXVIDEO_13 338 339 /** The RandR "proc" vector, which we wrap with our own in order to notice 340 * when a client sends a GetScreenInfo request. */ 341 static int (*g_pfnVBoxRandRProc)(ClientPtr) = NULL; 342 /** The swapped RandR "proc" vector. */ 343 static int (*g_pfnVBoxRandRSwappedProc)(ClientPtr) = NULL; 344 345 /* TESTING: dynamic resizing and toggling cursor integration work with older guest X servers (1.2 and older). */ 346 static void vboxRandRDispatchCore(ClientPtr pClient) 347 { 348 xRRGetScreenInfoReq *pReq = (xRRGetScreenInfoReq *)pClient->requestBuffer; 349 WindowPtr pWin; 350 ScrnInfoPtr pScrn; 351 VBOXPtr pVBox; 352 DisplayModePtr pMode; 353 354 if (pClient->req_len != sizeof(xRRGetScreenInfoReq) >> 2) 355 return; 356 pWin = (WindowPtr)SecurityLookupWindow(pReq->window, pClient, 357 SecurityReadAccess); 358 if (!pWin) 359 return; 360 pScrn = xf86Screens[pWin->drawable.pScreen->myNum]; 361 pVBox = VBOXGetRec(pScrn); 362 TRACE_LOG("pVBox->fUseHardwareCursor=%u\n", pVBox->fUseHardwareCursor); 363 VBoxUpdateSizeHints(pScrn); 364 pMode = pScrn->modes; 365 if (pScrn->currentMode == pMode) 366 pMode = pMode->next; 367 pMode->HDisplay = pVBox->pScreens[0].aPreferredSize.cx; 368 pMode->VDisplay = pVBox->pScreens[0].aPreferredSize.cy; 369 } 370 371 static int vboxRandRDispatch(ClientPtr pClient) 372 { 373 xReq *pReq = (xReq *)pClient->requestBuffer; 374 375 if (pReq->data == X_RRGetScreenInfo) 376 vboxRandRDispatchCore(pClient); 377 return g_pfnVBoxRandRProc(pClient); 378 } 379 380 static int vboxRandRSwappedDispatch(ClientPtr pClient) 381 { 382 xReq *pReq = (xReq *)pClient->requestBuffer; 383 384 if (pReq->data == X_RRGetScreenInfo) 385 vboxRandRDispatchCore(pClient); 386 return g_pfnVBoxRandRSwappedProc(pClient); 387 } 388 389 static Bool vboxRandRCreateScreenResources(ScreenPtr pScreen) 390 { 391 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 232 392 VBOXPtr pVBox = VBOXGetRec(pScrn); 233 int rc; 234 unsigned i; 235 bool fChanged = false; 236 uint32_t fCursorCapabilities; 237 238 if (pfNeedUpdate != NULL) 239 *pfNeedUpdate = false; 240 if (!pVBox->fHaveHGSMIModeHints) 393 ExtensionEntry *pExt; 394 395 pScreen->CreateScreenResources = pVBox->pfnCreateScreenResources; 396 if (!pScreen->CreateScreenResources(pScreen)) 397 return FALSE; 398 /* I doubt we can be loaded twice - should I fail here? */ 399 if (g_pfnVBoxRandRProc) 400 return TRUE; 401 pExt = CheckExtension(RANDR_NAME); 402 if (!pExt) 403 { 404 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 405 "RandR extension not found, disabling dynamic resizing.\n"); 406 return TRUE; 407 } 408 if ( !ProcVector[pExt->base] 409 #if !defined(XF86_VERSION_CURRENT) \ 410 || XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4, 3, 99, 0, 0) 411 /* SwappedProcVector is not exported in XFree86, so we will not support 412 * swapped byte order clients. I doubt this is a big issue. */ 413 || !SwappedProcVector[pExt->base] 414 #endif 415 ) 416 FatalError("RandR \"proc\" vector not initialised\n"); 417 g_pfnVBoxRandRProc = ProcVector[pExt->base]; 418 ProcVector[pExt->base] = vboxRandRDispatch; 419 #if !defined(XF86_VERSION_CURRENT) \ 420 || XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4, 3, 99, 0, 0) 421 g_pfnVBoxRandRSwappedProc = SwappedProcVector[pExt->base]; 422 SwappedProcVector[pExt->base] = vboxRandRSwappedDispatch; 423 #endif 424 return TRUE; 425 } 426 427 /** Install our private RandR hook procedure, so that we can detect 428 * GetScreenInfo requests from clients to update our dynamic mode. This works 429 * by installing a wrapper around CreateScreenResources(), which will be called 430 * after RandR is initialised. The wrapper then in turn wraps the RandR "proc" 431 * vectors with its own handlers which will get called on any client RandR 432 * request. This should not be used in conjunction with RandR 1.2 or later. 433 * A couple of points of interest in our RandR 1.1 support: 434 * * We use the first two screen modes as dynamic modes. When a new mode hint 435 * arrives we update the first of the two which is not the current mode with 436 * the new size. 437 * * RandR 1.1 always advertises a mode of the size of the initial virtual 438 * resolution via GetScreenInfo(), so we make sure that a mode of that size 439 * is always present in the list. 440 * * RandR adds each new mode it sees to an internal array, but never removes 441 * entries. This array might end up getting rather long given that we can 442 * report a lot more modes than physical hardware. 443 */ 444 void VBoxSetUpRandR11(ScreenPtr pScreen) 445 { 446 VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]); 447 448 if (!pScreen->CreateScreenResources) 449 FatalError("called to early: CreateScreenResources not yet initialised\n"); 450 pVBox->pfnCreateScreenResources = pScreen->CreateScreenResources; 451 pScreen->CreateScreenResources = vboxRandRCreateScreenResources; 452 } 453 454 #endif /* !VBOXVIDEO_13 */ 455 456 #ifdef VBOXVIDEO_13 457 # ifdef RT_OS_LINUX 458 /* TESTING: dynamic resizing works on recent Linux guest X servers at the log-in screen. */ 459 /** @note to maximise code coverage we only read data from HGSMI once, and only when responding to an ACPI event. */ 460 static void acpiEventHandler(int fd, void *pvData) 461 { 462 ScreenPtr pScreen = (ScreenPtr)pvData; 463 VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]); 464 struct input_event event; 465 ssize_t rc; 466 467 pVBox->fHaveReadHGSMIModeHintData = false; 468 RRGetInfo(pScreen 469 # if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5 470 , TRUE 471 # endif 472 ); 473 VBVXASSERT(pVBox->fHaveReadHGSMIModeHintData == true, ("fHaveReadHGSMIModeHintData not set.\n")); 474 do 475 rc = read(fd, &event, sizeof(event)); 476 while (rc > 0 || (rc == -1 && errno == EINTR)); 477 /* Why do they return EAGAIN instead of zero bytes read like everyone else does? */ 478 VBVXASSERT(rc != -1 || errno == EAGAIN, ("Reading ACPI input event failed.\n")); 479 } 480 481 void VBoxSetUpLinuxACPI(ScreenPtr pScreen) 482 { 483 VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]); 484 struct dirent *pDirent; 485 DIR *pDir; 486 int fd = -1; 487 488 if (pVBox->fdACPIDevices != -1 || pVBox->hACPIEventHandler != NULL) 489 FatalError("ACPI input file descriptor not initialised correctly.\n"); 490 pDir = opendir("/dev/input"); 491 if (pDir == NULL) 241 492 return; 242 rc = VBoxHGSMIGetModeHints(&pVBox->guestCtx, pVBox->cScreens, pVBox->paVBVAModeHints); 243 VBVXASSERT(rc == VINF_SUCCESS, ("VBoxHGSMIGetModeHints failed, rc=%d.\n", rc)); 244 for (i = 0; i < pVBox->cScreens; ++i) 245 if (pVBox->paVBVAModeHints[i].magic == VBVAMODEHINT_MAGIC) 493 for (pDirent = readdir(pDir); pDirent != NULL; pDirent = readdir(pDir)) 494 { 495 if (strncmp(pDirent->d_name, "event", sizeof("event") - 1) == 0) 246 496 { 247 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cx, pVBox->paVBVAModeHints[i].cx & 0x8fff, &fChanged, true); 248 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cy, pVBox->paVBVAModeHints[i].cy & 0x8fff, &fChanged, true); 249 COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afConnected, RT_BOOL(pVBox->paVBVAModeHints[i].fEnabled), &fChanged, true); 497 #define BITS_PER_BLOCK (sizeof(unsigned long) * 8) 498 char szFile[64] = "/dev/input/"; 499 char szDevice[64] = ""; 500 unsigned long afKeys[KEY_MAX / BITS_PER_BLOCK]; 501 502 strncat(szFile, pDirent->d_name, sizeof(szFile) - sizeof("/dev/input/")); 503 if (fd != -1) 504 close(fd); 505 fd = open(szFile, O_RDONLY | O_NONBLOCK); 506 if ( fd == -1 507 || ioctl(fd, EVIOCGNAME(sizeof(szDevice)), szDevice) == -1 508 || strcmp(szDevice, "Video Bus") != 0) 509 continue; 510 if ( ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(afKeys)), afKeys) == -1 511 || (( afKeys[KEY_SWITCHVIDEOMODE / BITS_PER_BLOCK] 512 >> KEY_SWITCHVIDEOMODE % BITS_PER_BLOCK) & 1) == 0) 513 break; 514 if (ioctl(fd, EVIOCGRAB, (void *)1) != 0) 515 break; 516 pVBox->hACPIEventHandler 517 = xf86AddGeneralHandler(fd, acpiEventHandler, pScreen); 518 if (pVBox->hACPIEventHandler == NULL) 519 break; 520 pVBox->fdACPIDevices = fd; 521 fd = -1; 522 break; 523 #undef BITS_PER_BLOCK 250 524 } 251 rc = VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &fCursorCapabilities); 252 VBVXASSERT(rc == VINF_SUCCESS, ("Getting VBOX_VBVA_CONF32_CURSOR_CAPABILITIES failed, rc=%d.\n", rc)); 253 compareAndMaybeSetUseHardwareCursor(pVBox, fCursorCapabilities, &fChanged, true); 254 if (pfNeedUpdate != NULL) 255 *pfNeedUpdate = fChanged; 256 } 257 258 #undef COMPARE_AND_MAYBE_SET 525 } 526 if (fd != -1) 527 close(fd); 528 closedir(pDir); 529 } 530 531 void VBoxCleanUpLinuxACPI(ScreenPtr pScreen) 532 { 533 VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]); 534 if (pVBox->fdACPIDevices != -1) 535 close(pVBox->fdACPIDevices); 536 pVBox->fdACPIDevices = -1; 537 xf86RemoveGeneralHandler(pVBox->hACPIEventHandler); 538 pVBox->hACPIEventHandler = NULL; 539 } 540 # endif /* RT_OS_LINUX */ 541 #endif /* VBOXVIDEO_13 */ -
trunk/src/VBox/Additions/x11/vboxvideo/helpers.c
r54530 r54531 55 55 } 56 56 57 /* TESTING: if this is broken, dynamic resizing will not work on old X servers (1.2 and older). */ 57 58 int vbvxGetIntegerPropery(ScrnInfoPtr pScrn, char *pszName, size_t *pcData, int32_t **ppaData) 58 59 { … … 63 64 if (!ROOT_WINDOW(pScrn)) 64 65 return VERR_NOT_FOUND; 65 atom = MakeAtom(pszName, strlen(pszName), TRUE);66 atom = MakeAtom(pszName, strlen(pszName), FALSE); 66 67 if (atom == BAD_RESOURCE) 67 68 return VERR_NOT_FOUND; … … 75 76 *ppaData = (int32_t *)prop->data; 76 77 return VINF_SUCCESS; 77 }78 79 void vbvxSetIntegerPropery(ScrnInfoPtr pScrn, char *pszName, size_t cData, int32_t *paData, Bool fSendEvent)80 {81 Atom property_name;82 int i;83 84 property_name = MakeAtom(pszName, strlen(pszName), TRUE);85 VBVXASSERT(property_name != BAD_RESOURCE, ("Failed to set atom \"%s\"\n", pszName));86 ChangeWindowProperty(ROOT_WINDOW(pScrn), property_name, XA_INTEGER, 32, PropModeReplace, cData, paData, fSendEvent);87 78 } 88 79 -
trunk/src/VBox/Additions/x11/vboxvideo/setmode.c
r54530 r54531 75 75 * size of a new framebuffer. Framebuffer sizes larger than available VRAM 76 76 * be treated as zero and passed over. */ 77 void vb vxClearVRAM(ScrnInfoPtr pScrn, size_t cbOldSize, size_t cbNewSize)77 void vboxClearVRAM(ScrnInfoPtr pScrn, int32_t cNewX, int32_t cNewY) 78 78 { 79 79 VBOXPtr pVBox = VBOXGetRec(pScrn); 80 81 /* Assume 32BPP - this is just a sanity test. */ 82 VBVXASSERT(cbOldSize / 4 <= INT16_MAX * INT16_MAX && cbNewSize / 4 <= INT16_MAX * INT16_MAX,83 ("cbOldSize or cbNewSize is too big.\n"));84 if (cbOld Size > (size_t)pVBox->cbFBMax)85 cbOld Size = pVBox->cbFBMax;86 if (cbNew Size > (size_t)pVBox->cbFBMax)87 cbNew Size = pVBox->cbFBMax;88 memset(pVBox->base, 0, max(cbOld Size, cbNewSize));80 uint64_t cbOldFB, cbNewFB; 81 82 cbOldFB = pVBox->cbLine * pScrn->virtualX; 83 cbNewFB = vboxLineLength(pScrn, cNewX) * cNewY; 84 if (cbOldFB > (uint64_t)pVBox->cbFBMax) 85 cbOldFB = 0; 86 if (cbNewFB > (uint64_t)pVBox->cbFBMax) 87 cbNewFB = 0; 88 memset(pVBox->base, 0, max(cbOldFB, cbNewFB)); 89 89 } 90 90 91 91 /** Set a graphics mode. Poke any required values into registers, do an HGSMI 92 * mode set and tell the host we support advanced graphics functions. 93 */ 94 void vbvxSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth, unsigned cHeight, int x, int y, bool fEnabled, 95 bool fConnected, struct vbvxFrameBuffer *pFrameBuffer) 92 * mode set and tell the host we support advanced graphics functions. This 93 * procedure is complicated by the fact that X.Org can implicitly disable a 94 * screen by resizing the virtual framebuffer so that the screen is no longer 95 * inside it. We have to spot and handle this. 96 */ 97 Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth, 98 unsigned cHeight, int x, int y) 96 99 { 97 100 VBOXPtr pVBox = VBOXGetRec(pScrn); 98 uint32_t offStart; 101 uint32_t offStart, cwReal = cWidth; 102 bool fEnabled; 99 103 uint16_t fFlags; 100 104 int rc; 101 105 102 TRACE_LOG("cDisplay=%u, cWidth=%u, cHeight=%u, x=%d, y=%d, fEnabled=%d, fConnected=%d, pFrameBuffer: { x0=%d, y0=%d, cWidth=%u, cHeight=%u, cBPP=%u }\n", 103 cDisplay, cWidth, cHeight, x, y, fEnabled, fConnected, pFrameBuffer->x0, pFrameBuffer->y0, pFrameBuffer->cWidth, 104 pFrameBuffer->cHeight, pFrameBuffer->cBPP); 105 VBVXASSERT(cWidth != 0 && cHeight != 0, ("cWidth = 0 or cHeight = 0\n")); 106 offStart = (y * pFrameBuffer->cWidth + x) * pFrameBuffer->cBPP / 8; 106 TRACE_LOG("cDisplay=%u, cWidth=%u, cHeight=%u, x=%d, y=%d, displayWidth=%d\n", 107 cDisplay, cWidth, cHeight, x, y, pScrn->displayWidth); 108 offStart = y * pVBox->cbLine + x * vboxBPP(pScrn) / 8; 109 /* Deactivate the screen if the mode - specifically the virtual width - is 110 * too large for VRAM as we sometimes have to do this - see comments in 111 * VBOXPreInit. */ 112 if ( offStart + pVBox->cbLine * cHeight > pVBox->cbFBMax 113 || pVBox->cbLine * pScrn->virtualY > pVBox->cbFBMax) 114 return FALSE; 115 /* Deactivate the screen if it is outside of the virtual framebuffer and 116 * clamp it to lie inside if it is partly outside. */ 117 if (x >= pScrn->displayWidth || x + (int) cWidth <= 0) 118 return FALSE; 119 else 120 cwReal = RT_MIN((int) cWidth, pScrn->displayWidth - x); 121 TRACE_LOG("pVBox->pScreens[%u].fCrtcEnabled=%d, fOutputEnabled=%d\n", 122 cDisplay, (int)pVBox->pScreens[cDisplay].fCrtcEnabled, 123 (int)pVBox->pScreens[cDisplay].fOutputEnabled); 107 124 if (cDisplay == 0) 108 VBoxVideoSetModeRegisters(cWidth, cHeight, pFrameBuffer->cWidth, pFrameBuffer->cBPP, 0, x, y); 125 VBoxVideoSetModeRegisters(cwReal, cHeight, pScrn->displayWidth, 126 vboxBPP(pScrn), 0, x, y); 127 fEnabled = pVBox->pScreens[cDisplay].fCrtcEnabled 128 && pVBox->pScreens[cDisplay].fOutputEnabled; 109 129 fFlags = VBVA_SCREEN_F_ACTIVE; 110 fFlags |= (fConnected ? 0 : VBVA_SCREEN_F_DISABLED); 111 VBoxHGSMIProcessDisplayInfo(&pVBox->guestCtx, cDisplay, x - pFrameBuffer->x0, y - pFrameBuffer->y0, offStart, 112 pFrameBuffer->cWidth * pFrameBuffer->cBPP / 8, cWidth, cHeight, 113 fEnabled ? pFrameBuffer->cBPP : 0, fFlags); 114 rc = VBoxHGSMIUpdateInputMapping(&pVBox->guestCtx, 0 - pFrameBuffer->x0, 0 - pFrameBuffer->y0, pFrameBuffer->cWidth, 115 pFrameBuffer->cHeight); 130 fFlags |= (pVBox->pScreens[cDisplay].afConnected ? 0 131 : VBVA_SCREEN_F_DISABLED); 132 VBoxHGSMIProcessDisplayInfo(&pVBox->guestCtx, cDisplay, x, y, 133 offStart, pVBox->cbLine, cwReal, cHeight, 134 fEnabled ? vboxBPP(pScrn) : 0, fFlags); 135 if (cDisplay == 0) 136 { 137 rc = VBoxHGSMIUpdateInputMapping(&pVBox->guestCtx, 0 - pVBox->pScreens[0].aScreenLocation.x, 138 0 - pVBox->pScreens[0].aScreenLocation.y, pScrn->virtualX, pScrn->virtualY); 139 if (RT_FAILURE(rc)) 140 FatalError("Failed to update the input mapping.\n"); 141 } 142 return TRUE; 143 } 144 145 /** Resize the virtual framebuffer. After resizing we reset all modes 146 * (X.Org 1.3+) to adjust them to the new framebuffer. 147 */ 148 Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height) 149 { 150 ScreenPtr pScreen = pScrn->pScreen; 151 PixmapPtr pPixmap = pScreen->GetScreenPixmap(pScreen); 152 VBOXPtr pVBox = VBOXGetRec(pScrn); 153 uint64_t cbLine = vboxLineLength(pScrn, width); 154 int displayWidth = vboxDisplayPitch(pScrn, cbLine); 155 int rc; 156 157 TRACE_LOG("width=%d, height=%d\n", width, height); 158 if ( width == pScrn->virtualX 159 && height == pScrn->virtualY 160 && displayWidth == pScrn->displayWidth) 161 return TRUE; 162 if (!pPixmap) { 163 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 164 "Failed to get the screen pixmap.\n"); 165 return FALSE; 166 } 167 if (cbLine > UINT32_MAX || cbLine * height >= pVBox->cbFBMax) 168 { 169 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 170 "Unable to set up a virtual screen size of %dx%d with %lu of %d Kb of video memory available. Please increase the video memory size.\n", 171 width, height, pVBox->cbFBMax / 1024, pScrn->videoRam); 172 return FALSE; 173 } 174 pScreen->ModifyPixmapHeader(pPixmap, width, height, 175 pScrn->depth, vboxBPP(pScrn), cbLine, 176 pVBox->base); 177 vboxClearVRAM(pScrn, width, height); 178 pScrn->virtualX = width; 179 pScrn->virtualY = height; 180 pScrn->displayWidth = displayWidth; 181 pVBox->cbLine = cbLine; 182 #ifdef VBOX_DRI_OLD 183 if (pVBox->useDRI) 184 VBOXDRIUpdateStride(pScrn, pVBox); 185 #endif 186 #ifdef VBOXVIDEO_13 187 /* Write the new values to the hardware */ 188 /** @todo why is this only for VBOXVIDEO_13? */ 189 { 190 unsigned i; 191 for (i = 0; i < pVBox->cScreens; ++i) 192 VBOXSetMode(pScrn, i, pVBox->pScreens[i].aScreenLocation.cx, 193 pVBox->pScreens[i].aScreenLocation.cy, 194 pVBox->pScreens[i].aScreenLocation.x, 195 pVBox->pScreens[i].aScreenLocation.y); 196 } 197 #else 198 rc = VBoxHGSMIUpdateInputMapping(&pVBox->guestCtx, 0 - pVBox->pScreens[0].aScreenLocation.x, 199 0 - pVBox->pScreens[0].aScreenLocation.y, pScrn->virtualX, pScrn->virtualY); 116 200 if (RT_FAILURE(rc)) 117 201 FatalError("Failed to update the input mapping.\n"); 202 #endif 203 #ifdef RT_OS_SOLARIS 204 /* Tell the virtual mouse device about the new virtual desktop size. */ 205 { 206 int rc; 207 int hMouse = open("/dev/mouse", O_RDWR); 208 if (hMouse >= 0) 209 { 210 do { 211 Ms_screen_resolution Res = { height, width }; 212 rc = ioctl(hMouse, MSIOSRESOLUTION, &Res); 213 } while ((rc != 0) && (errno == EINTR)); 214 close(hMouse); 215 } 216 } 217 #endif 218 return TRUE; 118 219 } 119 120 /** Tell the virtual mouse device about the new virtual desktop size. */121 void vbvxSetSolarisMouseRange(int width, int height)122 {123 #ifdef RT_OS_SOLARIS124 int rc;125 int hMouse = open("/dev/mouse", O_RDWR);126 127 if (hMouse >= 0)128 {129 do {130 Ms_screen_resolution Res = { height, width };131 rc = ioctl(hMouse, MSIOSRESOLUTION, &Res);132 } while ((rc != 0) && (errno == EINTR));133 close(hMouse);134 }135 #else136 (void)width; (void)height;137 #endif138 } -
trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
r54530 r54531 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) … … 163 152 VBOXPtr pVBox = (VBOXPtr)xnfcalloc(sizeof(VBOXRec), 1); 164 153 pScrn->driverPrivate = pVBox; 154 #if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX) 155 pVBox->fdACPIDevices = -1; 156 #endif 165 157 } 166 158 } … … 270 262 #endif /* !XORG_7X */ 271 263 272 /** Resize the virtual framebuffer. */273 static Bool adjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height)274 {275 ScreenPtr pScreen = xf86ScrnToScreen(pScrn);276 VBOXPtr pVBox = VBOXGetRec(pScrn);277 int adjustedWidth = pScrn->bitsPerPixel == 16 ? (width + 1) & ~1 : width;278 int cbLine = adjustedWidth * pScrn->bitsPerPixel / 8;279 PixmapPtr pPixmap;280 int rc;281 282 TRACE_LOG("width=%d, height=%d\n", width, height);283 VBVXASSERT(width >= 0 && height >= 0, ("Invalid negative width (%d) or height (%d)\n", width, height));284 if (pScreen == NULL) /* Not yet initialised. */285 return TRUE;286 pPixmap = pScreen->GetScreenPixmap(pScreen);287 VBVXASSERT(pPixmap != NULL, ("Failed to get the screen pixmap.\n"));288 if ( adjustedWidth != pPixmap->drawable.width289 || height != pPixmap->drawable.height)290 {291 if (adjustedWidth > INT16_MAX || height > INT16_MAX || (unsigned)cbLine * (unsigned)height >= pVBox->cbFBMax)292 {293 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,294 "Virtual framebuffer %dx%d too large (%u Kb available).\n",295 adjustedWidth, height, (unsigned) pVBox->cbFBMax / 1024);296 return FALSE;297 }298 vbvxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel,299 adjustedWidth * height * pScrn->bitsPerPixel);300 pScreen->ModifyPixmapHeader(pPixmap, adjustedWidth, height, pScrn->depth, pScrn->bitsPerPixel, cbLine, pVBox->base);301 }302 pScrn->virtualX = adjustedWidth;303 pScrn->virtualY = height;304 pScrn->displayWidth = adjustedWidth;305 pVBox->cbLine = cbLine;306 #ifdef VBOX_DRI_OLD307 if (pVBox->useDRI)308 VBOXDRIUpdateStride(pScrn, pVBox);309 #endif310 return TRUE;311 }312 313 /** Set a video mode to the hardware, RandR 1.1 version. Since we no longer do314 * virtual frame buffers, adjust the screen pixmap dimensions to match. */315 static void setModeRandR11(ScrnInfoPtr pScrn, DisplayModePtr pMode)316 {317 VBOXPtr pVBox = VBOXGetRec(pScrn);318 struct vbvxFrameBuffer frameBuffer = { 0, 0, pMode->HDisplay, pMode->VDisplay, pScrn->bitsPerPixel};319 320 adjustScreenPixmap(pScrn, pMode->HDisplay, pMode->VDisplay);321 if (pMode->HDisplay != 0 && pMode->VDisplay != 0)322 vbvxSetMode(pScrn, 0, pMode->HDisplay, pMode->VDisplay, 0, 0, true, true, &frameBuffer);323 }324 325 264 #ifdef VBOXVIDEO_13 326 265 /* X.org 1.3+ mode-setting support ******************************************/ 327 328 /** Set a video mode to the hardware, RandR 1.2 version. If this is the first329 * screen, re-set the current mode for all others (the offset for the first330 * screen is always treated as zero by the hardware, so all other screens need331 * to be changed to compensate for any changes!). The mode to set is taken332 * from the X.Org Crtc structure. */333 static void setModeRandR12(ScrnInfoPtr pScrn, unsigned cScreen)334 {335 VBOXPtr pVBox = VBOXGetRec(pScrn);336 unsigned i;337 struct vbvxFrameBuffer frameBuffer = { pVBox->pScreens[0].paCrtcs->x, pVBox->pScreens[0].paCrtcs->y, pScrn->virtualX,338 pScrn->virtualY, pScrn->bitsPerPixel };339 unsigned cFirst = cScreen;340 unsigned cLast = cScreen != 0 ? cScreen + 1 : pVBox->cScreens;341 342 for (i = cFirst; i < cLast; ++i)343 if (pVBox->pScreens[i].paCrtcs->mode.HDisplay != 0 && pVBox->pScreens[i].paCrtcs->mode.VDisplay != 0)344 vbvxSetMode(pScrn, i, pVBox->pScreens[i].paCrtcs->mode.HDisplay, pVBox->pScreens[i].paCrtcs->mode.VDisplay,345 pVBox->pScreens[i].paCrtcs->x, pVBox->pScreens[i].paCrtcs->y, pVBox->pScreens[i].fPowerOn,346 pVBox->pScreens[i].paOutputs->status == XF86OutputStatusConnected, &frameBuffer);347 }348 349 /** Wrapper around setModeRandR12() to avoid exposing non-obvious semantics.350 */351 static void setAllModesRandR12(ScrnInfoPtr pScrn)352 {353 setModeRandR12(pScrn, 0);354 }355 266 356 267 /* For descriptions of these functions and structures, see … … 361 272 { 362 273 VBOXPtr pVBox = VBOXGetRec(pScrn); 363 Bool rc;364 unsigned i;365 366 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; 367 278 /* Don't fiddle with the hardware if we are switched 368 279 * to a virtual terminal. */ … … 372 283 return TRUE; 373 284 } 374 rc = adjustScreenPixmap(pScrn, cw, ch); 375 /* Power-on all screens (the server expects this) and set the new pitch to them. */ 376 for (i = 0; i < pVBox->cScreens; ++i) 377 pVBox->pScreens[i].fPowerOn = true; 378 setAllModesRandR12(pScrn); 379 vbvxSetSolarisMouseRange(cw, ch); 380 return rc; 285 return VBOXAdjustScreenPixmap(pScrn, cw, ch); 381 286 } 382 287 … … 388 293 vbox_crtc_dpms(xf86CrtcPtr crtc, int mode) 389 294 { 390 ScrnInfoPtr pScrn = crtc->scrn; 391 VBOXPtr pVBox = VBOXGetRec(pScrn); 295 VBOXPtr pVBox = VBOXGetRec(crtc->scrn); 392 296 unsigned cDisplay = (uintptr_t)crtc->driver_private; 393 394 TRACE_LOG("mode=%d\n", mode); 395 pVBox->pScreens[cDisplay].fPowerOn = (mode != DPMSModeOff); 396 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); 397 315 } 398 316 … … 427 345 TRACE_LOG("name=%s, HDisplay=%d, VDisplay=%d, x=%d, y=%d\n", adjusted_mode->name, 428 346 adjusted_mode->HDisplay, adjusted_mode->VDisplay, x, y); 429 pVBox->pScreens[cDisplay].fPowerOn = true; 347 pVBox->pScreens[cDisplay].fCrtcEnabled = true; 348 pVBox->pScreens[cDisplay].fOutputEnabled = true; 430 349 pVBox->pScreens[cDisplay].aScreenLocation.cx = adjusted_mode->HDisplay; 431 350 pVBox->pScreens[cDisplay].aScreenLocation.cy = adjusted_mode->VDisplay; … … 440 359 return; 441 360 } 442 setModeRandR12(crtc->scrn, cDisplay); 361 VBOXSetMode(crtc->scrn, cDisplay, adjusted_mode->HDisplay, 362 adjusted_mode->VDisplay, x, y); 443 363 } 444 364 … … 482 402 vbox_output_dpms (xf86OutputPtr output, int mode) 483 403 { 484 (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); 485 424 } 486 425 … … 559 498 uint32_t x, y, iScreen; 560 499 iScreen = (uintptr_t)output->driver_private; 500 VBoxUpdateSizeHints(pScrn); 561 501 pMode = vbox_output_add_mode(pVBox, &pModes, NULL, pVBox->pScreens[iScreen].aPreferredSize.cx, 562 502 pVBox->pScreens[iScreen].aPreferredSize.cy, TRUE, FALSE); 563 503 VBOXEDIDSet(output, pMode); 504 /* Add standard modes supported by the host */ 505 for ( ; ; ) 506 { 507 cIndex = vboxNextStandardMode(pScrn, cIndex, &x, &y); 508 if (cIndex == 0) 509 break; 510 vbox_output_add_mode(pVBox, &pModes, NULL, x, y, FALSE, FALSE); 511 } 512 513 /* Also report any modes the user may have requested in the xorg.conf 514 * configuration file. */ 515 for (i = 0; pScrn->display->modes[i] != NULL; i++) 516 { 517 if (2 == sscanf(pScrn->display->modes[i], "%ux%u", &x, &y)) 518 vbox_output_add_mode(pVBox, &pModes, pScrn->display->modes[i], x, y, FALSE, TRUE); 519 } 564 520 TRACE_EXIT(); 565 521 return pModes; … … 661 617 662 618 #ifndef XF86_SCRN_INTERFACE 619 # define xf86ScreenToScrn(pScreen) xf86Screens[(pScreen)->myNum] 620 # define xf86ScrnToScreen(pScrn) screenInfo.screens[(pScrn)->scrnIndex] 663 621 # define SCRNINDEXAPI(pfn) pfn ## Index 664 622 static Bool VBOXScreenInitIndex(int scrnIndex, ScreenPtr pScreen, int argc, … … 931 889 932 890 /* Set the right virtual resolution. */ 933 pScrn->virtualX = pScrn-> bitsPerPixel == 16 ? (pScrn->currentMode->HDisplay + 1) & ~1 : pScrn->currentMode->HDisplay;891 pScrn->virtualX = pScrn->currentMode->HDisplay; 934 892 pScrn->virtualY = pScrn->currentMode->VDisplay; 935 893 … … 937 895 938 896 /* Needed before we initialise DRI. */ 939 p Scrn->displayWidth = pScrn->virtualX;940 p VBox->cbLine = pScrn->virtualX * pScrn->bitsPerPixel / 8;897 pVBox->cbLine = vboxLineLength(pScrn, pScrn->virtualX); 898 pScrn->displayWidth = vboxDisplayPitch(pScrn, pVBox->cbLine); 941 899 942 900 xf86PrintModes(pScrn); … … 1027 985 if (property_name == BAD_RESOURCE) 1028 986 FatalError("Failed to retrieve \"HAS_VT\" atom\n"); 1029 if (ROOT_WINDOW(pScrn) == NULL)1030 return;1031 987 ChangeWindowProperty(ROOT_WINDOW(pScrn), property_name, XA_INTEGER, 32, 1032 988 PropModeReplace, 1, &value, TRUE); 1033 989 } 1034 990 #endif /* SET_HAVE_VT_PROPERTY */ 1035 1036 #ifdef VBOXVIDEO_131037 static void getVirtualSize(ScrnInfoPtr pScrn, int *px, int *py)1038 {1039 VBOXPtr pVBox = VBOXGetRec(pScrn);1040 unsigned i;1041 1042 *px = 0;1043 *py = 0;1044 for (i = 0; i < pVBox->cScreens; ++i)1045 {1046 if (pVBox->pScreens[i].paOutputs->status == XF86OutputStatusConnected)1047 {1048 *px += pVBox->pScreens[i].aPreferredSize.cx;1049 *py = RT_MAX(*py, VBVXCAST(int, pVBox->pScreens[i].aPreferredSize.cy));1050 }1051 }1052 }1053 #endif1054 1055 static void setSizesAndCursorIntegration(ScrnInfoPtr pScrn, bool fScreenInitTime)1056 {1057 VBOXPtr pVBox = VBOXGetRec(pScrn);1058 #ifdef VBOXVIDEO_131059 unsigned i;1060 int x, y;1061 #else1062 DisplayModePtr pNewMode;1063 #endif1064 1065 TRACE_LOG("fScreenInitTime=%d\n", fScreenInitTime);1066 #ifdef VBOXVIDEO_131067 # if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 51068 RRGetInfo(xf86ScrnToScreen(pScrn), TRUE);1069 # else1070 RRGetInfo(xf86ScrnToScreen(pScrn));1071 # endif1072 getVirtualSize(pScrn, &x, &y);1073 if (fScreenInitTime)1074 {1075 pScrn->virtualX = x;1076 pScrn->virtualY = y;1077 }1078 else1079 RRScreenSizeSet(xf86ScrnToScreen(pScrn), x, y, xf86ScrnToScreen(pScrn)->mmWidth, xf86ScrnToScreen(pScrn)->mmHeight);1080 x = 0;1081 for (i = 0; i < pVBox->cScreens; ++i)1082 {1083 if (fScreenInitTime)1084 xf86CrtcSetMode(pVBox->pScreens[i].paCrtcs, pVBox->pScreens[i].paOutputs->probed_modes, RR_Rotate_0, x, 0);1085 else1086 RRCrtcSet(pVBox->pScreens[i].paCrtcs->randr_crtc, pVBox->pScreens[i].paOutputs->randr_output->modes[0], x, 0,1087 RR_Rotate_0, 1, &pVBox->pScreens[i].paOutputs->randr_output);1088 if (pVBox->pScreens[i].paOutputs->status == XF86OutputStatusConnected)1089 x += pVBox->pScreens[i].aPreferredSize.cx;1090 }1091 #else /* !VBOXVIDEO_13 */1092 pNewMode = pScrn->modes != pScrn->currentMode ? pScrn->modes : pScrn->modes->next;1093 pNewMode->HDisplay = pVBox->pScreens[0].aPreferredSize.cx;1094 pNewMode->VDisplay = pVBox->pScreens[0].aPreferredSize.cy;1095 #endif1096 vbvxReprobeCursor(pScrn);1097 }1098 1099 /* We update the size hints from the X11 property set by VBoxClient every time1100 * that the X server goes to sleep (to catch the property change request).1101 * Although this is far more often than necessary it should not have real-life1102 * performance consequences and allows us to simplify the code quite a bit. */1103 static void updateSizeHintsBlockHandler(pointer pData, OSTimePtr pTimeout, pointer pReadmask)1104 {1105 ScrnInfoPtr pScrn = (ScrnInfoPtr)pData;1106 VBOXPtr pVBox = VBOXGetRec(pScrn);1107 bool fNeedUpdate;1108 1109 (void)pTimeout;1110 (void)pReadmask;1111 if (!pScrn->vtSema || ROOT_WINDOW(pScrn) == NULL)1112 return;1113 vbvxReadSizesAndCursorIntegrationFromProperties(pScrn, &fNeedUpdate);1114 if (fNeedUpdate || pVBox->fForceModeUpdate)1115 setSizesAndCursorIntegration(pScrn, false);1116 }1117 1118 /* We update the size hints from the host every time that the X server is woken1119 * up by a client. Although this is far more often than necessary it should1120 * not have real-life performance consequences and allows us to simplify the1121 * code quite a bit. */1122 static void updateSizeHintsWakeupHandler(pointer pData, int i, pointer pLastSelectMask)1123 {1124 #ifdef VBOXVIDEO_131125 ScrnInfoPtr pScrn = (ScrnInfoPtr)pData;1126 bool fNeedUpdate;1127 1128 (void)i;1129 (void)pLastSelectMask;1130 if (!pScrn->vtSema || ROOT_WINDOW(pScrn) == NULL)1131 return;1132 vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, &fNeedUpdate);1133 if (fNeedUpdate)1134 setSizesAndCursorIntegration(pScrn, false);1135 #else1136 (void)pData; (void)i; (void)pLastSelectMask;1137 #endif1138 }1139 991 1140 992 /* … … 1210 1062 pScrn->vtSema = TRUE; 1211 1063 1212 if (!VBoxHGSMIIsSupported()) 1213 { 1214 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Graphics device too old to support.\n"); 1215 return FALSE; 1216 } 1217 vbvxSetUpHGSMIHeapInGuest(pVBox, pScrn->videoRam * 1024); 1218 pVBox->cScreens = VBoxHGSMIGetMonitorCount(&pVBox->guestCtx); 1219 pVBox->pScreens = xnfcalloc(pVBox->cScreens, sizeof(*pVBox->pScreens)); 1220 pVBox->paVBVAModeHints = xnfcalloc(pVBox->cScreens, sizeof(*pVBox->paVBVAModeHints)); 1221 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested monitor count: %u\n", pVBox->cScreens); 1064 #if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX) 1065 VBoxSetUpLinuxACPI(pScreen); 1066 #endif 1067 1068 vbox_open (pScrn, pScreen, pVBox); 1222 1069 vboxEnableVbva(pScrn); 1223 /* Set up the dirty rectangle handler. It will be added into a function1224 * chain and gets removed when the screen is cleaned up. */1225 if (ShadowFBInit2(pScreen, NULL, vbvxHandleDirtyRect) != TRUE)1226 return FALSE;1227 1070 VBoxInitialiseSizeHints(pScrn); 1228 /* Get any screen size hints from HGSMI. Do not yet try to access X111229 * properties, as they are not yet set up, and nor are the clients that1230 * might have set them. */1231 vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, NULL);1232 1071 1233 1072 #ifdef VBOXVIDEO_13 … … 1265 1104 /* Set a sane minimum and maximum mode size to match what the hardware 1266 1105 * supports. */ 1267 xf86CrtcSetSizeRange(pScrn, 64, 64, VBE_DISPI_MAX_XRES, VBE_DISPI_MAX_YRES);1106 xf86CrtcSetSizeRange(pScrn, 64, 64, 16384, 16384); 1268 1107 1269 1108 /* Now create our initial CRTC/output configuration. */ … … 1273 1112 } 1274 1113 1275 /* Initialise randr 1.2 mode-setting functions. */ 1114 /* Initialise randr 1.2 mode-setting functions and set first mode. 1115 * Note that the mode won't be usable until the server has resized the 1116 * framebuffer to something reasonable. */ 1276 1117 if (!xf86CrtcScreenInit(pScreen)) { 1277 1118 return FALSE; 1278 1119 } 1279 1120 1280 setSizesAndCursorIntegration(pScrn, true); 1121 if (!xf86SetDesiredModes(pScrn)) { 1122 return FALSE; 1123 } 1281 1124 #else /* !VBOXVIDEO_13 */ 1125 VBoxSetUpRandR11(pScreen); 1282 1126 /* set first video mode */ 1283 if (!VBOXSwitchMode(pScrn, pScrn->currentMode)) 1127 if (!VBOXSetMode(pScrn, 0, pScrn->currentMode->HDisplay, 1128 pScrn->currentMode->VDisplay, pScrn->frameX0, 1129 pScrn->frameY0)) 1284 1130 return FALSE; 1285 #endif 1286 1287 /* Register block and wake-up handlers for getting new screen size hints. */ 1288 RegisterBlockAndWakeupHandlers(updateSizeHintsBlockHandler, updateSizeHintsWakeupHandler, (pointer)pScrn); 1131 /* Save the size in case we need to re-set it later. */ 1132 pVBox->FBSize.cx = pScrn->currentMode->HDisplay; 1133 pVBox->FBSize.cy = pScrn->currentMode->VDisplay; 1134 pVBox->pScreens[0].aScreenLocation.cx = pScrn->currentMode->HDisplay; 1135 pVBox->pScreens[0].aScreenLocation.cy = pScrn->currentMode->VDisplay; 1136 pVBox->pScreens[0].aScreenLocation.x = pScrn->frameX0; 1137 pVBox->pScreens[0].aScreenLocation.y = pScrn->frameY0; 1138 #endif /* !VBOXVIDEO_13 */ 1289 1139 1290 1140 /* software cursor */ … … 1337 1187 1338 1188 TRACE_ENTRY(); 1189 vboxClearVRAM(pScrn, 0, 0); 1339 1190 #ifdef VBOX_DRI_OLD 1340 1191 if (pVBox->useDRI) … … 1347 1198 } 1348 1199 #endif 1349 vbvxSetUpHGSMIHeapInGuest(pVBox, pScrn->videoRam * 1024);1350 1200 vboxEnableVbva(pScrn); 1351 /* Re-set video mode */ 1352 vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, NULL); 1353 vbvxReadSizesAndCursorIntegrationFromProperties(pScrn, NULL); 1354 setSizesAndCursorIntegration(pScrn, false); 1201 /* Re-assert this in case we had a change request while switched out. */ 1202 if (pVBox->FBSize.cx && pVBox->FBSize.cy) 1203 VBOXAdjustScreenPixmap(pScrn, pVBox->FBSize.cx, pVBox->FBSize.cy); 1204 #ifdef VBOXVIDEO_13 1205 if (!xf86SetDesiredModes(pScrn)) 1206 return FALSE; 1207 #else 1208 if (!VBOXSetMode(pScrn, 0, pScrn->currentMode->HDisplay, 1209 pScrn->currentMode->VDisplay, pScrn->frameX0, 1210 pScrn->frameY0)) 1211 return FALSE; 1212 #endif 1355 1213 #ifdef SET_HAVE_VT_PROPERTY 1356 1214 updateHasVTProperty(pScrn, TRUE); … … 1372 1230 #endif 1373 1231 vboxDisableVbva(pScrn); 1374 vb vxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel, 0);1232 vboxClearVRAM(pScrn, 0, 0); 1375 1233 #ifdef VBOX_DRI_OLD 1376 1234 if (pVBox->useDRI) … … 1403 1261 #endif 1404 1262 vboxDisableVbva(pScrn); 1405 vb vxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel, 0);1263 vboxClearVRAM(pScrn, 0, 0); 1406 1264 } 1407 1265 #ifdef VBOX_DRI … … 1429 1287 1430 1288 pScreen->CloseScreen = pVBox->CloseScreen; 1289 #if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX) 1290 VBoxCleanUpLinuxACPI(pScreen); 1291 #endif 1431 1292 #ifndef XF86_SCRN_INTERFACE 1432 1293 return pScreen->CloseScreen(pScreen->myNum, pScreen); … … 1439 1300 { 1440 1301 VBOXPtr pVBox; 1441 Bool rc = TRUE;1302 Bool rc; 1442 1303 1443 1304 TRACE_LOG("HDisplay=%d, VDisplay=%d\n", pMode->HDisplay, pMode->VDisplay); 1305 #ifndef VBOXVIDEO_13 1306 pVBox = VBOXGetRec(pScrn); 1307 /* Save the size in case we need to re-set it later. */ 1308 pVBox->FBSize.cx = pMode->HDisplay; 1309 pVBox->FBSize.cy = pMode->VDisplay; 1310 pVBox->pScreens[0].aScreenLocation.cx = pMode->HDisplay; 1311 pVBox->pScreens[0].aScreenLocation.cy = pMode->VDisplay; 1312 pVBox->pScreens[0].aScreenLocation.x = pScrn->frameX0; 1313 pVBox->pScreens[0].aScreenLocation.y = pScrn->frameY0; 1314 #endif 1444 1315 if (!pScrn->vtSema) 1445 1316 { … … 1451 1322 rc = xf86SetSingleMode(pScrn, pMode, RR_Rotate_0); 1452 1323 #else 1453 setModeRandR11(pScrn, pMode); 1324 VBOXAdjustScreenPixmap(pScrn, pMode->HDisplay, pMode->VDisplay); 1325 rc = VBOXSetMode(pScrn, 0, pMode->HDisplay, pMode->VDisplay, 1326 pScrn->frameX0, pScrn->frameY0); 1454 1327 #endif 1455 1328 TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE"); … … 1458 1331 1459 1332 static void VBOXAdjustFrame(ScrnInfoPtr pScrn, int x, int y) 1460 { (void)pScrn; (void)x; (void)y; } 1333 { 1334 VBOXPtr pVBox = VBOXGetRec(pScrn); 1335 1336 TRACE_ENTRY(); 1337 pVBox->pScreens[0].aScreenLocation.x = x; 1338 pVBox->pScreens[0].aScreenLocation.y = y; 1339 /* Don't fiddle with the hardware if we are switched 1340 * to a virtual terminal. */ 1341 if (!pScrn->vtSema) 1342 { 1343 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1344 "We do not own the active VT, exiting.\n"); 1345 return; 1346 } 1347 VBOXSetMode(pScrn, 0, pVBox->pScreens[0].aScreenLocation.cx, 1348 pVBox->pScreens[0].aScreenLocation.cy, x, y); 1349 TRACE_EXIT(); 1350 } 1461 1351 1462 1352 static void VBOXFreeScreen(ScrnInfoPtr pScrn) -
trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
r54530 r54531 96 96 } 97 97 98 #define VBVXCAST(type, val) \99 ((long long)(type)(val) == (long long)(val) \100 && (unsigned long long)(type)(val) == (unsigned long long)(val) \101 ? ((type)(val)) \102 : (vbvxMsg("Cannot convert " #val " to " #type ".\n"), vbvxAbortServer(), 0))103 104 98 #define BOOL_STR(a) ((a) ? "TRUE" : "FALSE") 105 99 … … 154 148 RTRECT2 aScreenLocation; 155 149 /** Is this CRTC enabled or in DPMS off state? */ 156 Bool fPowerOn; 150 Bool fCrtcEnabled; 151 /** Is this output enabled or in DPMS low power state? */ 152 Bool fOutputEnabled; 157 153 #ifdef VBOXVIDEO_13 158 154 /** The virtual crtcs. */ … … 169 165 /** Has this screen been enabled by the host? */ 170 166 Bool afConnected; 171 Bool afLastConnected; 167 /** The last mode hint data read from the X11 property. */ 168 int32_t lastModeHintFromProperty; 172 169 }; 173 170 … … 201 198 /** Do we currently want to use the host cursor? */ 202 199 Bool fUseHardwareCursor; 200 /** The last cursor capabilities data read from the X11 property. */ 201 int32_t fLastCursorCapabilitiesFromProperty; 203 202 /** Number of screens attached */ 204 203 uint32_t cScreens; 205 204 /** Information about each virtual screen. */ 206 205 struct VBoxScreen *pScreens; 207 /** Can we get mode hint and cursor integration information from HGSMI? */ 208 bool fHaveHGSMIModeHints; 206 /** The last requested framebuffer size. */ 207 RTRECTSIZE FBSize; 208 #ifdef VBOXVIDEO_13 209 209 /** Array of structures for receiving mode hints. */ 210 210 VBVAMODEHINT *paVBVAModeHints; 211 /** Should we force a screen mode update next time the handler is called? */ 212 bool fForceModeUpdate; 211 # ifdef RT_OS_LINUX 212 /** Input device file descriptor for getting ACPI hot-plug events. */ 213 int fdACPIDevices; 214 /** Input handler handle for ACPI hot-plug listener. */ 215 void *hACPIEventHandler; 216 # endif 217 /** Have we read all available HGSMI mode hint data? */ 218 bool fHaveReadHGSMIModeHintData; 219 #else 220 /** The original CreateScreenResources procedure which we wrap with our own. 221 */ 222 CreateScreenResourcesProcPtr pfnCreateScreenResources; 223 #endif 213 224 /** HGSMI guest heap context */ 214 225 HGSMIGUESTCOMMANDCONTEXT guestCtx; … … 233 244 #define VBOXGetRec vbvxGetRec /* Temporary */ 234 245 extern int vbvxGetIntegerPropery(ScrnInfoPtr pScrn, char *pszName, size_t *pcData, int32_t **ppaData); 235 extern void vbvxSetIntegerPropery(ScrnInfoPtr pScrn, char *pszName, size_t cData, int32_t *paData, Bool fSendEvent);236 246 extern void vbvxReprobeCursor(ScrnInfoPtr pScrn); 237 247 238 248 /* setmode.c */ 239 240 /** Structure describing the virtual frame buffer. It starts at the beginning241 * of the video RAM. */242 struct vbvxFrameBuffer {243 /** X offset of first screen in frame buffer. */244 int x0;245 /** Y offset of first screen in frame buffer. */246 int y0;247 /** Frame buffer virtual width. */248 unsigned cWidth;249 /** Frame buffer virtual height. */250 unsigned cHeight;251 /** Bits per pixel. */252 unsigned cBPP;253 };254 255 extern void vbvxClearVRAM(ScrnInfoPtr pScrn, size_t cbOldSize, size_t cbNewSize);256 extern void vbvxSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth, unsigned cHeight, int x, int y, bool fEnabled,257 bool fConnected, struct vbvxFrameBuffer *pFrameBuffer);258 extern void vbvxSetSolarisMouseRange(int width, int height);259 260 /* pointer.c */261 249 extern Bool vbox_cursor_init (ScreenPtr pScreen); 250 extern void vbox_open (ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox); 262 251 extern void vbox_close (ScrnInfoPtr pScrn, VBOXPtr pVBox); 263 252 264 /* vbva.c */265 extern void vbvxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects);266 extern void vbvxSetUpHGSMIHeapInGuest(VBOXPtr pVBox, uint32_t cbVRAM);267 253 extern Bool vboxEnableVbva(ScrnInfoPtr pScrn); 268 254 extern void vboxDisableVbva(ScrnInfoPtr pScrn); 269 255 270 256 /* getmode.c */ 257 extern unsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex, 258 uint32_t *pcx, uint32_t *pcy); 271 259 extern void vboxAddModes(ScrnInfoPtr pScrn); 272 260 extern void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn); 273 extern void vbvxReadSizesAndCursorIntegrationFromProperties(ScrnInfoPtr pScrn, bool *pfNeedUpdate); 274 extern void vbvxReadSizesAndCursorIntegrationFromHGSMI(ScrnInfoPtr pScrn, bool *pfNeedUpdate); 261 extern void VBoxUpdateSizeHints(ScrnInfoPtr pScrn); 262 #ifndef VBOXVIDEO_13 263 extern void VBoxSetUpRandR11(ScreenPtr pScreen); 264 #else 265 void VBoxSetUpLinuxACPI(ScreenPtr pScreen); 266 void VBoxCleanUpLinuxACPI(ScreenPtr pScreen); 267 #endif 275 268 276 269 /* DRI stuff */ … … 286 279 #endif 287 280 281 /* Utilities */ 282 283 /** Calculate the BPP from the screen depth */ 284 static inline uint16_t vboxBPP(ScrnInfoPtr pScrn) 285 { 286 return pScrn->depth == 24 ? 32 : 16; 287 } 288 289 /** Calculate the scan line length for a display width */ 290 static inline int32_t vboxLineLength(ScrnInfoPtr pScrn, int32_t cDisplayWidth) 291 { 292 uint32_t cbLine = (cDisplayWidth * vboxBPP(pScrn) / 8 + 3) & ~3; 293 return cbLine < INT32_MAX ? cbLine : INT32_MAX; 294 } 295 296 /** Calculate the display pitch from the scan line length */ 297 static inline int32_t vboxDisplayPitch(ScrnInfoPtr pScrn, int32_t cbLine) 298 { 299 return cbLine * 8 / vboxBPP(pScrn); 300 } 301 302 extern void vboxClearVRAM(ScrnInfoPtr pScrn, int32_t cNewX, int32_t cNewY); 303 extern Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth, 304 unsigned cHeight, int x, int y); 305 extern Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height); 306 288 307 #endif /* _VBOXVIDEO_H_ */ 289 308 -
trunk/src/VBox/Additions/x11/vboxvideo/vbva.c
r54530 r54531 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; 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"); 184 241 } 185 242 … … 195 252 { 196 253 bool rc = TRUE; 254 int scrnIndex = pScrn->scrnIndex; 197 255 unsigned i; 198 256 VBOXPtr pVBox = pScrn->driverPrivate; 199 257 200 258 TRACE_ENTRY(); 201 if (!vboxSetupVRAMVbva(p VBox))259 if (!vboxSetupVRAMVbva(pScrn, pVBox)) 202 260 return FALSE; 203 261 for (i = 0; i < pVBox->cScreens; ++i) … … 211 269 rc = FALSE; 212 270 } 213 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 } 214 278 #ifdef VBOXVIDEO_13 215 VBoxHGSMISendCapsInfo(&pVBox->guestCtx, VBVACAPS_VIDEO_MODE_HINTS | VBVACAPS_DISABLE_CURSOR_INTEGRATION); 216 pVBox->fHaveHGSMIModeHints = haveHGSMIModeHintAndCursorReportingInterface(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 217 285 #endif 218 286 return rc; … … 231 299 { 232 300 int rc; 301 int scrnIndex = pScrn->scrnIndex; 233 302 unsigned i; 234 303 VBOXPtr pVBox = pScrn->driverPrivate;
Note:
See TracChangeset
for help on using the changeset viewer.