Changeset 70126 in vbox for trunk/src/VBox/Additions/x11/VBoxClient/display-svga.cpp
- Timestamp:
- Dec 14, 2017 11:14:08 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/display-svga.cpp
r69500 r70126 1 1 /* $Id$ */ 2 2 /** @file 3 * X11 guest client - VMSVGA emulation resize event pass-through to guest3 * X11 guest client - VMSVGA emulation resize event pass-through to drm guest 4 4 * driver. 5 5 */ … … 47 47 48 48 /** Maximum number of supported screens. DRM and X11 both limit this to 32. */ 49 /** @todo if this ever changes, dynamically allocate resizeable arrays in the 50 * context structure. */ 49 51 #define VMW_MAX_HEADS 32 50 52 … … 162 164 } 163 165 164 /* VMWare X.Org driver control parts definitions. */165 166 #include <X11/Xlibint.h>167 168 struct X11CONTEXT169 {170 Display *pDisplay;171 int hRandRMajor;172 int hVMWMajor;173 };174 175 static void x11Connect(struct X11CONTEXT *pContext)176 {177 int dummy;178 179 if (pContext->pDisplay != NULL)180 VBClFatalError(("%s called with bad argument\n", __func__));181 pContext->pDisplay = XOpenDisplay(NULL);182 if (pContext->pDisplay == NULL)183 return;184 if ( !XQueryExtension(pContext->pDisplay, "RANDR",185 &pContext->hRandRMajor, &dummy, &dummy)186 || !XQueryExtension(pContext->pDisplay, "VMWARE_CTRL",187 &pContext->hVMWMajor, &dummy, &dummy))188 {189 XCloseDisplay(pContext->pDisplay);190 pContext->pDisplay = NULL;191 }192 }193 194 #define X11_VMW_TOPOLOGY_REQ 2195 struct X11VMWRECT /* xXineramaScreenInfo in Xlib headers. */196 {197 int16_t x;198 int16_t y;199 uint16_t w;200 uint16_t h;201 };202 AssertCompileSize(struct X11VMWRECT, 8);203 204 struct X11REQHEADER205 {206 uint8_t hMajor;207 uint8_t idType;208 uint16_t cd;209 };210 211 struct X11VMWTOPOLOGYREQ212 {213 struct X11REQHEADER header;214 uint32_t idX11Screen;215 uint32_t cScreens;216 uint32_t u32Pad;217 struct X11VMWRECT aRects[1];218 };219 AssertCompileSize(struct X11VMWTOPOLOGYREQ, 24);220 221 #define X11_VMW_TOPOLOGY_REPLY_SIZE 32222 223 #define X11_VMW_RESOLUTION_REQUEST 1224 struct X11VMWRESOLUTIONREQ225 {226 struct X11REQHEADER header;227 uint32_t idX11Screen;228 uint32_t x;229 uint32_t y;230 };231 AssertCompileSize(struct X11VMWRESOLUTIONREQ, 16);232 233 #define X11_VMW_RESOLUTION_REPLY_SIZE 32234 235 #define X11_RANDR_GET_SCREEN_REQUEST 5236 struct X11RANDRGETSCREENREQ237 {238 struct X11REQHEADER header;239 uint32_t hWindow;240 };241 AssertCompileSize(struct X11RANDRGETSCREENREQ, 8);242 243 #define X11_RANDR_GET_SCREEN_REPLY_SIZE 32244 245 /* This was a macro in old Xlib versions and a function in newer ones; the246 * display members touched by the macro were declared as ABI for compatibility247 * reasons. To simplify building with different generations, we duplicate the248 * code. */249 static void x11GetRequest(struct X11CONTEXT *pContext, uint8_t hMajor,250 uint8_t idType, size_t cb, struct X11REQHEADER **ppReq)251 {252 if (pContext->pDisplay->bufptr + cb > pContext->pDisplay->bufmax)253 _XFlush(pContext->pDisplay);254 if (pContext->pDisplay->bufptr + cb > pContext->pDisplay->bufmax)255 VBClFatalError(("%s display buffer overflow.\n", __func__));256 if (cb % 4 != 0)257 VBClFatalError(("%s bad parameter.\n", __func__));258 pContext->pDisplay->last_req = pContext->pDisplay->bufptr;259 *ppReq = (struct X11REQHEADER *)pContext->pDisplay->bufptr;260 (*ppReq)->hMajor = hMajor;261 (*ppReq)->idType = idType;262 (*ppReq)->cd = cb / 4;263 pContext->pDisplay->bufptr += cb;264 pContext->pDisplay->request++;265 }266 267 static void x11SendHints(struct X11CONTEXT *pContext, struct DRMVMWRECT *pRects,268 unsigned cRects)269 {270 unsigned i;271 struct X11VMWTOPOLOGYREQ *pReqTopology;272 uint8_t repTopology[X11_VMW_TOPOLOGY_REPLY_SIZE];273 struct X11VMWRESOLUTIONREQ *pReqResolution;274 uint8_t repResolution[X11_VMW_RESOLUTION_REPLY_SIZE];275 276 if (!VALID_PTR(pContext->pDisplay))277 VBClFatalError(("%s bad display argument.\n", __func__));278 if (cRects == 0)279 return;280 /* Try a topology (multiple screen) request. */281 x11GetRequest(pContext, pContext->hVMWMajor, X11_VMW_TOPOLOGY_REQ,282 sizeof(struct X11VMWTOPOLOGYREQ)283 + sizeof(struct X11VMWRECT) * (cRects - 1),284 (struct X11REQHEADER **)&pReqTopology);285 pReqTopology->idX11Screen = DefaultScreen(pContext->pDisplay);286 pReqTopology->cScreens = cRects;287 for (i = 0; i < cRects; ++i)288 {289 pReqTopology->aRects[i].x = pRects[i].x;290 pReqTopology->aRects[i].y = pRects[i].y;291 pReqTopology->aRects[i].w = pRects[i].w;292 pReqTopology->aRects[i].h = pRects[i].h;293 }294 _XSend(pContext->pDisplay, NULL, 0);295 if (_XReply(pContext->pDisplay, (xReply *)&repTopology, 0, xTrue))296 return;297 /* That failed, so try the old single screen set resolution. We prefer298 * simpler code to negligeably improved efficiency, so we just always try299 * both requests instead of doing version checks or caching. */300 x11GetRequest(pContext, pContext->hVMWMajor, X11_VMW_RESOLUTION_REQUEST,301 sizeof(struct X11VMWTOPOLOGYREQ),302 (struct X11REQHEADER **)&pReqResolution);303 pReqResolution->idX11Screen = DefaultScreen(pContext->pDisplay);304 pReqResolution->x = pRects[0].x;305 pReqResolution->y = pRects[0].y;306 if (_XReply(pContext->pDisplay, (xReply *)&repResolution, 0, xTrue))307 return;308 /* What now? */309 VBClFatalError(("%s failed to set resolution\n", __func__));310 }311 312 /** Call RRGetScreenInfo to wake up the server to the new modes. */313 static void x11GetScreenInfo(struct X11CONTEXT *pContext)314 {315 struct X11RANDRGETSCREENREQ *pReqGetScreen;316 uint8_t repGetScreen[X11_RANDR_GET_SCREEN_REPLY_SIZE];317 318 if (!VALID_PTR(pContext->pDisplay))319 VBClFatalError(("%s bad display argument.\n", __func__));320 x11GetRequest(pContext, pContext->hRandRMajor, X11_RANDR_GET_SCREEN_REQUEST,321 sizeof(struct X11RANDRGETSCREENREQ),322 (struct X11REQHEADER **)&pReqGetScreen);323 pReqGetScreen->hWindow = DefaultRootWindow(pContext->pDisplay);324 _XSend(pContext->pDisplay, NULL, 0);325 if (!_XReply(pContext->pDisplay, (xReply *)&repGetScreen, 0, xTrue))326 VBClFatalError(("%s failed to set resolution\n", __func__));327 }328 329 166 static const char *getPidFilePath() 330 167 { … … 337 174 (void)fDaemonised; 338 175 struct DRMCONTEXT drmContext = { NIL_RTFILE }; 339 struct X11CONTEXT x11Context = { NULL };340 176 unsigned i; 341 177 int rc; … … 350 186 drmConnect(&drmContext); 351 187 if (drmContext.hDevice == NIL_RTFILE) 352 { 353 x11Connect(&x11Context); 354 if (x11Context.pDisplay == NULL) 355 return VINF_SUCCESS; 356 } 188 return VINF_SUCCESS; 357 189 /* Initialise the guest library. */ 358 190 rc = VbglR3InitUser(); … … 407 239 } 408 240 } 409 if (drmContext.hDevice != NIL_RTFILE) 410 drmSendHints(&drmContext, aRects, cHeads); 411 else 412 { 413 x11SendHints(&x11Context, aRects, cHeads); 414 x11GetScreenInfo(&x11Context); 415 } 241 drmSendHints(&drmContext, aRects, cHeads); 416 242 } 417 243 } 418 244 419 st ruct VBCLSERVICE interface =245 static struct VBCLSERVICE interface = 420 246 { 421 247 getPidFilePath,
Note:
See TracChangeset
for help on using the changeset viewer.