Changeset 57356 in vbox
- Timestamp:
- Aug 14, 2015 3:03:30 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 102119
- Location:
- trunk/src/VBox/Additions/x11
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/display.cpp
r56322 r57356 26 26 #include <X11/Xatom.h> 27 27 28 #include <iprt/asm.h> 28 29 #include <iprt/assert.h> 29 30 #include <iprt/err.h> … … 54 55 bool fEnabled; 55 56 bool fUpdateSize; 56 bool fUpdatePosition;57 volatile bool fUpdatePosition; 57 58 }; 58 59 … … 84 85 }; 85 86 86 /** Tell the VBoxGuest driver we no longer want any events and tell the host 87 * we no longer support any capabilities. */ 88 static int disableEventsAndCaps(bool fDisableEvents) 89 { 90 int rc = VbglR3SetGuestCaps(0, VMMDEV_GUEST_SUPPORTS_GRAPHICS); 91 if (RT_FAILURE(rc)) 92 VBClFatalError(("Failed to unset graphics capability, rc=%Rrc.\n", rc)); 93 rc = VbglR3SetMouseStatus(VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR); 94 if (RT_FAILURE(rc)) 95 VBClFatalError(("Failed to unset mouse status, rc=%Rrc.\n", rc)); 96 if (fDisableEvents) 97 rc = VbglR3CtlFilterMask(0, VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED | VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST); 98 if (RT_FAILURE(rc)) 99 VBClFatalError(("Failed to unset filter mask, rc=%Rrc.\n", rc)); 100 return VINF_SUCCESS; 101 } 102 103 /** Tell the VBoxGuest driver which events we want and tell the host which 104 * capabilities we support. */ 105 static int enableEventsAndCaps() 106 { 107 int rc = VbglR3CtlFilterMask( VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED 108 | VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, 0); 109 if (RT_FAILURE(rc)) 110 VBClFatalError(("Failed to set filter mask, rc=%Rrc.\n", rc)); 111 rc = VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0); 112 if (RT_FAILURE(rc)) 113 VBClFatalError(("Failed to set graphics capability, rc=%Rrc.\n", rc)); 114 rc = VbglR3SetMouseStatus(0); 115 if (RT_FAILURE(rc)) 116 VBClFatalError(("Failed to set mouse status, rc=%Rrc.\n", rc)); 87 /** Thread to monitor and react to X server VT switches and exits. */ 88 static int pfnMonitorThread(RTTHREAD self, void *pvUser) 89 { 90 struct DISPLAYSTATE *pState = (struct DISPLAYSTATE *)pvUser; 91 Display *pDisplay; 92 bool fHasVT = true; 93 94 pDisplay = XOpenDisplay(NULL); 95 if (!pDisplay) 96 VBClFatalError(("Failed to open the X11 display\n")); 97 XSelectInput(pDisplay, DefaultRootWindow(pDisplay), PropertyChangeMask); 98 while (true) 99 { 100 XEvent event; 101 102 XNextEvent(pDisplay, &event); 103 /* This property is deleted when the server regains the virtual 104 * terminal. Force the main thread to call xrandr again, as old X 105 * servers could not handle it while switched out. */ 106 if (pState->fHaveRandR12) 107 continue; 108 if ( event.type != PropertyNotify 109 || event.xproperty.state != PropertyDelete 110 || event.xproperty.window != DefaultRootWindow(pDisplay) 111 || event.xproperty.atom != XInternAtom(pDisplay, "VBOXVIDEO_NO_VT", False)) 112 continue; 113 LogRel(("VBoxClient/Display: entered virtual terminal.\n")); 114 ASMAtomicWriteBool(&pState->paScreenInformation[0].fUpdateSize, true); 115 VbglR3InterruptEventWaits(); 116 } 117 return VINF_SUCCESS; /* Should never be reached. */ 118 } 119 120 static int startMonitorThread(struct DISPLAYSTATE *pState) 121 { 122 int rc; 123 124 rc = RTThreadCreate(NULL, pfnMonitorThread, (void *)pState, 0, RTTHREADTYPE_INFREQUENT_POLLER, 0, "VT_MONITOR"); 125 if (rc != VINF_SUCCESS) 126 VBClFatalError(("Failed to start the VT monitor thread, rc=%Rrc\n", rc)); 117 127 return VINF_SUCCESS; 118 128 } … … 209 219 && pState->paScreenInformation[0].cx > 0 && pState->paScreenInformation[0].cy > 0) 210 220 { 221 int ret; 222 211 223 RTStrPrintf(szCommand, sizeof(szCommand), "%s -s %ux%u", 212 224 pState->pcszXrandr, pState->paScreenInformation[0].cx, pState->paScreenInformation[0].cy); 213 system(szCommand); 225 ret = system(szCommand); 226 LogRel(("VBoxClient/Display: executed \"%s\", returned %d.\n", szCommand, ret)); 214 227 pState->paScreenInformation[0].fUpdateSize = false; 215 228 } … … 238 251 int rc; 239 252 unsigned i, cScreensTracked; 253 uint32_t fModeSet = false; 240 254 241 255 LogRelFlowFunc(("\n")); … … 262 276 } 263 277 } 278 /* Semantics: when VBOX_HAS_GRAPHICS is set, the X server driver assumes 279 * that a client capable of forwarding mode hints will be present for the 280 * rest of the X session. If we crash things will not work as they should. 281 * I thought that preferable to implementing complex crash-handling logic. 282 */ 283 XChangeProperty(pState->pDisplay, DefaultRootWindow(pState->pDisplay), XInternAtom(pState->pDisplay, "VBOX_HAS_GRAPHICS", 0), 284 XA_INTEGER, 32, PropModeReplace, (unsigned char *)&fModeSet, 1); 264 285 while (true) 265 286 { … … 333 354 if (RT_FAILURE(rc)) 334 355 return rc; 335 rc = enableEventsAndCaps(); 356 rc = VbglR3CtlFilterMask(VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED | VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, 0); 357 if (RT_FAILURE(rc)) 358 VBClFatalError(("Failed to set filter mask, rc=%Rrc.\n", rc)); 336 359 if (RT_SUCCESS(rc)) 337 360 pSelf->mfInit = true; … … 346 369 if (!pSelf->mfInit) 347 370 return VERR_WRONG_ORDER; 348 rc = VBClStartVTMonitor();371 rc = startMonitorThread(pSelf); 349 372 if (RT_FAILURE(rc)) 350 373 VBClFatalError(("Failed to start the VT monitor thread: %Rrc\n", rc)); … … 353 376 } 354 377 355 static int pause(struct VBCLSERVICE **ppInterface)356 {357 struct DISPLAYSTATE *pSelf = getStateFromInterface(ppInterface);358 359 if (!pSelf->mfInit)360 return VERR_WRONG_ORDER;361 return disableEventsAndCaps(false);362 }363 364 static int resume(struct VBCLSERVICE **ppInterface)365 {366 struct DISPLAYSTATE *pSelf = getStateFromInterface(ppInterface);367 int rc;368 369 if (!pSelf->mfInit)370 return VERR_WRONG_ORDER;371 rc = enableEventsAndCaps();372 /* RandR 1.1-based drivers only let us change mode when we are not switched373 * out, so interrupt the wait when we switch in and re-set it. */374 VbglR3InterruptEventWaits();375 return rc;376 }377 378 378 static void cleanup(struct VBCLSERVICE **ppInterface) 379 379 { 380 380 NOREF(ppInterface); 381 disableEventsAndCaps(true);381 VbglR3CtlFilterMask(0, VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED | VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST); 382 382 VbglR3Term(); 383 383 } … … 388 388 init, 389 389 run, 390 pause,391 resume,390 VBClServiceDefaultHandler, /* pause */ 391 VBClServiceDefaultHandler, /* resume */ 392 392 cleanup 393 393 }; -
trunk/src/VBox/Additions/x11/undefined_xfree86
r52651 r57356 83 83 defaultDPMSEnabled 84 84 DeleteCallback 85 DeleteProperty 85 86 DeliverEvents 86 87 deltaSaveUndersViewable -
trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
r57180 r57356 57 57 #include "vboxvideo.h" 58 58 #include <VBox/VBoxGuest.h> 59 #include <VBox/VBoxGuestLib.h> 59 60 #include <VBox/Hardware/VBoxVideoVBE.h> 60 61 #include "version-generated.h" … … 98 99 # include <stdlib.h> 99 100 # include <string.h> 100 #endif101 102 /* This was accepted upstream in X.Org Server 1.16 which bumped the video103 * driver ABI to 17. */104 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 17105 # define SET_HAVE_VT_PROPERTY106 101 #endif 107 102 … … 300 295 301 296 /** Set a video mode to the hardware, RandR 1.1 version. Since we no longer do 302 * virtual frame buffers, adjust the screen pixmap dimensions to match. */ 303 static void setModeRandR11(ScrnInfoPtr pScrn, DisplayModePtr pMode, bool fScreenInitTime, bool fEnterVTTime) 297 * virtual frame buffers, adjust the screen pixmap dimensions to match. The 298 * "override" parameters are for when we received a mode hint while switched to 299 * a virtual terminal. In this case VBoxClient will have told us about the 300 * mode, but not yet been able to do a mode switch using RandR. We solve this 301 * by setting the requested mode to the host but keeping the virtual frame- 302 * buffer matching what the X server expects. */ 303 static void setModeRandR11(ScrnInfoPtr pScrn, DisplayModePtr pMode, bool fScreenInitTime, bool fEnterVTTime, 304 int cXOverRide, int cYOverRide) 304 305 { 305 306 VBOXPtr pVBox = VBOXGetRec(pScrn); 306 307 struct vbvxFrameBuffer frameBuffer = { 0, 0, pMode->HDisplay, pMode->VDisplay, pScrn->bitsPerPixel}; 308 int cXPhysical = cXOverRide > 0 ? min(cXOverRide, pMode->HDisplay) : pMode->HDisplay; 309 int cYPhysical = cYOverRide > 0 ? min(cYOverRide, pMode->VDisplay) : pMode->VDisplay; 307 310 308 311 pVBox->pScreens[0].aScreenLocation.cx = pMode->HDisplay; … … 330 333 } 331 334 if (pMode->HDisplay != 0 && pMode->VDisplay != 0 && pScrn->vtSema) 332 vbvxSetMode(pScrn, 0, pMode->HDisplay, pMode->VDisplay, 0, 0, true, true, &frameBuffer);335 vbvxSetMode(pScrn, 0, cXPhysical, cYPhysical, 0, 0, true, true, &frameBuffer); 333 336 pScrn->currentMode = pMode; 334 337 } … … 996 999 } 997 1000 998 #define HAS_VT_ATOM_NAME "XFree86_has_VT" 999 #define VBOXVIDEO_DRIVER_ATOM_NAME "VBOXVIDEO_DRIVER_IN_USE" 1000 /* The memory storing the initial value of the XFree86_has_VT root window 1001 * property. This has to remain available until server start-up, so we just 1002 * use a global. */ 1003 static CARD32 InitialPropertyValue = 1; 1004 1005 /** Initialise a flag property on the root window to say whether the server VT 1006 * is currently the active one as some clients need to know this. */ 1007 static void initialiseProperties(ScrnInfoPtr pScrn) 1008 { 1009 Atom atom = -1; 1010 CARD32 *PropertyValue = &InitialPropertyValue; 1011 #ifdef SET_HAVE_VT_PROPERTY 1012 atom = MakeAtom(HAS_VT_ATOM_NAME, sizeof(HAS_VT_ATOM_NAME) - 1, TRUE); 1013 if (xf86RegisterRootWindowProperty(pScrn->scrnIndex, atom, XA_INTEGER, 1014 32, 1, PropertyValue) != Success) 1015 FatalError("vboxvideo: failed to register VT property\n"); 1016 #endif /* SET_HAVE_VT_PROPERTY */ 1017 atom = MakeAtom(VBOXVIDEO_DRIVER_ATOM_NAME, 1018 sizeof(VBOXVIDEO_DRIVER_ATOM_NAME) - 1, TRUE); 1019 if (xf86RegisterRootWindowProperty(pScrn->scrnIndex, atom, XA_INTEGER, 1020 32, 1, PropertyValue) != Success) 1021 FatalError("vboxvideo: failed to register driver in use property\n"); 1022 } 1023 1024 #ifdef SET_HAVE_VT_PROPERTY 1025 /** Update a flag property on the root window to say whether the server VT 1026 * is currently the active one as some clients need to know this. */ 1027 static void updateHasVTProperty(ScrnInfoPtr pScrn, Bool hasVT) 1028 { 1029 Atom property_name; 1030 int32_t value = hasVT ? 1 : 0; 1031 int i; 1032 1033 property_name = MakeAtom(HAS_VT_ATOM_NAME, sizeof(HAS_VT_ATOM_NAME) - 1, 1034 FALSE); 1035 if (property_name == BAD_RESOURCE) 1036 FatalError("Failed to retrieve \"HAS_VT\" atom\n"); 1037 if (ROOT_WINDOW(pScrn) == NULL) 1001 /** Set the graphics and guest cursor support capabilities to the host if 1002 * the user-space helper is running. */ 1003 static void updateGraphicsCapability(ScrnInfoPtr pScrn, Bool hasVT) 1004 { 1005 VBOXPtr pVBox = VBOXGetRec(pScrn); 1006 size_t cData; 1007 int32_t *paData; 1008 int rc; 1009 1010 if (pVBox->fHaveHGSMIModeHints) 1038 1011 return; 1039 ChangeWindowProperty(ROOT_WINDOW(pScrn), property_name, XA_INTEGER, 32, 1040 PropModeReplace, 1, &value, TRUE); 1041 } 1042 #endif /* SET_HAVE_VT_PROPERTY */ 1012 rc = vbvxGetIntegerPropery(pScrn, "VBOX_HAS_GRAPHICS", &cData, &paData); 1013 if (rc != VINF_SUCCESS || cData != 1) 1014 return; 1015 if (RT_BOOL(*paData) != hasVT) 1016 { 1017 uint32_t fFeatures; 1018 VbglR3SetGuestCaps(hasVT ? VMMDEV_GUEST_SUPPORTS_GRAPHICS : 0, hasVT ? 0 : VMMDEV_GUEST_SUPPORTS_GRAPHICS); 1019 rc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL); 1020 fFeatures &= VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE | VMMDEV_MOUSE_NEW_PROTOCOL; 1021 if (RT_SUCCESS(rc)) 1022 VbglR3SetMouseStatus(hasVT ? fFeatures : fFeatures | VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR); 1023 } 1024 *paData = hasVT; 1025 } 1043 1026 1044 1027 #ifdef VBOXVIDEO_13 … … 1169 1152 * Although this is far more often than necessary it should not have real-life 1170 1153 * performance consequences and allows us to simplify the code quite a bit. */ 1171 static void updateSizeHintsBlockHandler(pointer pData, OSTimePtr pTimeout, pointer pReadmask)1154 static void vboxBlockHandler(pointer pData, OSTimePtr pTimeout, pointer pReadmask) 1172 1155 { 1173 1156 ScrnInfoPtr pScrn = (ScrnInfoPtr)pData; … … 1177 1160 (void)pTimeout; 1178 1161 (void)pReadmask; 1179 if (!pScrn->vtSema) 1180 return; 1181 vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, &fNeedUpdate); 1162 updateGraphicsCapability(pScrn, pScrn->vtSema); 1163 if (pScrn->vtSema) 1164 vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, &fNeedUpdate); 1165 /* This has to be done even when we are switched out so that VBoxClient can 1166 * set a mode using RandR without having to know the virtual terminal state. 1167 */ 1182 1168 if (ROOT_WINDOW(pScrn) != NULL) 1183 1169 vbvxReadSizesAndCursorIntegrationFromProperties(pScrn, &fNeedUpdate); … … 1208 1194 TRACE_ENTRY(); 1209 1195 1196 /* Initialise our guest library if possible: ignore failure. */ 1197 VbglR3Init(); 1210 1198 if (!VBOXMapVidMem(pScrn)) 1211 1199 return (FALSE); … … 1340 1328 #else 1341 1329 /* set first video mode */ 1342 setModeRandR11(pScrn, pScrn->currentMode, true, false );1330 setModeRandR11(pScrn, pScrn->currentMode, true, false, 0, 0); 1343 1331 #endif 1344 1332 1345 1333 /* Register block and wake-up handlers for getting new screen size hints. */ 1346 RegisterBlockAndWakeupHandlers( updateSizeHintsBlockHandler, (WakeupHandlerProcPtr)NoopDDA, (pointer)pScrn);1334 RegisterBlockAndWakeupHandlers(vboxBlockHandler, (WakeupHandlerProcPtr)NoopDDA, (pointer)pScrn); 1347 1335 1348 1336 /* software cursor */ … … 1385 1373 #endif 1386 1374 1387 initialiseProperties(pScrn);1388 1389 1375 return (TRUE); 1390 1376 } 1391 1377 1378 #define NO_VT_ATOM_NAME "VBOXVIDEO_NO_VT" 1379 1392 1380 static Bool VBOXEnterVT(ScrnInfoPtr pScrn) 1393 1381 { 1394 1382 VBOXPtr pVBox = VBOXGetRec(pScrn); 1383 #ifndef VBOXVIDEO_13 1384 /* If we got a mode request while we were switched out, temporarily override 1385 * the physical mode set to the device while keeping things consistent from 1386 * the server's point of view. */ 1387 int cXOverRide = RT_CLAMP(pVBox->pScreens[0].aPreferredSize.cx, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL); 1388 int cYOverRide = RT_CLAMP(pVBox->pScreens[0].aPreferredSize.cy, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL); 1389 #endif 1395 1390 1396 1391 TRACE_ENTRY(); 1392 updateGraphicsCapability(pScrn, TRUE); 1397 1393 #ifdef VBOX_DRI_OLD 1398 1394 if (pVBox->useDRI) … … 1410 1406 #ifdef VBOXVIDEO_13 1411 1407 vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, NULL); 1412 vbvxReadSizesAndCursorIntegrationFromProperties(pScrn, NULL);1413 1408 setSizesAndCursorIntegration(pScrn, false); 1414 1409 #else 1415 setModeRandR11(pScrn, pScrn->currentMode, false, true); 1416 #endif 1417 #ifdef SET_HAVE_VT_PROPERTY 1418 updateHasVTProperty(pScrn, TRUE); 1410 setModeRandR11(pScrn, pScrn->currentMode, false, true, cXOverRide, cYOverRide); 1411 DeleteProperty(ROOT_WINDOW(pScrn), MakeAtom(NO_VT_ATOM_NAME, sizeof(NO_VT_ATOM_NAME) - 1, TRUE)); 1419 1412 #endif 1420 1413 return TRUE; … … 1426 1419 #ifdef VBOXVIDEO_13 1427 1420 unsigned i; 1421 #else 1422 int32_t propertyValue = 0; 1428 1423 #endif 1429 1424 1430 1425 TRACE_ENTRY(); 1426 updateGraphicsCapability(pScrn, FALSE); 1431 1427 #ifdef VBOXVIDEO_13 1432 1428 for (i = 0; i < pVBox->cScreens; ++i) 1433 1429 vbox_crtc_dpms(pVBox->pScreens[i].paCrtcs, DPMSModeOff); 1430 #else 1431 ChangeWindowProperty(ROOT_WINDOW(pScrn), MakeAtom(NO_VT_ATOM_NAME, sizeof(NO_VT_ATOM_NAME) - 1, FALSE), XA_INTEGER, 32, 1432 PropModeReplace, 1, &propertyValue, TRUE); 1434 1433 #endif 1435 1434 vboxDisableVbva(pScrn); … … 1443 1442 #endif 1444 1443 VBOXRestoreMode(pScrn); 1445 #ifdef SET_HAVE_VT_PROPERTY1446 updateHasVTProperty(pScrn, FALSE);1447 #endif1448 1444 TRACE_EXIT(); 1449 1445 } … … 1456 1452 BOOL fRestore = TRUE; 1457 1453 #endif 1454 BOOL ret; 1455 1458 1456 if (pScrn->vtSema) 1459 1457 { … … 1494 1492 #endif 1495 1493 #ifndef XF86_SCRN_INTERFACE 1496 return pScreen->CloseScreen(pScreen->myNum, pScreen); 1497 #else 1498 return pScreen->CloseScreen(pScreen); 1499 #endif 1494 ret = pScreen->CloseScreen(pScreen->myNum, pScreen); 1495 #else 1496 ret = pScreen->CloseScreen(pScreen); 1497 #endif 1498 VbglR3Term(); 1499 return ret; 1500 1500 } 1501 1501 … … 1508 1508 rc = xf86SetSingleMode(pScrn, pMode, RR_Rotate_0); 1509 1509 #else 1510 setModeRandR11(pScrn, pMode, false, false );1510 setModeRandR11(pScrn, pMode, false, false, 0, 0); 1511 1511 #endif 1512 1512 TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE");
Note:
See TracChangeset
for help on using the changeset viewer.