Changeset 48070 in vbox for trunk/src/VBox/Additions/WINNT/VBoxTray
- Timestamp:
- Aug 26, 2013 6:13:22 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 88439
- Location:
- trunk/src/VBox/Additions/WINNT/VBoxTray
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/Makefile.kmk
r42288 r48070 61 61 VBoxTray_DEFS += VBOX_WITH_WDDM 62 62 # VBoxTray_DEFS += LOG_ENABLED 63 VBoxTray_SOURCES += ../Graphics/Video/disp/wddm/VBoxDispKmt.cpp 63 64 endif 64 65 -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDispIf.cpp
r46625 r48070 27 27 #endif 28 28 29 #include "VBoxDisplay.h" 30 31 #ifndef NT_SUCCESS 32 # define NT_SUCCESS(_Status) ((_Status) >= 0) 33 #endif 34 35 typedef struct VBOXDISPIF_OP 36 { 37 PCVBOXDISPIF pIf; 38 VBOXDISPKMT_ADAPTER Adapter; 39 VBOXDISPKMT_DEVICE Device; 40 VBOXDISPKMT_CONTEXT Context; 41 } VBOXDISPIF_OP; 42 43 DWORD EnableAndResizeDispDev(DEVMODE *paDeviceModes, DISPLAY_DEVICE *paDisplayDevices, DWORD totalDispNum, UINT Id, DWORD aWidth, DWORD aHeight, 44 DWORD aBitsPerPixel, DWORD aPosX, DWORD aPosY, BOOL fEnabled, BOOL fExtDispSup); 45 46 static DWORD vboxDispIfWddmResizeDisplay(PCVBOXDISPIF const pIf, UINT Id, BOOL fEnable, DISPLAY_DEVICE * paDisplayDevices, DEVMODE *paDeviceMode, UINT devModes); 47 48 static DWORD vboxDispIfResizePerform(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes); 49 50 static DWORD vboxDispIfWddmEnableDisplaysTryingTopology(PCVBOXDISPIF const pIf, UINT cIds, UINT *pIds, BOOL fEnable); 51 52 static DWORD vboxDispIfResizeStartedWDDMOp(VBOXDISPIF_OP *pOp); 53 29 54 /* APIs specific to win7 and above WDDM architecture. Not available for Vista WDDM. 30 55 * This is the reason they have not been put in the VBOXDISPIF struct in VBoxDispIf.h … … 42 67 static _VBOXDISPLAYWDDMAPICONTEXT gCtx = {0}; 43 68 69 typedef struct VBOXDISPIF_WDDM_DISPCFG 70 { 71 UINT32 cPathInfoArray; 72 DISPLAYCONFIG_PATH_INFO *pPathInfoArray; 73 UINT32 cModeInfoArray; 74 DISPLAYCONFIG_MODE_INFO *pModeInfoArray; 75 } VBOXDISPIF_WDDM_DISPCFG; 76 77 static DWORD vboxDispIfWddmDcCreate(VBOXDISPIF_WDDM_DISPCFG *pCfg, UINT32 fFlags) 78 { 79 UINT32 cPathInfoArray = 0; 80 UINT32 cModeInfoArray = 0; 81 DISPLAYCONFIG_PATH_INFO *pPathInfoArray; 82 DISPLAYCONFIG_MODE_INFO *pModeInfoArray; 83 DWORD winEr = gCtx.pfnGetDisplayConfigBufferSizes(fFlags, &cPathInfoArray, &cModeInfoArray); 84 if (winEr != ERROR_SUCCESS) 85 { 86 WARN(("VBoxTray: (WDDM) Failed GetDisplayConfigBufferSizes\n")); 87 return winEr; 88 } 89 90 pPathInfoArray = (DISPLAYCONFIG_PATH_INFO *)malloc(cPathInfoArray * sizeof(DISPLAYCONFIG_PATH_INFO)); 91 if (!pPathInfoArray) 92 { 93 WARN(("VBoxTray: (WDDM) malloc failed!\n")); 94 return ERROR_OUTOFMEMORY; 95 } 96 pModeInfoArray = (DISPLAYCONFIG_MODE_INFO *)malloc(cModeInfoArray * sizeof(DISPLAYCONFIG_MODE_INFO)); 97 if (!pModeInfoArray) 98 { 99 WARN(("VBoxTray: (WDDM) malloc failed!\n")); 100 free(pPathInfoArray); 101 return ERROR_OUTOFMEMORY; 102 } 103 104 winEr = gCtx.pfnQueryDisplayConfig(fFlags, &cPathInfoArray, pPathInfoArray, &cModeInfoArray, pModeInfoArray, NULL); 105 if (winEr != ERROR_SUCCESS) 106 { 107 WARN(("VBoxTray: (WDDM) Failed QueryDisplayConfig\n")); 108 free(pPathInfoArray); 109 free(pModeInfoArray); 110 return winEr; 111 } 112 113 pCfg->cPathInfoArray = cPathInfoArray; 114 pCfg->pPathInfoArray = pPathInfoArray; 115 pCfg->cModeInfoArray = cModeInfoArray; 116 pCfg->pModeInfoArray = pModeInfoArray; 117 return ERROR_SUCCESS; 118 } 119 120 static DWORD vboxDispIfWddmDcClone(VBOXDISPIF_WDDM_DISPCFG *pCfg, VBOXDISPIF_WDDM_DISPCFG *pCfgDst) 121 { 122 memset(pCfgDst, 0, sizeof (*pCfgDst)); 123 124 if (pCfg->cPathInfoArray) 125 { 126 pCfgDst->pPathInfoArray = (DISPLAYCONFIG_PATH_INFO *)malloc(pCfg->cPathInfoArray * sizeof (DISPLAYCONFIG_PATH_INFO)); 127 if (!pCfgDst->pPathInfoArray) 128 { 129 WARN(("VBoxTray: (WDDM) malloc failed!\n")); 130 return ERROR_OUTOFMEMORY; 131 } 132 133 memcpy(pCfgDst->pPathInfoArray, pCfg->pPathInfoArray, pCfg->cPathInfoArray * sizeof (DISPLAYCONFIG_PATH_INFO)); 134 135 pCfgDst->cPathInfoArray = pCfg->cPathInfoArray; 136 } 137 138 if (pCfg->cModeInfoArray) 139 { 140 pCfgDst->pModeInfoArray = (DISPLAYCONFIG_MODE_INFO *)malloc(pCfg->cModeInfoArray * sizeof (DISPLAYCONFIG_MODE_INFO)); 141 if (!pCfgDst->pModeInfoArray) 142 { 143 WARN(("VBoxTray: (WDDM) malloc failed!\n")); 144 if (pCfgDst->pPathInfoArray) 145 { 146 free(pCfgDst->pPathInfoArray); 147 pCfgDst->pPathInfoArray = NULL; 148 } 149 return ERROR_OUTOFMEMORY; 150 } 151 152 memcpy(pCfgDst->pModeInfoArray, pCfg->pModeInfoArray, pCfg->cModeInfoArray * sizeof (DISPLAYCONFIG_MODE_INFO)); 153 154 pCfgDst->cModeInfoArray = pCfg->cModeInfoArray; 155 } 156 157 return ERROR_SUCCESS; 158 } 159 160 161 static VOID vboxDispIfWddmDcTerm(VBOXDISPIF_WDDM_DISPCFG *pCfg) 162 { 163 if (pCfg->pPathInfoArray) 164 free(pCfg->pPathInfoArray); 165 if (pCfg->pModeInfoArray) 166 free(pCfg->pModeInfoArray); 167 /* sanity */ 168 memset(pCfg, 0, sizeof (*pCfg)); 169 } 170 171 static UINT32 g_cVBoxDispIfWddmDisplays = 0; 172 static DWORD vboxDispIfWddmDcQueryNumDisplays(UINT32 *pcDisplays) 173 { 174 if (!g_cVBoxDispIfWddmDisplays) 175 { 176 VBOXDISPIF_WDDM_DISPCFG DispCfg; 177 *pcDisplays = 0; 178 DWORD winEr = vboxDispIfWddmDcCreate(&DispCfg, QDC_ALL_PATHS); 179 if (winEr != ERROR_SUCCESS) 180 { 181 WARN(("VBoxTray:(WDDM) vboxDispIfWddmDcCreate Failed winEr %d\n", winEr)); 182 return winEr; 183 } 184 185 int cDisplays = -1; 186 187 for (UINT iter = 0; iter < DispCfg.cPathInfoArray; ++iter) 188 { 189 if (cDisplays < (int)(DispCfg.pPathInfoArray[iter].sourceInfo.id)) 190 cDisplays = (int)(DispCfg.pPathInfoArray[iter].sourceInfo.id); 191 } 192 193 cDisplays++; 194 195 g_cVBoxDispIfWddmDisplays = cDisplays; 196 Assert(g_cVBoxDispIfWddmDisplays); 197 198 vboxDispIfWddmDcTerm(&DispCfg); 199 } 200 201 *pcDisplays = g_cVBoxDispIfWddmDisplays; 202 return ERROR_SUCCESS; 203 } 204 205 static int vboxDispIfWddmDcSearchPath(VBOXDISPIF_WDDM_DISPCFG *pCfg, UINT srcId, UINT trgId) 206 { 207 for (UINT iter = 0; iter < pCfg->cPathInfoArray; ++iter) 208 { 209 if ((srcId == ~0UL || pCfg->pPathInfoArray[iter].sourceInfo.id == srcId) 210 && (trgId == ~0UL || pCfg->pPathInfoArray[iter].targetInfo.id == trgId)) 211 { 212 return (int)iter; 213 } 214 } 215 return -1; 216 } 217 218 static int vboxDispIfWddmDcSearchActivePath(VBOXDISPIF_WDDM_DISPCFG *pCfg, UINT srcId, UINT trgId) 219 { 220 int idx = vboxDispIfWddmDcSearchPath(pCfg, srcId, trgId); 221 if (idx < 0) 222 return idx; 223 224 if (!(pCfg->pPathInfoArray[idx].flags & DISPLAYCONFIG_PATH_ACTIVE)) 225 return -1; 226 227 return idx; 228 } 229 230 static VOID vboxDispIfWddmDcSettingsInvalidateModeIndex(VBOXDISPIF_WDDM_DISPCFG *pCfg, int idx) 231 { 232 pCfg->pPathInfoArray[idx].sourceInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 233 pCfg->pPathInfoArray[idx].targetInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 234 } 235 236 static VOID vboxDispIfWddmDcSettingsInvalidateModeIndeces(VBOXDISPIF_WDDM_DISPCFG *pCfg) 237 { 238 for (UINT iter = 0; iter < pCfg->cPathInfoArray; ++iter) 239 { 240 vboxDispIfWddmDcSettingsInvalidateModeIndex(pCfg, (int)iter); 241 } 242 243 if (pCfg->pModeInfoArray) 244 { 245 free(pCfg->pModeInfoArray); 246 pCfg->pModeInfoArray = NULL; 247 } 248 pCfg->cModeInfoArray = 0; 249 } 250 251 static DWORD vboxDispIfWddmDcSettingsModeAdd(VBOXDISPIF_WDDM_DISPCFG *pCfg, UINT *pIdx) 252 { 253 UINT32 cModeInfoArray = pCfg->cModeInfoArray + 1; 254 DISPLAYCONFIG_MODE_INFO *pModeInfoArray = (DISPLAYCONFIG_MODE_INFO *)malloc(cModeInfoArray * sizeof (DISPLAYCONFIG_MODE_INFO)); 255 if (!pModeInfoArray) 256 { 257 WARN(("VBoxTray: (WDDM) malloc failed!\n")); 258 return ERROR_OUTOFMEMORY; 259 } 260 261 memcpy (pModeInfoArray, pCfg->pModeInfoArray, pCfg->cModeInfoArray * sizeof(DISPLAYCONFIG_MODE_INFO)); 262 memset(&pModeInfoArray[cModeInfoArray-1], 0, sizeof (pModeInfoArray[0])); 263 free(pCfg->pModeInfoArray); 264 *pIdx = cModeInfoArray-1; 265 pCfg->pModeInfoArray = pModeInfoArray; 266 pCfg->cModeInfoArray = cModeInfoArray; 267 return ERROR_SUCCESS; 268 } 269 270 static DWORD vboxDispIfWddmDcSettingsUpdate(VBOXDISPIF_WDDM_DISPCFG *pCfg, int idx, DEVMODE *pDeviceMode, BOOL fInvalidateSrcMode, BOOL fEnable) 271 { 272 UINT Id = pCfg->pPathInfoArray[idx].sourceInfo.id; 273 274 if (fInvalidateSrcMode) 275 pCfg->pPathInfoArray[idx].sourceInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 276 else if (pDeviceMode) 277 { 278 UINT iSrcMode = pCfg->pPathInfoArray[idx].sourceInfo.modeInfoIdx; 279 if (iSrcMode == DISPLAYCONFIG_PATH_MODE_IDX_INVALID) 280 { 281 282 WARN(("VBoxTray: (WDDM) no source mode index specified")); 283 DWORD winEr = vboxDispIfWddmDcSettingsModeAdd(pCfg, &iSrcMode); 284 if (winEr != ERROR_SUCCESS) 285 { 286 WARN(("VBoxTray:(WDDM) vboxDispIfWddmDcSettingsModeAdd Failed winEr %d\n", winEr)); 287 return winEr; 288 } 289 pCfg->pPathInfoArray[idx].sourceInfo.modeInfoIdx = iSrcMode; 290 } 291 292 for (int i = 0; i < (int)pCfg->cPathInfoArray; ++i) 293 { 294 if (i == idx) 295 continue; 296 297 if (pCfg->pPathInfoArray[i].sourceInfo.modeInfoIdx == iSrcMode) 298 { 299 /* this is something we're not expecting/supporting */ 300 WARN(("VBoxTray: (WDDM) multiple paths have the same mode index")); 301 return ERROR_NOT_SUPPORTED; 302 } 303 } 304 305 if (pDeviceMode->dmFields & DM_PELSWIDTH) 306 pCfg->pModeInfoArray[iSrcMode].sourceMode.width = pDeviceMode->dmPelsWidth; 307 if (pDeviceMode->dmFields & DM_PELSHEIGHT) 308 pCfg->pModeInfoArray[iSrcMode].sourceMode.height = pDeviceMode->dmPelsHeight; 309 if (pDeviceMode->dmFields & DM_POSITION) 310 { 311 pCfg->pModeInfoArray[iSrcMode].sourceMode.position.x = pDeviceMode->dmPosition.x; 312 pCfg->pModeInfoArray[iSrcMode].sourceMode.position.y = pDeviceMode->dmPosition.y; 313 } 314 if (pDeviceMode->dmFields & DM_BITSPERPEL) 315 { 316 switch (pDeviceMode->dmBitsPerPel) 317 { 318 case 32: 319 pCfg->pModeInfoArray[iSrcMode].sourceMode.pixelFormat = DISPLAYCONFIG_PIXELFORMAT_32BPP; 320 break; 321 case 24: 322 pCfg->pModeInfoArray[iSrcMode].sourceMode.pixelFormat = DISPLAYCONFIG_PIXELFORMAT_24BPP; 323 break; 324 case 16: 325 pCfg->pModeInfoArray[iSrcMode].sourceMode.pixelFormat = DISPLAYCONFIG_PIXELFORMAT_16BPP; 326 break; 327 case 8: 328 pCfg->pModeInfoArray[iSrcMode].sourceMode.pixelFormat = DISPLAYCONFIG_PIXELFORMAT_8BPP; 329 break; 330 default: 331 LogRel(("VBoxTray: (WDDM) invalid bpp %d, using 32\n", pDeviceMode->dmBitsPerPel)); 332 pCfg->pModeInfoArray[iSrcMode].sourceMode.pixelFormat = DISPLAYCONFIG_PIXELFORMAT_32BPP; 333 break; 334 } 335 } 336 } 337 338 pCfg->pPathInfoArray[idx].targetInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 339 340 if (fEnable) 341 pCfg->pPathInfoArray[idx].flags |= DISPLAYCONFIG_PATH_ACTIVE; 342 else 343 pCfg->pPathInfoArray[idx].flags &= ~DISPLAYCONFIG_PATH_ACTIVE; 344 345 return ERROR_SUCCESS; 346 } 347 348 static DWORD vboxDispIfWddmDcSet(VBOXDISPIF_WDDM_DISPCFG *pCfg, UINT fFlags) 349 { 350 DWORD winEr = gCtx.pfnSetDisplayConfig(pCfg->cPathInfoArray, pCfg->pPathInfoArray, pCfg->cModeInfoArray, pCfg->pModeInfoArray, fFlags); 351 if (winEr != ERROR_SUCCESS) 352 Log(("VBoxTray:(WDDM) pfnSetDisplayConfig Failed for Flags 0x%x\n", fFlags)); 353 return winEr; 354 } 355 356 static BOOL vboxDispIfWddmDcSettingsAdjustSupportedPaths(VBOXDISPIF_WDDM_DISPCFG *pCfg) 357 { 358 BOOL fAdjusted = FALSE; 359 for (UINT iter = 0; iter < pCfg->cPathInfoArray; ++iter) 360 { 361 if (pCfg->pPathInfoArray[iter].sourceInfo.id == pCfg->pPathInfoArray[iter].targetInfo.id) 362 continue; 363 364 if (!(pCfg->pPathInfoArray[iter].flags & DISPLAYCONFIG_PATH_ACTIVE)) 365 continue; 366 367 pCfg->pPathInfoArray[iter].flags &= ~DISPLAYCONFIG_PATH_ACTIVE; 368 fAdjusted = TRUE; 369 } 370 371 return fAdjusted; 372 } 373 374 static void vboxDispIfWddmDcSettingsAttachDisbledToPrimary(VBOXDISPIF_WDDM_DISPCFG *pCfg) 375 { 376 for (UINT iter = 0; iter < pCfg->cPathInfoArray; ++iter) 377 { 378 if ((pCfg->pPathInfoArray[iter].flags & DISPLAYCONFIG_PATH_ACTIVE)) 379 continue; 380 381 pCfg->pPathInfoArray[iter].sourceInfo.id = 0; 382 pCfg->pPathInfoArray[iter].sourceInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 383 pCfg->pPathInfoArray[iter].targetInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 384 } 385 } 386 387 static DWORD vboxDispIfWddmDcSettingsIncludeAllTargets(VBOXDISPIF_WDDM_DISPCFG *pCfg) 388 { 389 UINT32 cDisplays = 0; 390 VBOXDISPIF_WDDM_DISPCFG AllCfg; 391 BOOL fAllCfgInited = FALSE; 392 393 DWORD winEr = vboxDispIfWddmDcQueryNumDisplays(&cDisplays); 394 if (winEr != ERROR_SUCCESS) 395 { 396 WARN(("VBoxTray:(WDDM) vboxDispIfWddmDcQueryNumDisplays Failed winEr %d\n", winEr)); 397 return winEr; 398 } 399 400 DISPLAYCONFIG_PATH_INFO *pPathInfoArray = (DISPLAYCONFIG_PATH_INFO *)malloc(cDisplays * sizeof(DISPLAYCONFIG_PATH_INFO)); 401 if (!pPathInfoArray) 402 { 403 WARN(("malloc failed\n")); 404 return ERROR_OUTOFMEMORY; 405 } 406 407 for (UINT i = 0; i < cDisplays; ++i) 408 { 409 int idx = vboxDispIfWddmDcSearchPath(pCfg, i, i); 410 if (idx < 0) 411 { 412 idx = vboxDispIfWddmDcSearchPath(pCfg, -1, i); 413 if (idx >= 0) 414 { 415 WARN(("VBoxTray:(WDDM) different source and target paare enabled, this is something we would not expect\n")); 416 } 417 } 418 419 if (idx >= 0) 420 pPathInfoArray[i] = pCfg->pPathInfoArray[idx]; 421 else 422 { 423 if (!fAllCfgInited) 424 { 425 winEr = vboxDispIfWddmDcCreate(&AllCfg, QDC_ALL_PATHS); 426 if (winEr != ERROR_SUCCESS) 427 { 428 WARN(("VBoxTray:(WDDM) vboxDispIfWddmDcCreate Failed winEr %d\n", winEr)); 429 free(pPathInfoArray); 430 return winEr; 431 } 432 fAllCfgInited = TRUE; 433 } 434 435 idx = vboxDispIfWddmDcSearchPath(&AllCfg, i, i); 436 if (idx < 0) 437 { 438 WARN(("VBoxTray:(WDDM) %d %d path not supported\n", i, i)); 439 idx = vboxDispIfWddmDcSearchPath(pCfg, -1, i); 440 if (idx < 0) 441 { 442 WARN(("VBoxTray:(WDDM) %d %d path not supported\n", -1, i)); 443 } 444 } 445 446 if (idx >= 0) 447 { 448 pPathInfoArray[i] = AllCfg.pPathInfoArray[idx]; 449 450 if (pPathInfoArray[i].flags & DISPLAYCONFIG_PATH_ACTIVE) 451 { 452 WARN(("VBoxTray:(WDDM) disabled path %d %d is marked active\n", 453 pPathInfoArray[i].sourceInfo.id, pPathInfoArray[i].targetInfo.id)); 454 pPathInfoArray[i].flags &= ~DISPLAYCONFIG_PATH_ACTIVE; 455 } 456 457 Assert(pPathInfoArray[i].sourceInfo.modeInfoIdx == DISPLAYCONFIG_PATH_MODE_IDX_INVALID); 458 Assert(pPathInfoArray[i].sourceInfo.statusFlags == 0); 459 460 Assert(pPathInfoArray[i].targetInfo.modeInfoIdx == DISPLAYCONFIG_PATH_MODE_IDX_INVALID); 461 Assert(pPathInfoArray[i].targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15); 462 Assert(pPathInfoArray[i].targetInfo.rotation == DISPLAYCONFIG_ROTATION_IDENTITY); 463 Assert(pPathInfoArray[i].targetInfo.scaling == DISPLAYCONFIG_SCALING_PREFERRED); 464 Assert(pPathInfoArray[i].targetInfo.refreshRate.Numerator == 0); 465 Assert(pPathInfoArray[i].targetInfo.refreshRate.Denominator == 0); 466 Assert(pPathInfoArray[i].targetInfo.scanLineOrdering == DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED); 467 Assert(pPathInfoArray[i].targetInfo.targetAvailable == TRUE); 468 Assert(pPathInfoArray[i].targetInfo.statusFlags == DISPLAYCONFIG_TARGET_FORCIBLE); 469 470 Assert(pPathInfoArray[i].flags == 0); 471 } 472 else 473 { 474 pPathInfoArray[i].sourceInfo.adapterId = pCfg->pPathInfoArray[0].sourceInfo.adapterId; 475 pPathInfoArray[i].sourceInfo.id = i; 476 pPathInfoArray[i].sourceInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 477 pPathInfoArray[i].sourceInfo.statusFlags = 0; 478 479 pPathInfoArray[i].targetInfo.adapterId = pPathInfoArray[i].sourceInfo.adapterId; 480 pPathInfoArray[i].targetInfo.id = i; 481 pPathInfoArray[i].targetInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 482 pPathInfoArray[i].targetInfo.outputTechnology = DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15; 483 pPathInfoArray[i].targetInfo.rotation = DISPLAYCONFIG_ROTATION_IDENTITY; 484 pPathInfoArray[i].targetInfo.scaling = DISPLAYCONFIG_SCALING_PREFERRED; 485 pPathInfoArray[i].targetInfo.refreshRate.Numerator = 0; 486 pPathInfoArray[i].targetInfo.refreshRate.Denominator = 0; 487 pPathInfoArray[i].targetInfo.scanLineOrdering = DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED; 488 pPathInfoArray[i].targetInfo.targetAvailable = TRUE; 489 pPathInfoArray[i].targetInfo.statusFlags = DISPLAYCONFIG_TARGET_FORCIBLE; 490 491 pPathInfoArray[i].flags = 0; 492 } 493 } 494 } 495 496 free(pCfg->pPathInfoArray); 497 pCfg->pPathInfoArray = pPathInfoArray; 498 pCfg->cPathInfoArray = cDisplays; 499 if (fAllCfgInited) 500 vboxDispIfWddmDcTerm(&AllCfg); 501 502 return ERROR_SUCCESS; 503 } 504 505 static DWORD vboxDispIfOpBegin(PCVBOXDISPIF pIf, VBOXDISPIF_OP *pOp) 506 { 507 pOp->pIf = pIf; 508 509 HRESULT hr = vboxDispKmtOpenAdapter(&pIf->modeData.wddm.KmtCallbacks, &pOp->Adapter); 510 if (SUCCEEDED(hr)) 511 { 512 hr = vboxDispKmtCreateDevice(&pOp->Adapter, &pOp->Device); 513 if (SUCCEEDED(hr)) 514 { 515 hr = vboxDispKmtCreateContext(&pOp->Device, &pOp->Context, VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE, 516 0, 0, NULL, 0ULL); 517 if (SUCCEEDED(hr)) 518 return ERROR_SUCCESS; 519 else 520 WARN(("VBoxTray: vboxDispKmtCreateContext failed hr 0x%x", hr)); 521 522 vboxDispKmtDestroyDevice(&pOp->Device); 523 } 524 else 525 WARN(("VBoxTray: vboxDispKmtCreateDevice failed hr 0x%x", hr)); 526 527 vboxDispKmtCloseAdapter(&pOp->Adapter); 528 } 529 530 return hr; 531 } 532 533 static VOID vboxDispIfOpEnd(VBOXDISPIF_OP *pOp) 534 { 535 vboxDispKmtDestroyContext(&pOp->Context); 536 vboxDispKmtDestroyDevice(&pOp->Device); 537 vboxDispKmtCloseAdapter(&pOp->Adapter); 538 } 539 44 540 /* display driver interface abstraction for XPDM & WDDM 45 541 * with WDDM we can not use ExtEscape to communicate with our driver … … 60 556 { 61 557 #ifdef VBOX_WITH_WDDM 62 if (pIf->enmMode == VBOXDISPIF_MODE_WDDM)558 if (pIf->enmMode >= VBOXDISPIF_MODE_WDDM) 63 559 { 64 560 vboxDispIfWddmTerm(pIf); 561 562 vboxDispKmtCallbacksTerm(&pIf->modeData.wddm.KmtCallbacks); 65 563 } 66 564 #endif … … 127 625 128 626 /* this is vista and up */ 129 HMODULE hGdi32 = GetModuleHandle("gdi32"); 130 if (hGdi32 != NULL) 131 { 132 pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromHdc = (PFND3DKMT_OPENADAPTERFROMHDC)GetProcAddress(hGdi32, "D3DKMTOpenAdapterFromHdc"); 133 Log((__FUNCTION__"pfnD3DKMTOpenAdapterFromHdc = %p\n", pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromHdc)); 134 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromHdc); 135 136 pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromGdiDisplayName = (PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME)GetProcAddress(hGdi32, "D3DKMTOpenAdapterFromGdiDisplayName"); 137 Log((__FUNCTION__": pfnD3DKMTOpenAdapterFromGdiDisplayName = %p\n", pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromGdiDisplayName)); 138 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromGdiDisplayName); 139 140 pIf->modeData.wddm.pfnD3DKMTCloseAdapter = (PFND3DKMT_CLOSEADAPTER)GetProcAddress(hGdi32, "D3DKMTCloseAdapter"); 141 Log((__FUNCTION__": pfnD3DKMTCloseAdapter = %p\n", pIf->modeData.wddm.pfnD3DKMTCloseAdapter)); 142 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTCloseAdapter); 143 144 pIf->modeData.wddm.pfnD3DKMTEscape = (PFND3DKMT_ESCAPE)GetProcAddress(hGdi32, "D3DKMTEscape"); 145 Log((__FUNCTION__": pfnD3DKMTEscape = %p\n", pIf->modeData.wddm.pfnD3DKMTEscape)); 146 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTCloseAdapter); 147 148 pIf->modeData.wddm.pfnD3DKMTInvalidateActiveVidPn = (PFND3DKMT_INVALIDATEACTIVEVIDPN)GetProcAddress(hGdi32, "D3DKMTInvalidateActiveVidPn"); 149 Log((__FUNCTION__": pfnD3DKMTInvalidateActiveVidPn = %p\n", pIf->modeData.wddm.pfnD3DKMTInvalidateActiveVidPn)); 150 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTInvalidateActiveVidPn); 151 152 pIf->modeData.wddm.pfnD3DKMTPollDisplayChildren = (PFND3DKMT_POLLDISPLAYCHILDREN)GetProcAddress(hGdi32, "D3DKMTPollDisplayChildren"); 153 Log((__FUNCTION__": pfnD3DKMTPollDisplayChildren = %p\n", pIf->modeData.wddm.pfnD3DKMTPollDisplayChildren)); 154 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTPollDisplayChildren); 155 156 if (!bSupported) 157 { 158 Log((__FUNCTION__": one of pfnD3DKMT function pointers failed to initialize\n")); 159 err = ERROR_NOT_SUPPORTED; 160 } 161 } 162 else 163 { 164 Log((__FUNCTION__": GetModuleHandle(gdi32) failed, err(%d)\n", GetLastError())); 165 err = ERROR_NOT_SUPPORTED; 166 } 167 627 HRESULT hr = vboxDispKmtCallbacksInit(&pIf->modeData.wddm.KmtCallbacks); 628 if (FAILED(hr)) 629 { 630 WARN(("VBoxTray: vboxDispKmtCallbacksInit failed hr 0x%x\n", hr)); 631 err = hr; 632 } 168 633 } 169 634 else 170 635 { 171 Log((__FUNCTION__": GetModuleHandle(user32) failed, err(%d)\n", GetLastError()));636 WARN((__FUNCTION__": GetModuleHandle(USER32) failed, err(%d)\n", GetLastError())); 172 637 err = ERROR_NOT_SUPPORTED; 173 638 } … … 175 640 else 176 641 { 177 Log((__FUNCTION__": can not switch to VBOXDISPIF_MODE_WDDM, because os is not Vista or upper\n"));642 WARN((__FUNCTION__": can not switch to VBOXDISPIF_MODE_WDDM, because os is not Vista or upper\n")); 178 643 err = ERROR_NOT_SUPPORTED; 179 644 } … … 185 650 186 651 return err; 652 } 653 654 static DWORD vboxDispIfSwitchToWDDM_W7(PVBOXDISPIF pIf) 655 { 656 return vboxDispIfSwitchToWDDM(pIf); 187 657 } 188 658 … … 209 679 { 210 680 winEr = GetLastError(); 211 Log(("CreateDC failed %d", winEr));681 WARN(("CreateDC failed %d", winEr)); 212 682 break; 213 683 } … … 218 688 { 219 689 winEr = GetLastError(); 220 Log(("EnumDisplayDevices failed %d", winEr));690 WARN(("EnumDisplayDevices failed %d", winEr)); 221 691 break; 222 692 } 223 693 } 224 694 225 Log(("vboxDispIfWDDMAdpHdcCreate failure branch %d", winEr));695 WARN(("vboxDispIfWDDMAdpHdcCreate failure branch %d", winEr)); 226 696 return winEr; 227 697 } 228 698 229 230 typedef DECLCALLBACK(BOOLEAN) FNVBOXDISPIFWDDM_ADAPTEROP(PCVBOXDISPIF pIf, D3DKMT_HANDLE hAdapter, DISPLAY_DEVICE *pDev, PVOID pContext); 231 typedef FNVBOXDISPIFWDDM_ADAPTEROP *PFNVBOXDISPIFWDDM_ADAPTEROP; 232 static DWORD vboxDispIfWDDMAdapterOp(PCVBOXDISPIF pIf, int iDisplay, PFNVBOXDISPIFWDDM_ADAPTEROP pfnOp, PVOID pContext) 233 { 234 D3DKMT_OPENADAPTERFROMHDC OpenAdapterData = {0}; 235 DISPLAY_DEVICE DDev; 236 DWORD err = vboxDispIfWDDMAdpHdcCreate(iDisplay, &OpenAdapterData.hDc, &DDev); 237 Assert(err == NO_ERROR); 238 if (err == NO_ERROR) 239 { 240 NTSTATUS Status = pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromHdc(&OpenAdapterData); 241 Assert(!Status); 242 if (!Status) 243 { 244 BOOLEAN bCloseAdapter = pfnOp(pIf, OpenAdapterData.hAdapter, &DDev, pContext); 245 246 if (bCloseAdapter) 247 { 248 D3DKMT_CLOSEADAPTER ClosaAdapterData = {0}; 249 ClosaAdapterData.hAdapter = OpenAdapterData.hAdapter; 250 Status = pIf->modeData.wddm.pfnD3DKMTCloseAdapter(&ClosaAdapterData); 251 if (Status) 252 { 253 Log((__FUNCTION__": pfnD3DKMTCloseAdapter failed, Status (0x%x)\n", Status)); 254 } 255 } 256 } 257 else 258 { 259 Log((__FUNCTION__": pfnD3DKMTOpenAdapterFromGdiDisplayName failed, Status (0x%x)\n", Status)); 260 err = ERROR_GEN_FAILURE; 261 } 262 263 DeleteDC(OpenAdapterData.hDc); 264 } 265 else 266 Log((__FUNCTION__": vboxDispIfWDDMAdpHdcCreate failed, winEr (%d)\n", err)); 267 268 return err; 269 } 270 271 typedef struct 272 { 273 NTSTATUS Status; 274 PVBOXDISPIFESCAPE pEscape; 275 int cbData; 276 D3DDDI_ESCAPEFLAGS EscapeFlags; 277 } VBOXDISPIFWDDM_ESCAPEOP_CONTEXT, *PVBOXDISPIFWDDM_ESCAPEOP_CONTEXT; 278 279 DECLCALLBACK(BOOLEAN) vboxDispIfEscapeWDDMOp(PCVBOXDISPIF pIf, D3DKMT_HANDLE hAdapter, DISPLAY_DEVICE *pDev, PVOID pContext) 280 { 281 PVBOXDISPIFWDDM_ESCAPEOP_CONTEXT pCtx = (PVBOXDISPIFWDDM_ESCAPEOP_CONTEXT)pContext; 699 static DWORD vboxDispIfEscapeWDDM(PCVBOXDISPIF pIf, PVBOXDISPIFESCAPE pEscape, int cbData, BOOL fHwAccess) 700 { 701 DWORD winEr = ERROR_SUCCESS; 702 VBOXDISPKMT_ADAPTER Adapter; 703 HRESULT hr = vboxDispKmtOpenAdapter(&pIf->modeData.wddm.KmtCallbacks, &Adapter); 704 if (!SUCCEEDED(hr)) 705 { 706 WARN(("VBoxTray: vboxDispKmtOpenAdapter failed hr 0x%x\n", hr)); 707 return hr; 708 } 282 709 283 710 D3DKMT_ESCAPE EscapeData = {0}; 284 EscapeData.hAdapter = hAdapter;711 EscapeData.hAdapter = Adapter.hAdapter; 285 712 //EscapeData.hDevice = NULL; 286 713 EscapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE; 287 EscapeData.Flags = pCtx->EscapeFlags; 288 EscapeData.pPrivateDriverData = pCtx->pEscape; 289 EscapeData.PrivateDriverDataSize = VBOXDISPIFESCAPE_SIZE(pCtx->cbData); 714 if (fHwAccess) 715 EscapeData.Flags.HardwareAccess = 1; 716 EscapeData.pPrivateDriverData = pEscape; 717 EscapeData.PrivateDriverDataSize = VBOXDISPIFESCAPE_SIZE(cbData); 290 718 //EscapeData.hContext = NULL; 291 719 292 pCtx->Status = pIf->modeData.wddm.pfnD3DKMTEscape(&EscapeData); 293 294 return TRUE; 295 } 296 297 static DWORD vboxDispIfEscapeWDDM(PCVBOXDISPIF pIf, PVBOXDISPIFESCAPE pEscape, int cbData, BOOL fHwAccess) 298 { 299 VBOXDISPIFWDDM_ESCAPEOP_CONTEXT Ctx = {0}; 300 Ctx.pEscape = pEscape; 301 Ctx.cbData = cbData; 302 if (fHwAccess) 303 Ctx.EscapeFlags.HardwareAccess = 1; 304 DWORD err = vboxDispIfWDDMAdapterOp(pIf, -1 /* iDisplay, -1 means primary */, vboxDispIfEscapeWDDMOp, &Ctx); 305 if (err == NO_ERROR) 306 { 307 if (!Ctx.Status) 308 err = NO_ERROR; 309 else 310 { 311 if (Ctx.Status == 0xC00000BBL) /* not supported */ 312 err = ERROR_NOT_SUPPORTED; 313 else 314 err = ERROR_GEN_FAILURE; 315 Log((__FUNCTION__": pfnD3DKMTEscape failed, Status (0x%x)\n", Ctx.Status)); 316 } 317 } 720 NTSTATUS Status = pIf->modeData.wddm.KmtCallbacks.pfnD3DKMTEscape(&EscapeData); 721 if (NT_SUCCESS(Status)) 722 winEr = ERROR_SUCCESS; 318 723 else 319 Log((__FUNCTION__": vboxDispIfWDDMAdapterOp failed, err (%d)\n", err)); 320 321 return err; 322 } 323 324 typedef struct 325 { 326 NTSTATUS Status; 327 VBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO Info; 328 } VBOXDISPIFWDDM_RESIZEOP_CONTEXT, *PVBOXDISPIFWDDM_RESIZEOP_CONTEXT; 329 330 DECLCALLBACK(BOOLEAN) vboxDispIfResizeWDDMOp(PCVBOXDISPIF pIf, D3DKMT_HANDLE hAdapter, DISPLAY_DEVICE *pDev, PVOID pContext) 331 { 332 PVBOXDISPIFWDDM_RESIZEOP_CONTEXT pCtx = (PVBOXDISPIFWDDM_RESIZEOP_CONTEXT)pContext; 333 D3DKMT_INVALIDATEACTIVEVIDPN IAVidPnData = {0}; 334 uint32_t cbData = VBOXWDDM_RECOMMENDVIDPN_SIZE(1); 335 PVBOXWDDM_RECOMMENDVIDPN pData = (PVBOXWDDM_RECOMMENDVIDPN)malloc(cbData); 336 if (pData) 337 { 338 memset(pData, 0, cbData); 339 pData->cScreenInfos = 1; 340 memcpy(&pData->aScreenInfos[0], &pCtx->Info, sizeof (VBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO)); 341 342 IAVidPnData.hAdapter = hAdapter; 343 IAVidPnData.pPrivateDriverData = pData; 344 IAVidPnData.PrivateDriverDataSize = cbData; 345 346 pCtx->Status = pIf->modeData.wddm.pfnD3DKMTInvalidateActiveVidPn(&IAVidPnData); 347 Assert(!pCtx->Status); 348 if (pCtx->Status) 349 Log((__FUNCTION__": pfnD3DKMTInvalidateActiveVidPn failed, Status (0x%x)\n", pCtx->Status)); 350 351 free(pData); 352 } 353 else 354 { 355 Log((__FUNCTION__": malloc failed\n")); 356 pCtx->Status = -1; 357 } 358 359 return TRUE; 360 } 361 362 static DWORD vboxDispIfResizeWDDM(PCVBOXDISPIF const pIf, ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel) 363 { 364 VBOXDISPIFWDDM_RESIZEOP_CONTEXT Ctx = {0}; 365 Ctx.Info.Id = Id; 366 Ctx.Info.Width = Width; 367 Ctx.Info.Height = Height; 368 Ctx.Info.BitsPerPixel = BitsPerPixel; 369 DWORD err = vboxDispIfWDDMAdapterOp(pIf, -1, /* (int)Id - always say -1 to use primary display since the display does not really matter here */ 370 vboxDispIfResizeWDDMOp, &Ctx); 371 if (err == NO_ERROR) 372 { 373 if (!Ctx.Status) 374 err = NO_ERROR; 375 else 376 { 377 if (Ctx.Status == 0xC00000BBL) /* not supported */ 378 err = ERROR_NOT_SUPPORTED; 379 else 380 err = ERROR_GEN_FAILURE; 381 Log((__FUNCTION__": vboxDispIfResizeWDDMOp failed, Status (0x%x)\n", Ctx.Status)); 382 } 383 } 384 else 385 Log((__FUNCTION__": vboxDispIfWDDMAdapterOp failed, err (%d)\n", err)); 386 387 return err; 724 { 725 WARN(("VBoxTray: pfnD3DKMTEscape failed Status 0x%x\n", Status)); 726 winEr = ERROR_GEN_FAILURE; 727 } 728 729 vboxDispKmtCloseAdapter(&Adapter); 730 731 return winEr; 388 732 } 389 733 #endif … … 398 742 #ifdef VBOX_WITH_WDDM 399 743 case VBOXDISPIF_MODE_WDDM: 744 case VBOXDISPIF_MODE_WDDM_W7: 400 745 return vboxDispIfEscapeWDDM(pIf, pEscape, cbData, TRUE /* BOOL fHwAccess */); 401 746 #endif … … 415 760 #ifdef VBOX_WITH_WDDM 416 761 case VBOXDISPIF_MODE_WDDM: 762 case VBOXDISPIF_MODE_WDDM_W7: 417 763 return vboxDispIfEscapeWDDM(pIf, pEscape, cbData, TRUE /* BOOL fHwAccess */); 418 764 #endif … … 422 768 } 423 769 } 424 425 static DWORD vboxDispIfResizeXPDM(PCVBOXDISPIF const pIf, ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel)426 {427 return ERROR_NOT_SUPPORTED;428 }429 430 DWORD VBoxDispIfResize(PCVBOXDISPIF const pIf, ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel)431 {432 switch (pIf->enmMode)433 {434 case VBOXDISPIF_MODE_XPDM_NT4:435 return ERROR_NOT_SUPPORTED;436 case VBOXDISPIF_MODE_XPDM:437 return vboxDispIfResizeXPDM(pIf, Id, Width, Height, BitsPerPixel);438 #ifdef VBOX_WITH_WDDM439 case VBOXDISPIF_MODE_WDDM:440 return vboxDispIfResizeWDDM(pIf, Id, Width, Height, BitsPerPixel);441 #endif442 default:443 Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));444 return ERROR_INVALID_PARAMETER;445 }446 }447 448 770 449 771 #ifdef VBOX_WITH_WDDM … … 460 782 UINT_PTR idTimer; 461 783 PCVBOXDISPIF pIf; 784 UINT iChangedMode; 785 BOOL fEnable; 786 BOOL fExtDispSup; 462 787 DISPLAY_DEVICE *paDisplayDevices; 463 788 DEVMODE *paDeviceModes; … … 506 831 } 507 832 508 static DWORD vboxDispIfWddmValidateFixResize(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes);833 //static DWORD vboxDispIfWddmValidateFixResize(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes); 509 834 510 835 static void vboxRrRetryReschedule() … … 512 837 } 513 838 514 static void VBoxRrRetrySchedule(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes)839 static void VBoxRrRetrySchedule(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 515 840 { 516 841 PVBOXRR pMon = &g_VBoxRr; … … 519 844 520 845 pMon->pIf = pIf; 846 pMon->iChangedMode = iChangedMode; 847 pMon->fEnable = fEnable; 848 pMon->fExtDispSup = fExtDispSup; 849 521 850 if (cDevModes) 522 851 { … … 549 878 if (!pMon->idTimer) 550 879 { 551 Log(("VBoxTray: SetTimer failed!, err %d\n", GetLastError()));880 WARN(("VBoxTray: SetTimer failed!, err %d\n", GetLastError())); 552 881 vboxRrRetryStopLocked(); 553 882 } … … 562 891 if (pMon->pIf) 563 892 { 564 DWORD dwErr = vboxDispIf WddmValidateFixResize(pMon->pIf, pMon->paDisplayDevices, pMon->paDeviceModes, pMon->cDevModes);893 DWORD dwErr = vboxDispIfResizePerform(pMon->pIf, pMon->iChangedMode, pMon->fEnable, pMon->fExtDispSup, pMon->paDisplayDevices, pMon->paDeviceModes, pMon->cDevModes); 565 894 if (ERROR_RETRY != dwErr) 566 895 VBoxRrRetryStop(); … … 634 963 { 635 964 DWORD winErr = GetLastError(); 636 Log((__FUNCTION__": RegisterClass failed, winErr(%d)\n", winErr));965 WARN((__FUNCTION__": RegisterClass failed, winErr(%d)\n", winErr)); 637 966 hr = E_FAIL; 638 967 } … … 658 987 { 659 988 DWORD winErr = GetLastError(); 660 Log((__FUNCTION__": CreateWindowEx failed, winErr(%d)\n", winErr));989 WARN((__FUNCTION__": CreateWindowEx failed, winErr(%d)\n", winErr)); 661 990 hr = E_FAIL; 662 991 } … … 673 1002 674 1003 DWORD winErr = GetLastError(); 675 Log((__FUNCTION__": DestroyWindow failed, winErr(%d) for hWnd(0x%x)\n", winErr, hWnd));1004 WARN((__FUNCTION__": DestroyWindow failed, winErr(%d) for hWnd(0x%x)\n", winErr, hWnd)); 676 1005 677 1006 return HRESULT_FROM_WIN32(winErr); … … 731 1060 DWORD winEr = GetLastError(); 732 1061 hr = HRESULT_FROM_WIN32(winEr); 733 Assert(0);734 1062 /* just ensure we never return success in this case */ 735 1063 Assert(hr != S_OK); … … 737 1065 if (hr == S_OK || hr == S_FALSE) 738 1066 hr = E_FAIL; 739 Log(("VBoxTray: GetMessage returned -1, err %d\n", winEr));1067 WARN(("VBoxTray: GetMessage returned -1, err %d\n", winEr)); 740 1068 VBoxRrRetryStop(); 741 1069 break; … … 769 1097 { 770 1098 DWORD winErr = GetLastError(); 771 Log((__FUNCTION__": SetEvent failed, winErr = (%d)", winErr));1099 WARN((__FUNCTION__": SetEvent failed, winErr = (%d)", winErr)); 772 1100 HRESULT tmpHr = HRESULT_FROM_WIN32(winErr); 773 1101 Assert(tmpHr != S_OK); … … 822 1150 { 823 1151 DWORD winErr = GetLastError(); 824 Log((__FUNCTION__": CreateThread failed, winErr = (%d)", winErr));1152 WARN((__FUNCTION__": CreateThread failed, winErr = (%d)", winErr)); 825 1153 hr = HRESULT_FROM_WIN32(winErr); 826 1154 Assert(hr != S_OK); … … 831 1159 { 832 1160 DWORD winErr = GetLastError(); 833 Log((__FUNCTION__": CreateEvent failed, winErr = (%d)", winErr));1161 WARN((__FUNCTION__": CreateEvent failed, winErr = (%d)", winErr)); 834 1162 hr = HRESULT_FROM_WIN32(winErr); 835 1163 Assert(hr != S_OK); … … 877 1205 } 878 1206 879 880 typedef struct VBOXDISPIF_WDDM_INTERNAL881 {882 PCVBOXDISPIF pIf;883 } VBOXDISPIF_WDDM_INTERNAL, *PVBOXDISPIF_WDDM_INTERNAL;884 885 static VBOXDISPIF_WDDM_INTERNAL g_VBoxDispIfWddm;886 887 static BOOL vboxDispIfWddmValidateResize(DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes)888 {889 DISPLAY_DEVICE DisplayDevice;890 int i = 0;891 UINT cMatched = 0;892 DEVMODE CurDevMode, RegDevMode;893 for (int i = 0; ; ++i)894 {895 ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));896 DisplayDevice.cb = sizeof(DISPLAY_DEVICE);897 898 if (!EnumDisplayDevices (NULL, i, &DisplayDevice, 0))899 break;900 901 Log(("VBoxTray: vboxDispIfValidateResize: [%d(%d)] %s\n", i, cMatched, DisplayDevice.DeviceName));902 903 BOOL bFetchDevice = FALSE;904 905 if (DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)906 {907 Log(("VBoxTray: vboxDispIfValidateResize: Found primary device. err %d\n", GetLastError ()));908 bFetchDevice = TRUE;909 }910 else if (!(DisplayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))911 {912 913 Log(("VBoxTray: vboxDispIfValidateResize: Found secondary device. err %d\n", GetLastError ()));914 bFetchDevice = TRUE;915 }916 917 if (bFetchDevice)918 {919 if (cMatched >= cDevModes)920 {921 Log(("VBoxTray: vboxDispIfValidateResize: %d >= %d\n", cDevModes, cMatched));922 return FALSE;923 }924 925 /* First try to get the video mode stored in registry (ENUM_REGISTRY_SETTINGS).926 * A secondary display could be not active at the moment and would not have927 * a current video mode (ENUM_CURRENT_SETTINGS).928 */929 ZeroMemory(&RegDevMode, sizeof(RegDevMode));930 RegDevMode.dmSize = sizeof(DEVMODE);931 if (!EnumDisplaySettings((LPSTR)DisplayDevice.DeviceName,932 ENUM_REGISTRY_SETTINGS, &RegDevMode))933 {934 Log(("VBoxTray: vboxDispIfValidateResize: EnumDisplaySettings error %d\n", GetLastError ()));935 return FALSE;936 }937 938 /* with Win8 WDDM Display-only driver, it seems like sometimes we get an auto-resize setting being stored in registry, although current settings do not match */939 ZeroMemory(&CurDevMode, sizeof(CurDevMode));940 CurDevMode.dmSize = sizeof(CurDevMode);941 if (!EnumDisplaySettings((LPSTR)DisplayDevice.DeviceName,942 ENUM_CURRENT_SETTINGS, &CurDevMode))943 {944 /* ENUM_CURRENT_SETTINGS returns FALSE when the display is not active:945 * for example a disabled secondary display */946 Log(("VBoxTray: vboxDispIfValidateResize: EnumDisplaySettings(ENUM_CURRENT_SETTINGS) error %d\n", GetLastError ()));947 return FALSE;948 }949 950 /* No ENUM_REGISTRY_SETTINGS yet. Seen on Vista after installation.951 * Get the current video mode then.952 */953 if ( RegDevMode.dmPelsWidth != 0954 && RegDevMode.dmPelsHeight == 0)955 {956 if (CurDevMode.dmBitsPerPel != RegDevMode.dmBitsPerPel957 || CurDevMode.dmPelsWidth != RegDevMode.dmPelsWidth958 || CurDevMode.dmPelsHeight != RegDevMode.dmPelsHeight959 || CurDevMode.dmPosition.x != RegDevMode.dmPosition.x960 || CurDevMode.dmPosition.y != RegDevMode.dmPosition.y)961 {962 Log(("VBoxTray: vboxDispIfValidateResize: current settings do not match registry settings, trating as no-match"));963 return FALSE;964 }965 }966 967 UINT j = 0;968 for (; j < cDevModes; ++j)969 {970 if (!strncmp(DisplayDevice.DeviceName, paDisplayDevices[j].DeviceName, RT_ELEMENTS(CurDevMode.dmDeviceName)))971 {972 if (paDeviceModes[j].dmBitsPerPel != CurDevMode.dmBitsPerPel973 || (paDeviceModes[j].dmPelsWidth & 0xfff8) != (CurDevMode.dmPelsWidth & 0xfff8)974 || (paDeviceModes[j].dmPelsHeight & 0xfff8) != (CurDevMode.dmPelsHeight & 0xfff8)975 || (paDeviceModes[j].dmPosition.x & 0xfff8) != (CurDevMode.dmPosition.x & 0xfff8)976 || (paDeviceModes[j].dmPosition.y & 0xfff8) != (CurDevMode.dmPosition.y & 0xfff8)977 || (paDisplayDevices[j].StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) != (DisplayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))978 {979 return FALSE;980 }981 break;982 }983 }984 985 if (j == cDevModes)986 return FALSE;987 988 ++cMatched;989 }990 }991 992 return cMatched == cDevModes;993 }994 995 static DWORD vboxDispIfWddmValidateFixResize(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes)996 {997 if (vboxDispIfWddmValidateResize(paDisplayDevices, paDeviceModes, cDevModes))998 return NO_ERROR;999 1000 LONG status = DISP_CHANGE_SUCCESSFUL;1001 1002 /* now try to resize in a "regular" way */1003 /* Assign the new rectangles to displays. */1004 for (UINT i = 0; i < cDevModes; i++)1005 {1006 /* On Vista one must specify DM_BITSPERPEL.1007 * Note that the current mode dmBitsPerPel is already in the DEVMODE structure.1008 */1009 paDeviceModes[i].dmFields = DM_POSITION | DM_PELSHEIGHT | DM_PELSWIDTH | DM_BITSPERPEL;1010 1011 Log(("VBoxTray: ResizeDisplayDevice: pfnChangeDisplaySettingsEx %x: %dx%dx%d at %d,%d\n",1012 pIf->modeData.wddm.pfnChangeDisplaySettingsEx,1013 paDeviceModes[i].dmPelsWidth,1014 paDeviceModes[i].dmPelsHeight,1015 paDeviceModes[i].dmBitsPerPel,1016 paDeviceModes[i].dmPosition.x,1017 paDeviceModes[i].dmPosition.y));1018 1019 /* the miniport might have been adjusted the display mode stuff,1020 * adjust the paDeviceModes[i] by picking the closest available one */1021 // DEVMODE AdjustedMode = paDeviceModes[i];1022 // vboxDispIfAdjustMode(&paDisplayDevices[i], &AdjustedMode);1023 1024 LONG tmpStatus = pIf->modeData.wddm.pfnChangeDisplaySettingsEx((LPSTR)paDisplayDevices[i].DeviceName,1025 &paDeviceModes[i], NULL, CDS_NORESET | CDS_UPDATEREGISTRY, NULL);1026 Log(("VBoxTray: ResizeDisplayDevice: ChangeDisplaySettingsEx position status %d, err %d\n", tmpStatus, GetLastError ()));1027 if (tmpStatus != DISP_CHANGE_SUCCESSFUL)1028 {1029 status = tmpStatus;1030 }1031 }1032 1033 /* A second call to ChangeDisplaySettings updates the monitor. */1034 LONG tmpStatus = pIf->modeData.wddm.pfnChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL);1035 Log(("VBoxTray: ResizeDisplayDevice: ChangeDisplaySettings update status %d\n", status));1036 if (tmpStatus == DISP_CHANGE_SUCCESSFUL)1037 {1038 if (status == DISP_CHANGE_SUCCESSFUL)1039 {1040 Log(("VBoxTray: resize succeeded\n"));1041 return NO_ERROR;1042 }1043 }1044 else1045 {1046 if (status == DISP_CHANGE_SUCCESSFUL)1047 status = tmpStatus;1048 }1049 1050 if (status == DISP_CHANGE_FAILED)1051 {1052 Log(("VBoxTray: DISP_CHANGE_FAILED, retrying..\n"));1053 return ERROR_RETRY;1054 }1055 1056 Log(("VBoxTray: resize failed with status %d\n", status));1057 1058 return ERROR_GEN_FAILURE;1059 }1060 1061 1207 static DWORD vboxDispIfWddmInit(PCVBOXDISPIF pIf) 1062 1208 { 1063 memset(&g_VBoxDispIfWddm, 0, sizeof (g_VBoxDispIfWddm));1064 g_VBoxDispIfWddm.pIf = pIf;1065 1209 HRESULT hr = VBoxRrInit(); 1066 1210 if (SUCCEEDED(hr)) … … 1068 1212 return ERROR_SUCCESS; 1069 1213 } 1070 return ERROR_GEN_FAILURE; 1214 WARN(("VBoxTray: VBoxRrInit failed hr 0x%x\n", hr)); 1215 return hr; 1071 1216 } 1072 1217 … … 1074 1219 { 1075 1220 VBoxRrTerm(); 1076 memset(&g_VBoxDispIfWddm, 0, sizeof (g_VBoxDispIfWddm)); 1077 } 1078 1079 typedef struct VBOXDISPIF_REINITMODES_OP 1080 { 1081 VBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK EscData; 1082 } VBOXDISPIF_REINITMODES_OP, *PVBOXDISPIF_REINITMODES_OP; 1083 1084 static DECLCALLBACK(BOOLEAN) vboxDispIfReninitModesWDDMOp(PCVBOXDISPIF pIf, D3DKMT_HANDLE hAdapter, DISPLAY_DEVICE *pDev, PVOID pContext) 1085 { 1086 PVBOXDISPIF_REINITMODES_OP pData = (PVBOXDISPIF_REINITMODES_OP)pContext; 1087 VBOXDISPIFWDDM_ESCAPEOP_CONTEXT Ctx = {0}; 1088 Ctx.pEscape = &pData->EscData.EscapeHdr; 1089 Ctx.cbData = sizeof (pData->EscData) - sizeof (pData->EscData.EscapeHdr); 1090 // Ctx.EscapeFlags.HardwareAccess = 0; 1091 DWORD err = vboxDispIfWDDMAdapterOp(pIf, -1 /* iDisplay, -1 means primary */, vboxDispIfEscapeWDDMOp, &Ctx); 1092 if (err == NO_ERROR) 1093 { 1094 if (!Ctx.Status) 1095 err = NO_ERROR; 1096 else 1097 { 1098 if (Ctx.Status == 0xC00000BBL) /* not supported */ 1099 err = ERROR_NOT_SUPPORTED; 1100 else 1101 err = ERROR_GEN_FAILURE; 1102 Log((__FUNCTION__": pfnD3DKMTEscape failed, Status (0x%x)\n", Ctx.Status)); 1103 } 1104 } 1221 } 1222 1223 static DWORD vboxDispIfQueryDisplayConnection(VBOXDISPIF_OP *pOp, UINT32 iDisplay, BOOL *pfConnected) 1224 { 1225 if (pOp->pIf->enmMode == VBOXDISPIF_MODE_WDDM) 1226 { 1227 /* @todo: do we need ti impl it? */ 1228 *pfConnected = TRUE; 1229 return ERROR_SUCCESS; 1230 } 1231 1232 *pfConnected = FALSE; 1233 1234 VBOXDISPIF_WDDM_DISPCFG DispCfg; 1235 DWORD winEr = vboxDispIfWddmDcCreate(&DispCfg, QDC_ALL_PATHS); 1236 if (winEr != ERROR_SUCCESS) 1237 { 1238 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcCreate winEr %d\n", winEr)); 1239 return winEr; 1240 } 1241 1242 int idx = vboxDispIfWddmDcSearchPath(&DispCfg, iDisplay, iDisplay); 1243 *pfConnected = (idx >= 0); 1244 1245 vboxDispIfWddmDcTerm(&DispCfg); 1246 1247 return ERROR_SUCCESS; 1248 } 1249 1250 static DWORD vboxDispIfWaitDisplayDataInited(VBOXDISPIF_OP *pOp, const uint8_t *pu8DisplayMask) 1251 { 1252 DWORD winEr = ERROR_SUCCESS; 1253 do 1254 { 1255 Sleep(100); 1256 1257 D3DKMT_POLLDISPLAYCHILDREN PollData = {0}; 1258 PollData.hAdapter = pOp->Adapter.hAdapter; 1259 PollData.NonDestructiveOnly = 1; 1260 NTSTATUS Status = pOp->pIf->modeData.wddm.KmtCallbacks.pfnD3DKMTPollDisplayChildren(&PollData); 1261 if (Status != 0) 1262 { 1263 Log(("VBoxTray: (WDDM) pfnD3DKMTPollDisplayChildren failed, Status (0x%x)\n", Status)); 1264 continue; 1265 } 1266 1267 BOOL fFound = FALSE; 1268 #if 0 1269 for (UINT i = 0; i < VBOXWDDM_SCREENMASK_SIZE; ++i) 1270 { 1271 if (pu8DisplayMask && !ASMBitTest(pu8DisplayMask, i)) 1272 continue; 1273 1274 BOOL fConnected = FALSE; 1275 winEr = vboxDispIfQueryDisplayConnection(pOp, i, &fConnected); 1276 if (winEr != ERROR_SUCCESS) 1277 { 1278 WARN(("VBoxTray: (WDDM) Failed vboxDispIfQueryDisplayConnection winEr %d\n", winEr)); 1279 return winEr; 1280 } 1281 1282 if (!fConnected) 1283 { 1284 WARN(("VBoxTray: (WDDM) Display %d not connected, not expected\n", i)); 1285 fFound = TRUE; 1286 break; 1287 } 1288 } 1289 #endif 1290 if (!fFound) 1291 break; 1292 } while (1); 1293 1294 return winEr; 1295 } 1296 1297 static DWORD vboxDispIfReninitModesWDDM(VBOXDISPIF_OP *pOp, const uint8_t *pScreenIdMask) 1298 { 1299 DWORD winEr = ERROR_SUCCESS; 1300 VBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK EscData = {0}; 1301 EscData.EscapeHdr.escapeCode = VBOXESC_REINITVIDEOMODESBYMASK; 1302 memcpy(EscData.ScreenMask, pScreenIdMask, sizeof (EscData.ScreenMask)); 1303 1304 D3DKMT_ESCAPE EscapeData = {0}; 1305 EscapeData.hAdapter = pOp->Adapter.hAdapter; 1306 EscapeData.hDevice = pOp->Device.hDevice; 1307 EscapeData.hContext = pOp->Context.hContext; 1308 EscapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE; 1309 EscapeData.Flags.HardwareAccess = 1; 1310 EscapeData.pPrivateDriverData = &EscData; 1311 EscapeData.PrivateDriverDataSize = sizeof (EscData); 1312 1313 NTSTATUS Status = pOp->pIf->modeData.wddm.KmtCallbacks.pfnD3DKMTEscape(&EscapeData); 1314 if (NT_SUCCESS(Status)) 1315 winEr = ERROR_SUCCESS; 1105 1316 else 1106 Log((__FUNCTION__": vboxDispIfWDDMAdapterOp failed, err (%d)\n", err)); 1107 1108 D3DKMT_POLLDISPLAYCHILDREN PollData = {0}; 1109 PollData.hAdapter = hAdapter; 1110 PollData.NonDestructiveOnly = 1; 1111 NTSTATUS Status = pIf->modeData.wddm.pfnD3DKMTPollDisplayChildren(&PollData); 1112 if (Status != 0) 1113 { 1114 Log((__FUNCTION__": pfnD3DKMTPollDisplayChildren failed, Status (0x%x)\n", Status)); 1115 } 1116 return TRUE; 1117 } 1118 1119 static DWORD vboxDispIfReninitModesWDDM(PCVBOXDISPIF const pIf, uint8_t *pScreenIdMask, BOOL fReconnectDisplaysOnChange) 1120 { 1121 VBOXDISPIF_REINITMODES_OP OpData = {0}; 1122 OpData.EscData.EscapeHdr.escapeCode = VBOXESC_REINITVIDEOMODESBYMASK; 1123 if (fReconnectDisplaysOnChange) 1124 OpData.EscData.EscapeHdr.u32CmdSpecific = VBOXWDDM_REINITVIDEOMODESBYMASK_F_RECONNECT_DISPLAYS_ON_CHANGE; 1125 1126 memcpy(OpData.EscData.ScreenMask, pScreenIdMask, sizeof (OpData.EscData.ScreenMask)); 1127 1128 DWORD err = vboxDispIfWDDMAdapterOp(pIf, -1 /* iDisplay, -1 means primary */, vboxDispIfReninitModesWDDMOp, &OpData); 1129 return err; 1317 { 1318 WARN(("VBoxTray: pfnD3DKMTEscape VBOXESC_REINITVIDEOMODESBYMASK failed Status 0x%x\n", Status)); 1319 winEr = ERROR_GEN_FAILURE; 1320 } 1321 1322 winEr = vboxDispIfWaitDisplayDataInited(pOp, pScreenIdMask); 1323 if (winEr != NO_ERROR) 1324 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWaitDisplayDataInited winEr %d\n", winEr)); 1325 1326 return winEr; 1130 1327 } 1131 1328 … … 1137 1334 } 1138 1335 1139 static DWORD vboxDispIfAdjustMode(DISPLAY_DEVICE *pDisplayDevice, DEVMODE *pDeviceMode) 1140 { 1141 DEVMODE CurMode; 1142 DEVMODE BestMatchMode; 1143 DWORD i = 0; 1144 int64_t diffWH = INT64_MAX; 1145 int diffBpp = INT32_MAX; 1146 for (; ; ++i) 1147 { 1148 CurMode.dmSize = sizeof (CurMode); 1149 CurMode.dmDriverExtra = 0; 1150 1151 if (!EnumDisplaySettings(pDisplayDevice->DeviceName, i, &CurMode)) 1152 break; 1153 1154 if (CurMode.dmPelsWidth == pDeviceMode->dmPelsWidth 1155 && CurMode.dmPelsHeight == pDeviceMode->dmPelsHeight 1156 && CurMode.dmBitsPerPel == pDeviceMode->dmBitsPerPel) 1157 { 1158 Log(("Exact match found")); 1159 *pDeviceMode = CurMode; 1160 return NO_ERROR; 1161 } 1162 1163 int diffCurrW = RT_ABS((int)(CurMode.dmPelsWidth - pDeviceMode->dmPelsWidth)); 1164 int diffCurrH = RT_ABS((int)(CurMode.dmPelsHeight - pDeviceMode->dmPelsHeight)); 1165 int diffCurrBpp = RT_ABS((int)(CurMode.dmBitsPerPel - pDeviceMode->dmBitsPerPel) 1166 - 1 /* <- to make higher bpp take precedence over lower ones */ 1167 ); 1168 1169 int64_t diffCurrHW = (int64_t)diffCurrW*diffCurrW + (int64_t)diffCurrH*diffCurrH; 1170 1171 if (i == 0 1172 || diffCurrHW < diffWH 1173 || (diffCurrHW == diffWH && diffCurrBpp < diffBpp)) 1174 { 1175 /* first run */ 1176 BestMatchMode = CurMode; 1177 diffWH = diffCurrHW; 1178 diffBpp = diffCurrBpp; 1179 continue; 1180 } 1181 } 1182 1183 if (i == 0) 1184 { 1185 Log(("No modes found!")); 1186 return NO_ERROR; 1187 } 1188 1189 *pDeviceMode = BestMatchMode; 1190 return NO_ERROR; 1191 } 1192 1193 static DWORD vboxDispIfAdjustModeValues(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *pDisplayDevice, DEVMODE *pDeviceMode) 1194 { 1195 VBOXDISPIFESCAPE_ADJUSTVIDEOMODES Data = {0}; 1196 Data.EscapeHdr.escapeCode = VBOXESC_REINITVIDEOMODESBYMASK; 1197 Data.EscapeHdr.u32CmdSpecific = 1; 1198 Data.aScreenInfos[0].Mode.Id = 1199 Data.aScreenInfos[0].Mode.Width = pDeviceMode->dmPelsWidth; 1200 Data.aScreenInfos[0].Mode.Height = pDeviceMode->dmPelsHeight; 1201 Data.aScreenInfos[0].Mode.BitsPerPixel = pDeviceMode->dmBitsPerPel; 1202 if (pDeviceMode->dmPosition.x != 0 || pDeviceMode->dmPosition.y != 0) { 1203 Data.aScreenInfos[0].Mode.PosX = pDeviceMode->dmPosition.x; 1204 Data.aScreenInfos[0].Mode.PosY = pDeviceMode->dmPosition.y; 1205 } 1206 DWORD err = vboxDispIfEscapeWDDM(pIf, &Data.EscapeHdr, sizeof (Data) - sizeof (Data.EscapeHdr), TRUE); 1207 if (err != NO_ERROR) 1208 { 1209 Log((__FUNCTION__": VBoxDispIfEscape failed with err (%d)\n", err)); 1210 } 1211 return err; 1212 } 1213 1214 DWORD vboxDispIfResizeModesWDDM(PCVBOXDISPIF const pIf, UINT iChangedMode, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 1336 static DWORD vboxDispIfResizePerform(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 1337 { 1338 DWORD winEr; 1339 if (pIf->enmMode > VBOXDISPIF_MODE_WDDM) 1340 { 1341 winEr = vboxDispIfWddmResizeDisplay(pIf, iChangedMode, fEnable, paDisplayDevices, paDeviceModes, cDevModes); 1342 if (winEr != NO_ERROR) 1343 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmResizeDisplay winEr %d\n", winEr)); 1344 } 1345 else 1346 { 1347 winEr = EnableAndResizeDispDev(paDeviceModes, paDisplayDevices, cDevModes, iChangedMode, paDeviceModes[iChangedMode].dmPelsWidth, paDeviceModes[iChangedMode].dmPelsHeight, 1348 paDeviceModes[iChangedMode].dmBitsPerPel, paDeviceModes[iChangedMode].dmPosition.x, paDeviceModes[iChangedMode].dmPosition.y, fEnable, fExtDispSup); 1349 if (winEr != NO_ERROR) 1350 WARN(("VBoxTray: (WDDM) Failed EnableAndResizeDispDev winEr %d\n", winEr)); 1351 } 1352 return winEr; 1353 } 1354 1355 DWORD vboxDispIfResizeModesWDDM(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 1215 1356 { 1216 1357 UINT cbVidPnInfo = VBOXWDDM_RECOMMENDVIDPN_SIZE(cDevModes); … … 1218 1359 pVidPnInfo->cScreenInfos = cDevModes; 1219 1360 D3DKMT_HANDLE hAdapter = NULL; 1220 NTSTATUS Status;1221 1361 DWORD winEr = NO_ERROR; 1222 1362 UINT i = 0; … … 1225 1365 VBoxRrRetryStop(); 1226 1366 1227 for (; i < cDevModes; i++) 1228 { 1229 PVBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO pInfo = &pVidPnInfo->aScreenInfos[i]; 1230 D3DKMT_OPENADAPTERFROMHDC OpenAdapterData = {0}; 1231 OpenAdapterData.hDc = CreateDC(NULL, paDisplayDevices[i].DeviceName, NULL, NULL); 1232 if (!OpenAdapterData.hDc) 1233 { 1234 winEr = GetLastError(); 1235 Log(("VBoxTray: WARNING: Failed to get dc for display device %s, winEr %d\n", paDisplayDevices[i].DeviceName, winEr)); 1236 break; 1237 } 1238 1239 Status = pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromHdc(&OpenAdapterData); 1240 Assert(!Status); 1241 if (Status) 1242 { 1243 winEr = ERROR_GEN_FAILURE; 1244 Log(("VBoxTray: WARNING: Failed to open adapter from dc, Status 0x%x\n", Status)); 1245 break; 1246 } 1247 1248 pInfo->Id = OpenAdapterData.VidPnSourceId; 1249 pInfo->Width = paDeviceModes[i].dmPelsWidth; 1250 pInfo->Height = paDeviceModes[i].dmPelsHeight; 1251 pInfo->BitsPerPixel = paDeviceModes[i].dmBitsPerPel; 1252 1253 if (i == iChangedMode && (paDeviceModes[i].dmPosition.x != 0 || paDeviceModes[i].dmPosition.y != 0) ) 1254 { 1255 /* change position values only if not equal to 0*/ 1256 LogRel(("VBoxTray: (WDDM) Change Position x=%d*y=%d Display Device ID=%d\n", paDeviceModes[i].dmPosition.x, paDeviceModes[i].dmPosition.y, i)); 1257 pInfo->PosX = paDeviceModes[i].dmPosition.x; 1258 pInfo->PosY = paDeviceModes[i].dmPosition.y; 1259 } 1260 1261 if (!hAdapter) 1262 { 1263 hAdapter = OpenAdapterData.hAdapter; 1264 } 1265 else 1266 { 1267 D3DKMT_CLOSEADAPTER ClosaAdapterData = {0}; 1268 ClosaAdapterData.hAdapter = OpenAdapterData.hAdapter; 1269 Status = pIf->modeData.wddm.pfnD3DKMTCloseAdapter(&ClosaAdapterData); 1270 if (Status) 1271 Log(("VBoxTray: WARNING: Failed to close adapter, Status 0x%x\n", Status)); 1272 } 1273 } 1274 1275 BOOL fAbleToInvalidateVidPn = FALSE; 1276 1277 if (0 && winEr == NO_ERROR) 1278 { 1279 Assert(hAdapter); 1280 1281 D3DKMT_INVALIDATEACTIVEVIDPN IAVidPnData = {0}; 1282 IAVidPnData.hAdapter = hAdapter; 1283 IAVidPnData.pPrivateDriverData = pVidPnInfo; 1284 IAVidPnData.PrivateDriverDataSize = cbVidPnInfo; 1285 1286 DWORD winEr = NO_ERROR; 1287 Status = pIf->modeData.wddm.pfnD3DKMTInvalidateActiveVidPn(&IAVidPnData); 1288 Assert(!Status); 1289 if (Status) 1290 { 1291 Log((__FUNCTION__": pfnD3DKMTInvalidateActiveVidPn failed, Status (0x%x)\n", Status)); 1292 winEr = ERROR_GEN_FAILURE; 1293 } 1294 else 1295 { 1296 fAbleToInvalidateVidPn = TRUE; 1297 } 1298 } 1299 1300 if (hAdapter) 1301 { 1302 D3DKMT_CLOSEADAPTER ClosaAdapterData = {0}; 1303 ClosaAdapterData.hAdapter = hAdapter; 1304 Status = pIf->modeData.wddm.pfnD3DKMTCloseAdapter(&ClosaAdapterData); 1305 if (Status) 1306 Log(("VBoxTray: WARNING: Failed to close adapter[2], Status 0x%x\n", Status)); 1307 } 1308 1309 // for (i = 0; i < cDevModes; i++) 1310 // { 1311 // vboxDispIfAdjustMode(&paDisplayDevices[i], &paDeviceModes[i]); 1312 // } 1313 1314 if (fAbleToInvalidateVidPn) 1315 { 1316 Log(("VBoxTray: Invalidating VidPn Worked!\n")); 1317 OSVERSIONINFO OSinfo; 1318 OSinfo.dwOSVersionInfoSize = sizeof (OSinfo); 1319 GetVersionEx (&OSinfo); 1320 /* for win 7 and above calling ChangeDisplaySettingsEx to resize a specific display, is having 1321 * a side affect for enabling all the monitors including the disabled ones. So using 1322 * WDDM win 7 APIs to resize the display for OSes Win7 and above. 1323 */ 1324 if (OSinfo.dwMajorVersion >= 6 && OSinfo.dwMinorVersion >= 1) 1325 winEr = vboxDispIfWddmResizeDisplay(pIf, iChangedMode, paDisplayDevices, paDeviceModes, cDevModes); 1326 else 1327 winEr = vboxDispIfWddmValidateFixResize(pIf, paDisplayDevices, paDeviceModes, cDevModes); 1328 1329 } 1330 else 1331 { 1332 Log(("VBoxTray: Falling back to monitor mode reinit\n")); 1333 /* fallback impl needed for display-only driver 1334 * since D3DKMTInvalidateActiveVidPn is not available for WDDM > 1.0: 1335 * make the driver invalidate VidPn, 1336 * which is done by emulating a monitor re-plug currently */ 1367 VBOXDISPIF_OP Op; 1368 1369 winEr = vboxDispIfOpBegin(pIf, &Op); 1370 if (winEr != NO_ERROR) 1371 { 1372 WARN(("VBoxTray: vboxDispIfOpBegin failed winEr 0x%x", winEr)); 1373 return winEr; 1374 } 1375 1376 1377 // if (fEnable) 1378 { 1379 1337 1380 uint8_t ScreenMask[VBOXWDDM_SCREENMASK_SIZE] = {0}; 1338 1381 ASMBitSet(ScreenMask, iChangedMode); 1339 vboxDispIfReninitModesWDDM(pIf, ScreenMask, TRUE); 1340 1341 OSVERSIONINFO OSinfo; 1342 OSinfo.dwOSVersionInfoSize = sizeof (OSinfo); 1343 GetVersionEx (&OSinfo); 1344 if (OSinfo.dwMajorVersion >= 6 && OSinfo.dwMinorVersion >= 1) 1345 winEr = vboxDispIfWddmResizeDisplay(pIf, iChangedMode, paDisplayDevices, paDeviceModes, cDevModes); 1346 else 1347 winEr = vboxDispIfWddmValidateFixResize(pIf, paDisplayDevices, paDeviceModes, cDevModes); 1348 Assert(winEr == NO_ERROR); 1349 } 1382 vboxDispIfReninitModesWDDM(&Op, ScreenMask); 1383 } 1384 1385 winEr = vboxDispIfResizePerform(pIf, iChangedMode, fEnable, fExtDispSup, paDisplayDevices, paDeviceModes, cDevModes); 1350 1386 1351 1387 if (winEr == ERROR_RETRY) 1352 1388 { 1353 VBoxRrRetrySchedule(pIf, paDisplayDevices, paDeviceModes, cDevModes);1389 VBoxRrRetrySchedule(pIf, iChangedMode, fEnable, fExtDispSup, paDisplayDevices, paDeviceModes, cDevModes); 1354 1390 /* just pretend everything is fine so far */ 1355 1391 winEr = NO_ERROR; 1356 1392 } 1357 1393 1394 vboxDispIfOpEnd(&Op); 1395 1358 1396 return winEr; 1359 1397 } 1360 1398 1361 DWORD vboxDispIfWddmEnableDisplay(PCVBOXDISPIF const pIf, UINT Id, bool fEnabled) 1362 { 1363 DISPLAYCONFIG_PATH_INFO *pPathInfoArray; 1364 DISPLAYCONFIG_MODE_INFO *pModeInfoArray; 1365 UINT numPathArrayElements = 0; 1366 UINT numModeInfoArrayElements = 0; 1367 ULONG dwStatus; 1368 1369 dwStatus = gCtx.pfnGetDisplayConfigBufferSizes(fEnabled ? QDC_ALL_PATHS : QDC_ONLY_ACTIVE_PATHS, &numPathArrayElements, &numModeInfoArrayElements); 1370 if (dwStatus != ERROR_SUCCESS) 1371 { 1372 LogFlow(("VBoxTray: (WDDM) Failed GetDisplayConfigBufferSizes \n")); 1373 return dwStatus; 1374 } 1375 pPathInfoArray = (DISPLAYCONFIG_PATH_INFO *)malloc(numPathArrayElements * sizeof(DISPLAYCONFIG_PATH_INFO)); 1376 if (!pPathInfoArray) 1377 return ERROR_OUTOFMEMORY; 1378 pModeInfoArray = (DISPLAYCONFIG_MODE_INFO *)malloc(numModeInfoArrayElements * sizeof(DISPLAYCONFIG_MODE_INFO)); 1379 if (!pModeInfoArray ) 1380 { 1381 if (pPathInfoArray) 1382 { 1383 free(pPathInfoArray); 1384 } 1385 return ERROR_OUTOFMEMORY; 1386 } 1387 dwStatus = gCtx.pfnQueryDisplayConfig(fEnabled ? QDC_ALL_PATHS : QDC_ONLY_ACTIVE_PATHS, &numPathArrayElements, pPathInfoArray,&numModeInfoArrayElements, pModeInfoArray, NULL); 1388 if (dwStatus != ERROR_SUCCESS) 1389 { 1390 LogFlow(("VBoxTray: (WDDM) Failed QueryDisplayConfig \n")); 1391 free(pPathInfoArray); 1392 free(pModeInfoArray); 1393 return dwStatus; 1394 } 1395 for (unsigned int i=0; i < numPathArrayElements; ++i) 1396 { 1397 LogRel(("Sourceid= %d and targetid = %d\n", pPathInfoArray[i].sourceInfo.id, pPathInfoArray[i].targetInfo.id)); 1398 if (pPathInfoArray[i].sourceInfo.id == Id) 1399 { 1400 if (fEnabled) 1401 { 1402 LogRel(("VBoxTray: (WDDM) Enable the Display Device i =%d \n", i)); 1403 pPathInfoArray[i].flags=DISPLAYCONFIG_PATH_ACTIVE; 1399 static DWORD vboxDispIfWddmEnableDisplays(PCVBOXDISPIF const pIf, UINT cIds, UINT *pIds, BOOL fEnabled, BOOL fSetTopology, DEVMODE *pDeviceMode) 1400 { 1401 VBOXDISPIF_WDDM_DISPCFG DispCfg; 1402 1403 DWORD winEr; 1404 int iPath; 1405 1406 winEr = vboxDispIfWddmDcCreate(&DispCfg, QDC_ONLY_ACTIVE_PATHS); 1407 if (winEr != ERROR_SUCCESS) 1408 { 1409 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcCreate winEr %d\n", winEr)); 1410 return winEr; 1411 } 1412 1413 UINT cChangeIds = 0; 1414 UINT *pChangeIds = (UINT*)alloca(cIds * sizeof (*pChangeIds)); 1415 if (!pChangeIds) 1416 { 1417 WARN(("VBoxTray: (WDDM) Failed to alloc change ids\n")); 1418 winEr = ERROR_OUTOFMEMORY; 1419 goto done; 1420 } 1421 1422 for (UINT i = 0; i < cIds; ++i) 1423 { 1424 UINT Id = pIds[i]; 1425 bool fIsDup = false; 1426 for (UINT j = 0; j < cChangeIds; ++j) 1427 { 1428 if (pChangeIds[j] == Id) 1429 { 1430 fIsDup = true; 1404 1431 break; 1405 1432 } 1406 else 1407 { 1408 LogRel(("VBoxTray: (WDDM) Disable the Display Device Path ID=%d and Sourceid=%d\n", i, pPathInfoArray[i].sourceInfo.id)); 1409 pPathInfoArray[i].flags=0; 1410 break; 1411 } 1412 } 1413 } 1414 dwStatus = gCtx.pfnSetDisplayConfig(numPathArrayElements, pPathInfoArray, numModeInfoArrayElements, pModeInfoArray, (SDC_APPLY | SDC_SAVE_TO_DATABASE| SDC_ALLOW_CHANGES | SDC_USE_SUPPLIED_DISPLAY_CONFIG)); 1415 if (dwStatus != ERROR_SUCCESS) 1416 { 1417 free(pPathInfoArray); 1418 free(pModeInfoArray); 1419 LogRel(("VBoxTray:(WDDM) Failed to Enable/ disable the monitor.")); 1420 return dwStatus; 1421 } 1422 free(pPathInfoArray); 1423 free(pModeInfoArray); 1424 return ERROR_SUCCESS; 1425 } 1426 1427 DWORD vboxDispIfWddmResizeDisplay(PCVBOXDISPIF const pIf, UINT Id, DISPLAY_DEVICE * paDisplayDevices, DEVMODE *paDeviceMode, UINT devModes) 1428 { 1429 DISPLAYCONFIG_PATH_INFO *pPathInfoArray; 1430 DISPLAYCONFIG_MODE_INFO *pModeInfoArray; 1431 UINT numPathArrayElements = 0; 1432 UINT numModeInfoArrayElements = 0; 1433 ULONG dwStatus; 1434 bool fFoundDisplay = false; 1435 1436 dwStatus = gCtx.pfnGetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &numPathArrayElements, &numModeInfoArrayElements); 1437 if (dwStatus != ERROR_SUCCESS) 1438 { 1439 LogFlow(("VBoxTray: (WDDM) Failed GetDisplayConfigBufferSizes \n")); 1440 return dwStatus; 1441 } 1442 pPathInfoArray = (DISPLAYCONFIG_PATH_INFO *)malloc(numPathArrayElements * sizeof(DISPLAYCONFIG_PATH_INFO)); 1443 if (!pPathInfoArray) 1444 return ERROR_OUTOFMEMORY; 1445 pModeInfoArray = (DISPLAYCONFIG_MODE_INFO *)malloc(numModeInfoArrayElements * sizeof(DISPLAYCONFIG_MODE_INFO)); 1446 if (!pModeInfoArray ) 1447 { 1448 if (pPathInfoArray) 1449 { 1450 free(pPathInfoArray); 1451 } 1452 return ERROR_OUTOFMEMORY; 1453 } 1454 dwStatus = gCtx.pfnQueryDisplayConfig( QDC_ONLY_ACTIVE_PATHS, &numPathArrayElements, pPathInfoArray,&numModeInfoArrayElements, pModeInfoArray, NULL); 1455 if (dwStatus != ERROR_SUCCESS) 1456 { 1457 LogFlow(("VBoxTray: (WDDM) Failed QueryDisplayConfig \n")); 1458 free(pPathInfoArray); 1459 free(pModeInfoArray); 1460 return dwStatus; 1461 } 1462 LogFlow(("VBoxTray: NumPath =%d and NumMod=%d\n", numPathArrayElements, numModeInfoArrayElements)); 1463 for (UINT iter = 0; iter < numPathArrayElements; ++iter) 1464 { 1465 LogFlow(("Sourceid= %d and targetid = %d iter =%d and id = %d\n", pPathInfoArray[iter].sourceInfo.id, pPathInfoArray[iter].targetInfo.id, iter, Id)); 1466 if (pPathInfoArray[iter].sourceInfo.id == Id) 1467 { 1468 UINT iModIdx = pPathInfoArray[iter].sourceInfo.modeInfoIdx; 1469 LogFlow(("VBoxTray: Mode Index = %d\n", iModIdx)); 1470 pModeInfoArray[iModIdx].sourceMode.width = paDeviceMode[Id].dmPelsWidth; 1471 pModeInfoArray[iModIdx].sourceMode.height = paDeviceMode[Id].dmPelsHeight; 1472 if(paDeviceMode[Id].dmPosition.x != 0 || paDeviceMode[Id].dmPosition.y != 0) 1473 { 1474 pModeInfoArray[iModIdx].sourceMode.position.x = paDeviceMode[Id].dmPosition.x; 1475 pModeInfoArray[iModIdx].sourceMode.position.y = paDeviceMode[Id].dmPosition.y; 1476 } 1477 fFoundDisplay = true; 1478 break; 1479 } 1480 } 1481 if (fFoundDisplay) 1482 { 1483 /* Call SetDisplayConfig only if displaywith ID=Id has been found. */ 1484 LogFlow(("VBoxTray: Found Display with Id=%d\n", Id)); 1485 dwStatus = gCtx.pfnSetDisplayConfig(numPathArrayElements, pPathInfoArray, numModeInfoArrayElements, pModeInfoArray,(SDC_APPLY | SDC_SAVE_TO_DATABASE| SDC_ALLOW_CHANGES | SDC_USE_SUPPLIED_DISPLAY_CONFIG)); 1486 if (dwStatus != ERROR_SUCCESS) 1487 { 1488 LogRel(("VBoxTray:(WDDM) Failed to resize the monitor.\n")); 1489 free(pPathInfoArray); 1490 free(pModeInfoArray); 1491 1492 if (dwStatus == ERROR_GEN_FAILURE) 1493 { 1494 LogRel(("VBoxTray:(WDDM) going to retry\n")); 1495 return ERROR_RETRY; /* <- to make sure we retry */ 1496 } 1497 return dwStatus; 1498 } 1499 } 1500 free(pPathInfoArray); 1501 free(pModeInfoArray); 1502 return ERROR_SUCCESS; 1433 } 1434 1435 if (fIsDup) 1436 continue; 1437 1438 iPath = vboxDispIfWddmDcSearchPath(&DispCfg, Id, Id); 1439 1440 if (!((iPath >= 0) && (DispCfg.pPathInfoArray[iPath].flags & DISPLAYCONFIG_PATH_ACTIVE)) != !fEnabled) 1441 { 1442 pChangeIds[cChangeIds] = Id; 1443 ++cChangeIds; 1444 } 1445 } 1446 1447 if (cChangeIds == 0) 1448 { 1449 Log(("VBoxTray: (WDDM) vboxDispIfWddmEnableDisplay: settings are up to date\n")); 1450 winEr = ERROR_SUCCESS; 1451 goto done; 1452 } 1453 1454 /* we want to set primary for every disabled for non-topoly mode only */ 1455 winEr = vboxDispIfWddmDcSettingsIncludeAllTargets(&DispCfg); 1456 if (winEr != ERROR_SUCCESS) 1457 { 1458 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcSettingsIncludeAllTargets winEr %d\n", winEr)); 1459 return winEr; 1460 } 1461 1462 if (fSetTopology) 1463 vboxDispIfWddmDcSettingsInvalidateModeIndeces(&DispCfg); 1464 1465 for (UINT i = 0; i < cChangeIds; ++i) 1466 { 1467 UINT Id = pChangeIds[i]; 1468 /* re-query paths */ 1469 iPath = vboxDispIfWddmDcSearchPath(&DispCfg, -1, Id); 1470 if (iPath < 0) 1471 { 1472 WARN(("VBoxTray: (WDDM) path index not found while it should")); 1473 winEr = ERROR_GEN_FAILURE; 1474 goto done; 1475 } 1476 1477 winEr = vboxDispIfWddmDcSettingsUpdate(&DispCfg, iPath, pDeviceMode, !fEnabled || fSetTopology, fEnabled); 1478 if (winEr != ERROR_SUCCESS) 1479 { 1480 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcSettingsUpdate winEr %d\n", winEr)); 1481 goto done; 1482 } 1483 } 1484 1485 if (!fSetTopology) 1486 vboxDispIfWddmDcSettingsAttachDisbledToPrimary(&DispCfg); 1487 1488 #if 0 1489 /* ensure the zero-index (primary) screen is enabled */ 1490 iPath = vboxDispIfWddmDcSearchPath(&DispCfg, 0, 0); 1491 if (iPath < 0) 1492 { 1493 WARN(("VBoxTray: (WDDM) path index not found while it should")); 1494 winEr = ERROR_GEN_FAILURE; 1495 goto done; 1496 } 1497 1498 winEr = vboxDispIfWddmDcSettingsUpdate(&DispCfg, iPath, /* just re-use device node here*/ pDeviceMode, fSetTopology, TRUE); 1499 if (winEr != ERROR_SUCCESS) 1500 { 1501 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcSettingsUpdate winEr %d\n", winEr)); 1502 goto done; 1503 } 1504 #endif 1505 1506 UINT fSetFlags = !fSetTopology ? (SDC_USE_SUPPLIED_DISPLAY_CONFIG) : (SDC_ALLOW_PATH_ORDER_CHANGES | SDC_TOPOLOGY_SUPPLIED); 1507 winEr = vboxDispIfWddmDcSet(&DispCfg, fSetFlags | SDC_VALIDATE); 1508 if (winEr != ERROR_SUCCESS) 1509 { 1510 if (!fSetTopology) 1511 { 1512 WARN(("VBoxTray: (WDDM) vboxDispIfWddmDcSet validation failed winEr, trying with changes %d\n", winEr)); 1513 fSetFlags |= SDC_ALLOW_CHANGES; 1514 } 1515 else 1516 { 1517 Log(("VBoxTray: (WDDM) vboxDispIfWddmDcSet topology validation failed winEr %d\n", winEr)); 1518 goto done; 1519 } 1520 } 1521 1522 if (!fSetTopology) 1523 fSetFlags |= SDC_SAVE_TO_DATABASE; 1524 1525 winEr = vboxDispIfWddmDcSet(&DispCfg, fSetFlags | SDC_APPLY); 1526 if (winEr != ERROR_SUCCESS) 1527 WARN(("VBoxTray: (WDDM) vboxDispIfWddmDcSet apply failed winEr %d\n", winEr)); 1528 1529 done: 1530 vboxDispIfWddmDcTerm(&DispCfg); 1531 1532 return winEr; 1533 } 1534 1535 static DWORD vboxDispIfWddmEnableDisplaysTryingTopology(PCVBOXDISPIF const pIf, UINT cIds, UINT *pIds, BOOL fEnable) 1536 { 1537 DWORD winEr = vboxDispIfWddmEnableDisplays(pIf, cIds, pIds, fEnable, FALSE, NULL); 1538 if (winEr != ERROR_SUCCESS) 1539 { 1540 if (fEnable) 1541 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmEnableDisplay mode winEr %d\n", winEr)); 1542 else 1543 Log(("VBoxTray: (WDDM) Failed vboxDispIfWddmEnableDisplay mode winEr %d\n", winEr)); 1544 winEr = vboxDispIfWddmEnableDisplays(pIf, cIds, pIds, fEnable, TRUE, NULL); 1545 if (winEr != ERROR_SUCCESS) 1546 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmEnableDisplay mode winEr %d\n", winEr)); 1547 } 1548 1549 return winEr; 1550 } 1551 1552 static DWORD vboxDispIfWddmResizeDisplay(PCVBOXDISPIF const pIf, UINT Id, BOOL fEnable, DISPLAY_DEVICE * paDisplayDevices, DEVMODE *paDeviceMode, UINT devModes) 1553 { 1554 VBOXDISPIF_WDDM_DISPCFG DispCfg; 1555 DWORD winEr; 1556 int iPath; 1557 1558 winEr = vboxDispIfWddmDcCreate(&DispCfg, QDC_ONLY_ACTIVE_PATHS); 1559 if (winEr != ERROR_SUCCESS) 1560 { 1561 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcCreate\n")); 1562 return winEr; 1563 } 1564 1565 iPath = vboxDispIfWddmDcSearchActivePath(&DispCfg, Id, Id); 1566 1567 if (iPath < 0) 1568 { 1569 vboxDispIfWddmDcTerm(&DispCfg); 1570 1571 if (!fEnable) 1572 { 1573 /* nothing to be done here, just leave */ 1574 return ERROR_SUCCESS; 1575 } 1576 1577 winEr = vboxDispIfWddmEnableDisplaysTryingTopology(pIf, 1, &Id, fEnable); 1578 if (winEr != ERROR_SUCCESS) 1579 { 1580 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmEnableDisplaysTryingTopology winEr %d\n", winEr)); 1581 return winEr; 1582 } 1583 1584 winEr = vboxDispIfWddmDcCreate(&DispCfg, QDC_ONLY_ACTIVE_PATHS); 1585 if (winEr != ERROR_SUCCESS) 1586 { 1587 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcCreate winEr %d\n", winEr)); 1588 return winEr; 1589 } 1590 1591 iPath = vboxDispIfWddmDcSearchPath(&DispCfg, Id, Id); 1592 if (iPath < 0) 1593 { 1594 WARN(("VBoxTray: (WDDM) path (%d) is still disabled, going to retry winEr %d\n", winEr)); 1595 vboxDispIfWddmDcTerm(&DispCfg); 1596 return ERROR_RETRY; 1597 } 1598 } 1599 1600 Assert(iPath >= 0); 1601 1602 if (!fEnable) 1603 { 1604 /* need to disable it, and we are done */ 1605 vboxDispIfWddmDcTerm(&DispCfg); 1606 1607 winEr = vboxDispIfWddmEnableDisplaysTryingTopology(pIf, 1, &Id, fEnable); 1608 if (winEr != ERROR_SUCCESS) 1609 { 1610 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmEnableDisplaysTryingTopology winEr %d\n", winEr)); 1611 return winEr; 1612 } 1613 1614 return winEr; 1615 } 1616 1617 Assert(fEnable); 1618 1619 winEr = vboxDispIfWddmDcSettingsUpdate(&DispCfg, iPath, &paDeviceMode[Id], FALSE, fEnable); 1620 if (winEr != ERROR_SUCCESS) 1621 { 1622 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcSettingsUpdate\n")); 1623 vboxDispIfWddmDcTerm(&DispCfg); 1624 return winEr; 1625 } 1626 1627 UINT fSetFlags = SDC_USE_SUPPLIED_DISPLAY_CONFIG; 1628 winEr = vboxDispIfWddmDcSet(&DispCfg, fSetFlags | SDC_VALIDATE); 1629 if (winEr != ERROR_SUCCESS) 1630 { 1631 WARN(("VBoxTray:(WDDM) pfnSetDisplayConfig Failed to validate winEr %d.\n", winEr)); 1632 fSetFlags |= SDC_ALLOW_CHANGES; 1633 } 1634 1635 winEr = vboxDispIfWddmDcSet(&DispCfg, fSetFlags | SDC_SAVE_TO_DATABASE | SDC_APPLY); 1636 if (winEr != ERROR_SUCCESS) 1637 { 1638 WARN(("VBoxTray:(WDDM) pfnSetDisplayConfig Failed to validate winEr %d.\n", winEr)); 1639 } 1640 1641 vboxDispIfWddmDcTerm(&DispCfg); 1642 1643 return winEr; 1503 1644 } 1504 1645 1505 1646 #endif /* VBOX_WITH_WDDM */ 1506 1647 1507 DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes)1648 DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 1508 1649 { 1509 1650 switch (pIf->enmMode) … … 1515 1656 #ifdef VBOX_WITH_WDDM 1516 1657 case VBOXDISPIF_MODE_WDDM: 1517 return vboxDispIfResizeModesWDDM(pIf, iChangedMode, paDisplayDevices, paDeviceModes, cDevModes); 1658 case VBOXDISPIF_MODE_WDDM_W7: 1659 return vboxDispIfResizeModesWDDM(pIf, iChangedMode, fEnable, fExtDispSup, paDisplayDevices, paDeviceModes, cDevModes); 1518 1660 #endif 1519 1661 default: 1520 Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));1662 WARN((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode)); 1521 1663 return ERROR_INVALID_PARAMETER; 1522 1664 } … … 1533 1675 #ifdef VBOX_WITH_WDDM 1534 1676 case VBOXDISPIF_MODE_WDDM: 1677 case VBOXDISPIF_MODE_WDDM_W7: 1535 1678 return vboxDispIfCancelPendingResizeWDDM(pIf); 1536 1679 #endif 1537 1680 default: 1538 Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));1681 WARN((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode)); 1539 1682 return ERROR_INVALID_PARAMETER; 1540 1683 } 1541 1684 } 1542 1685 1543 DWORD VBoxDispIfReninitModes(PCVBOXDISPIF const pIf, uint8_t *pScreenIdMask, BOOL fReconnectDisplaysOnChange) 1686 static DWORD vboxDispIfConfigureTargetsWDDM(VBOXDISPIF_OP *pOp, uint32_t *pcConnected) 1687 { 1688 VBOXDISPIFESCAPE EscapeHdr = {0}; 1689 EscapeHdr.escapeCode = VBOXESC_CONFIGURETARGETS; 1690 EscapeHdr.u32CmdSpecific = 0; 1691 1692 D3DKMT_ESCAPE EscapeData = {0}; 1693 EscapeData.hAdapter = pOp->Adapter.hAdapter; 1694 EscapeData.hDevice = pOp->Device.hDevice; 1695 EscapeData.hContext = pOp->Context.hContext; 1696 EscapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE; 1697 EscapeData.Flags.HardwareAccess = 1; 1698 EscapeData.pPrivateDriverData = &EscapeHdr; 1699 EscapeData.PrivateDriverDataSize = sizeof (EscapeHdr); 1700 1701 NTSTATUS Status = pOp->pIf->modeData.wddm.KmtCallbacks.pfnD3DKMTEscape(&EscapeData); 1702 if (NT_SUCCESS(Status)) 1703 { 1704 if (pcConnected) 1705 *pcConnected = EscapeHdr.u32CmdSpecific; 1706 return NO_ERROR; 1707 } 1708 WARN(("VBoxTray: pfnD3DKMTEscape VBOXESC_CONFIGURETARGETS failed Status 0x%x\n", Status)); 1709 return Status; 1710 } 1711 1712 static DWORD vboxDispIfResizeStartedWDDMOp(VBOXDISPIF_OP *pOp) 1713 { 1714 DWORD NumDevices = VBoxGetDisplayConfigCount(); 1715 if (NumDevices == 0) 1716 { 1717 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: Zero devices found\n")); 1718 return ERROR_GEN_FAILURE; 1719 } 1720 1721 #ifdef DEBUG_misha 1722 { 1723 UINT cDcDisplays; 1724 DWORD winEr2 = vboxDispIfWddmDcQueryNumDisplays(&cDcDisplays); 1725 Assert(cDcDisplays == NumDevices); 1726 /* testing */ 1727 Assert(cDcDisplays == 2); 1728 } 1729 #endif 1730 DISPLAY_DEVICE *paDisplayDevices = (DISPLAY_DEVICE *)alloca (sizeof (DISPLAY_DEVICE) * NumDevices); 1731 DEVMODE *paDeviceModes = (DEVMODE *)alloca (sizeof (DEVMODE) * NumDevices); 1732 DWORD DevNum = 0; 1733 DWORD DevPrimaryNum = 0; 1734 1735 DWORD winEr = VBoxGetDisplayConfig(NumDevices, &DevPrimaryNum, &DevNum, paDisplayDevices, paDeviceModes); 1736 if (winEr != NO_ERROR) 1737 { 1738 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: VBoxGetDisplayConfig failed, %d\n", winEr)); 1739 return winEr; 1740 } 1741 1742 if (NumDevices != DevNum) 1743 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: NumDevices(%d) != DevNum(%d)\n", NumDevices, DevNum)); 1744 1745 1746 uint32_t cConnected = 0; 1747 winEr = vboxDispIfConfigureTargetsWDDM(pOp, &cConnected); 1748 if (winEr != NO_ERROR) 1749 { 1750 WARN(("VBoxTray: vboxDispIfConfigureTargetsWDDM failed winEr 0x%x\n", winEr)); 1751 return winEr; 1752 } 1753 1754 if (!cConnected) 1755 { 1756 Log(("VBoxTray: all targets already connected, nothing to do\n")); 1757 return NO_ERROR; 1758 } 1759 1760 winEr = vboxDispIfWaitDisplayDataInited(pOp, NULL); 1761 if (winEr != NO_ERROR) 1762 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: vboxDispIfWaitDisplayDataInited failed winEr 0x%x\n", winEr)); 1763 1764 DWORD NewNumDevices = VBoxGetDisplayConfigCount(); 1765 if (NewNumDevices == 0) 1766 { 1767 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: Zero devices found\n")); 1768 return ERROR_GEN_FAILURE; 1769 } 1770 1771 if (NewNumDevices != NumDevices) 1772 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: NumDevices(%d) != NewNumDevices(%d)\n", NumDevices, NewNumDevices)); 1773 1774 DISPLAY_DEVICE *paNewDisplayDevices = (DISPLAY_DEVICE *)alloca (sizeof (DISPLAY_DEVICE) * NewNumDevices); 1775 DEVMODE *paNewDeviceModes = (DEVMODE *)alloca (sizeof (DEVMODE) * NewNumDevices); 1776 DWORD NewDevNum = 0; 1777 DWORD NewDevPrimaryNum = 0; 1778 1779 winEr = VBoxGetDisplayConfig(NewNumDevices, &NewDevPrimaryNum, &NewDevNum, paNewDisplayDevices, paNewDeviceModes); 1780 if (winEr != NO_ERROR) 1781 { 1782 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: VBoxGetDisplayConfig failed for new devices, %d\n", winEr)); 1783 return winEr; 1784 } 1785 1786 if (NewNumDevices != NewDevNum) 1787 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: NewNumDevices(%d) != NewDevNum(%d)\n", NewNumDevices, NewDevNum)); 1788 1789 DWORD minDevNum = RT_MIN(DevNum, NewDevNum); 1790 UINT *pIds = (UINT*)alloca (sizeof (UINT) * minDevNum); 1791 UINT cIds = 0; 1792 for (DWORD i = 0; i < minDevNum; ++i) 1793 { 1794 if ((paNewDisplayDevices[i].StateFlags & DISPLAY_DEVICE_ACTIVE) 1795 && !(paDisplayDevices[i].StateFlags & DISPLAY_DEVICE_ACTIVE)) 1796 { 1797 pIds[cIds] = i; 1798 ++cIds; 1799 } 1800 } 1801 1802 if (!cIds) 1803 { 1804 /* this is something we would not regularly expect */ 1805 WARN(("VBoxTray: all targets already have proper config, nothing to do\n")); 1806 return NO_ERROR; 1807 } 1808 1809 if (pOp->pIf->enmMode > VBOXDISPIF_MODE_WDDM) 1810 { 1811 winEr = vboxDispIfWddmEnableDisplaysTryingTopology(pOp->pIf, cIds, pIds, FALSE); 1812 if (winEr != NO_ERROR) 1813 WARN(("VBoxTray: vboxDispIfWddmEnableDisplaysTryingTopology failed to record current settings, %d, ignoring\n", winEr)); 1814 } 1815 else 1816 { 1817 for (DWORD i = 0; i < cIds; ++i) 1818 { 1819 winEr = EnableAndResizeDispDev(paNewDeviceModes, paNewDisplayDevices, NewDevNum, i, 0, 0, 0, 0, 0, FALSE, TRUE); 1820 if (winEr != NO_ERROR) 1821 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: EnableAndResizeDispDev failed winEr 0x%x\n", winEr)); 1822 } 1823 } 1824 1825 return winEr; 1826 } 1827 1828 1829 static DWORD vboxDispIfResizeStartedWDDM(PCVBOXDISPIF const pIf) 1830 { 1831 VBOXDISPIF_OP Op; 1832 1833 DWORD winEr = vboxDispIfOpBegin(pIf, &Op); 1834 if (winEr != NO_ERROR) 1835 { 1836 WARN(("VBoxTray: vboxDispIfOpBegin failed winEr 0x%x\n", winEr)); 1837 return winEr; 1838 } 1839 1840 winEr = vboxDispIfResizeStartedWDDMOp(&Op); 1841 if (winEr != NO_ERROR) 1842 { 1843 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp failed winEr 0x%x\n", winEr)); 1844 } 1845 1846 vboxDispIfOpEnd(&Op); 1847 1848 return winEr; 1849 } 1850 1851 DWORD VBoxDispIfResizeStarted(PCVBOXDISPIF const pIf) 1544 1852 { 1545 1853 switch (pIf->enmMode) 1546 1854 { 1547 1855 case VBOXDISPIF_MODE_XPDM_NT4: 1548 return ERROR_NOT_SUPPORTED;1856 return NO_ERROR; 1549 1857 case VBOXDISPIF_MODE_XPDM: 1550 return ERROR_NOT_SUPPORTED;1858 return NO_ERROR; 1551 1859 #ifdef VBOX_WITH_WDDM 1552 1860 case VBOXDISPIF_MODE_WDDM: 1553 return vboxDispIfReninitModesWDDM(pIf, pScreenIdMask, fReconnectDisplaysOnChange); 1861 case VBOXDISPIF_MODE_WDDM_W7: 1862 return vboxDispIfResizeStartedWDDM(pIf); 1554 1863 #endif 1555 1864 default: 1556 Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));1865 WARN((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode)); 1557 1866 return ERROR_INVALID_PARAMETER; 1558 1867 } … … 1583 1892 if (!bSupported) 1584 1893 { 1585 Log((__FUNCTION__": pfnChangeDisplaySettingsEx function pointer failed to initialize\n"));1894 WARN((__FUNCTION__": pfnChangeDisplaySettingsEx function pointer failed to initialize\n")); 1586 1895 err = ERROR_NOT_SUPPORTED; 1587 1896 } … … 1589 1898 else 1590 1899 { 1591 Log((__FUNCTION__": failed to get user32 handle, err (%d)\n", GetLastError()));1900 WARN((__FUNCTION__": failed to get USER32 handle, err (%d)\n", GetLastError())); 1592 1901 err = ERROR_NOT_SUPPORTED; 1593 1902 } … … 1595 1904 else 1596 1905 { 1597 Log((__FUNCTION__": can not switch to VBOXDISPIF_MODE_XPDM, because os is not >= w2k\n"));1906 WARN((__FUNCTION__": can not switch to VBOXDISPIF_MODE_XPDM, because os is not >= w2k\n")); 1598 1907 err = ERROR_NOT_SUPPORTED; 1599 1908 } … … 1613 1922 1614 1923 #ifdef VBOX_WITH_WDDM 1615 if (pIf->enmMode == VBOXDISPIF_MODE_WDDM)1924 if (pIf->enmMode >= VBOXDISPIF_MODE_WDDM) 1616 1925 { 1617 1926 vboxDispIfWddmTerm(pIf); 1927 1928 vboxDispKmtCallbacksTerm(&pIf->modeData.wddm.KmtCallbacks); 1618 1929 } 1619 1930 #endif … … 1631 1942 } 1632 1943 else 1633 Log((__FUNCTION__": failed to switch to XPDM_NT4 mode, err (%d)\n", err));1944 WARN((__FUNCTION__": failed to switch to XPDM_NT4 mode, err (%d)\n", err)); 1634 1945 break; 1635 1946 case VBOXDISPIF_MODE_XPDM: … … 1642 1953 } 1643 1954 else 1644 Log((__FUNCTION__": failed to switch to XPDM mode, err (%d)\n", err));1955 WARN((__FUNCTION__": failed to switch to XPDM mode, err (%d)\n", err)); 1645 1956 break; 1646 1957 #ifdef VBOX_WITH_WDDM … … 1655 1966 } 1656 1967 else 1657 Log((__FUNCTION__": failed to switch to WDDM mode, err (%d)\n", err)); 1968 WARN((__FUNCTION__": failed to switch to WDDM mode, err (%d)\n", err)); 1969 break; 1970 } 1971 case VBOXDISPIF_MODE_WDDM_W7: 1972 { 1973 Log((__FUNCTION__": request to switch to VBOXDISPIF_MODE_WDDM_W7\n")); 1974 err = vboxDispIfSwitchToWDDM_W7(pIf); 1975 if (err == NO_ERROR) 1976 { 1977 Log((__FUNCTION__": successfully switched to WDDM mode\n")); 1978 pIf->enmMode = VBOXDISPIF_MODE_WDDM_W7; 1979 } 1980 else 1981 WARN((__FUNCTION__": failed to switch to WDDM mode, err (%d)\n", err)); 1658 1982 break; 1659 1983 } … … 1665 1989 return err; 1666 1990 } 1991 1992 static DWORD vboxDispIfSeamlesCreateWDDM(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent) 1993 { 1994 HRESULT hr = vboxDispKmtOpenAdapter(&pIf->modeData.wddm.KmtCallbacks, &pSeamless->modeData.wddm.Adapter); 1995 if (SUCCEEDED(hr)) 1996 { 1997 hr = vboxDispKmtCreateDevice(&pSeamless->modeData.wddm.Adapter, &pSeamless->modeData.wddm.Device); 1998 if (SUCCEEDED(hr)) 1999 { 2000 hr = vboxDispKmtCreateContext(&pSeamless->modeData.wddm.Device, &pSeamless->modeData.wddm.Context, VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_SEAMLESS, 2001 0, 0, hEvent, 0ULL); 2002 if (SUCCEEDED(hr)) 2003 return ERROR_SUCCESS; 2004 else 2005 WARN(("VBoxTray: vboxDispKmtCreateContext failed hr 0x%x", hr)); 2006 2007 vboxDispKmtDestroyDevice(&pSeamless->modeData.wddm.Device); 2008 } 2009 else 2010 WARN(("VBoxTray: vboxDispKmtCreateDevice failed hr 0x%x", hr)); 2011 2012 vboxDispKmtCloseAdapter(&pSeamless->modeData.wddm.Adapter); 2013 } 2014 2015 return hr; 2016 } 2017 2018 static DWORD vboxDispIfSeamlesTermWDDM(VBOXDISPIF_SEAMLESS *pSeamless) 2019 { 2020 vboxDispKmtDestroyContext(&pSeamless->modeData.wddm.Context); 2021 vboxDispKmtDestroyDevice(&pSeamless->modeData.wddm.Device); 2022 vboxDispKmtCloseAdapter(&pSeamless->modeData.wddm.Adapter); 2023 2024 return NO_ERROR; 2025 } 2026 2027 static DWORD vboxDispIfSeamlesSubmitWDDM(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData) 2028 { 2029 D3DKMT_ESCAPE EscapeData = {0}; 2030 EscapeData.hAdapter = pSeamless->modeData.wddm.Adapter.hAdapter; 2031 EscapeData.hDevice = pSeamless->modeData.wddm.Device.hDevice; 2032 EscapeData.hContext = pSeamless->modeData.wddm.Context.hContext; 2033 EscapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE; 2034 EscapeData.Flags.HardwareAccess = 1; 2035 EscapeData.pPrivateDriverData = pData; 2036 EscapeData.PrivateDriverDataSize = VBOXDISPIFESCAPE_SIZE(cbData); 2037 2038 NTSTATUS Status = pSeamless->pIf->modeData.wddm.KmtCallbacks.pfnD3DKMTEscape(&EscapeData); 2039 if (NT_SUCCESS(Status)) 2040 return ERROR_SUCCESS; 2041 2042 WARN(("VBoxTray: pfnD3DKMTEscape Seamless failed Status 0x%x\n", Status)); 2043 return Status; 2044 } 2045 2046 DWORD VBoxDispIfSeamlesCreate(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent) 2047 { 2048 memset(pSeamless, 0, sizeof (*pSeamless)); 2049 pSeamless->pIf = pIf; 2050 2051 switch (pIf->enmMode) 2052 { 2053 case VBOXDISPIF_MODE_XPDM_NT4: 2054 case VBOXDISPIF_MODE_XPDM: 2055 return NO_ERROR; 2056 #ifdef VBOX_WITH_WDDM 2057 case VBOXDISPIF_MODE_WDDM: 2058 case VBOXDISPIF_MODE_WDDM_W7: 2059 return vboxDispIfSeamlesCreateWDDM(pIf, pSeamless, hEvent); 2060 #endif 2061 default: 2062 WARN(("VBoxTray: VBoxDispIfSeamlesCreate: invalid mode %d\n", pIf->enmMode)); 2063 return ERROR_INVALID_PARAMETER; 2064 } 2065 } 2066 2067 DWORD VBoxDispIfSeamlesTerm(VBOXDISPIF_SEAMLESS *pSeamless) 2068 { 2069 PCVBOXDISPIF const pIf = pSeamless->pIf; 2070 DWORD winEr; 2071 switch (pIf->enmMode) 2072 { 2073 case VBOXDISPIF_MODE_XPDM_NT4: 2074 case VBOXDISPIF_MODE_XPDM: 2075 winEr = NO_ERROR; 2076 break; 2077 #ifdef VBOX_WITH_WDDM 2078 case VBOXDISPIF_MODE_WDDM: 2079 case VBOXDISPIF_MODE_WDDM_W7: 2080 winEr = vboxDispIfSeamlesTermWDDM(pSeamless); 2081 break; 2082 #endif 2083 default: 2084 WARN(("VBoxTray: VBoxDispIfSeamlesTerm: invalid mode %d\n", pIf->enmMode)); 2085 winEr = ERROR_INVALID_PARAMETER; 2086 break; 2087 } 2088 2089 if (winEr == NO_ERROR) 2090 memset(pSeamless, 0, sizeof (*pSeamless)); 2091 2092 return winEr; 2093 } 2094 2095 DWORD VBoxDispIfSeamlesSubmit(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData) 2096 { 2097 PCVBOXDISPIF const pIf = pSeamless->pIf; 2098 2099 if (pData->escapeCode != VBOXESC_SETVISIBLEREGION) 2100 { 2101 WARN(("VBoxTray: invalid escape code for Seamless submit %d\n", pData->escapeCode)); 2102 return ERROR_INVALID_PARAMETER; 2103 } 2104 2105 switch (pIf->enmMode) 2106 { 2107 case VBOXDISPIF_MODE_XPDM_NT4: 2108 case VBOXDISPIF_MODE_XPDM: 2109 return VBoxDispIfEscape(pIf, pData, cbData); 2110 #ifdef VBOX_WITH_WDDM 2111 case VBOXDISPIF_MODE_WDDM: 2112 case VBOXDISPIF_MODE_WDDM_W7: 2113 return vboxDispIfSeamlesSubmitWDDM(pSeamless, pData, cbData); 2114 #endif 2115 default: 2116 WARN(("VBoxTray: VBoxDispIfSeamlesSubmit: invalid mode %d\n", pIf->enmMode)); 2117 return ERROR_INVALID_PARAMETER; 2118 } 2119 } -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDispIf.h
r44729 r48070 19 19 # define D3DKMDT_SPECIAL_MULTIPLATFORM_TOOL 20 20 # include <d3dkmthk.h> 21 # include "../Graphics/Video/disp/wddm/VBoxDispKmt.h" 21 22 #endif 22 23 … … 30 31 #ifdef VBOX_WITH_WDDM 31 32 , VBOXDISPIF_MODE_WDDM 33 , VBOXDISPIF_MODE_WDDM_W7 32 34 #endif 33 35 } VBOXDISPIF_MODE; … … 59 61 BOOL (WINAPI * pfnEnumDisplayDevices)(IN LPCSTR lpDevice, IN DWORD iDevNum, OUT PDISPLAY_DEVICEA lpDisplayDevice, IN DWORD dwFlags); 60 62 61 /* open adapter */ 62 PFND3DKMT_OPENADAPTERFROMHDC pfnD3DKMTOpenAdapterFromHdc; 63 PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME pfnD3DKMTOpenAdapterFromGdiDisplayName; 64 /* close adapter */ 65 PFND3DKMT_CLOSEADAPTER pfnD3DKMTCloseAdapter; 66 /* escape */ 67 PFND3DKMT_ESCAPE pfnD3DKMTEscape; 68 /* auto resize support */ 69 PFND3DKMT_INVALIDATEACTIVEVIDPN pfnD3DKMTInvalidateActiveVidPn; 70 PFND3DKMT_POLLDISPLAYCHILDREN pfnD3DKMTPollDisplayChildren; 63 VBOXDISPKMT_CALLBACKS KmtCallbacks; 71 64 } wddm; 72 65 #endif … … 84 77 DWORD VBoxDispIfEscape(PCVBOXDISPIF const pIf, PVBOXDISPIFESCAPE pEscape, int cbData); 85 78 DWORD VBoxDispIfEscapeInOut(PCVBOXDISPIF const pIf, PVBOXDISPIFESCAPE pEscape, int cbData); 86 DWORD VBoxDispIfResize(PCVBOXDISPIF const pIf, ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel); 87 DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes); 79 DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes); 88 80 DWORD VBoxDispIfCancelPendingResize(PCVBOXDISPIF const pIf); 89 DWORD vboxDispIfWddmEnableDisplay(PCVBOXDISPIF const pIf, UINT Id, bool fEnabled); 90 DWORD vboxDispIfWddmResizeDisplay(PCVBOXDISPIF const pIf, UINT Id, DISPLAY_DEVICE * paDisplayDevices, DEVMODE *paDeviceMode, UINT devModes); 91 //DWORD VBoxDispIfReninitModes(PCVBOXDISPIF const pIf, uint8_t *pScreenIdMask, BOOL fReconnectDisplaysOnChange); 81 82 DWORD VBoxDispIfResizeStarted(PCVBOXDISPIF const pIf); 83 84 85 typedef struct VBOXDISPIF_SEAMLESS 86 { 87 PCVBOXDISPIF pIf; 88 89 union 90 { 91 #ifdef VBOX_WITH_WDDM 92 struct 93 { 94 VBOXDISPKMT_ADAPTER Adapter; 95 VBOXDISPKMT_DEVICE Device; 96 VBOXDISPKMT_CONTEXT Context; 97 } wddm; 98 #endif 99 } modeData; 100 } VBOXDISPIF_SEAMLESS; 101 102 DECLINLINE(bool) VBoxDispIfSeamlesIsValid(VBOXDISPIF_SEAMLESS *pSeamless) 103 { 104 return !!pSeamless->pIf; 105 } 106 107 DWORD VBoxDispIfSeamlesCreate(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent); 108 DWORD VBoxDispIfSeamlesTerm(VBOXDISPIF_SEAMLESS *pSeamless); 109 DWORD VBoxDispIfSeamlesSubmit(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData); -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp
r48030 r48070 90 90 Log(("VBoxTray: VBoxDisplayInit: WDDM driver is installed, switching display driver if to WDDM mode\n")); 91 91 /* this is hacky, but the most easiest way */ 92 DWORD err = VBoxDispIfSwitchMode(const_cast<PVBOXDISPIF>(&pEnv->dispIf), VBOXDISPIF_MODE_WDDM, NULL /* old mode, we don't care about it */); 92 VBOXDISPIF_MODE enmMode = (OSinfo.dwMajorVersion > 6 || OSinfo.dwMinorVersion > 0) ? VBOXDISPIF_MODE_WDDM_W7 : VBOXDISPIF_MODE_WDDM; 93 DWORD err = VBoxDispIfSwitchMode(const_cast<PVBOXDISPIF>(&pEnv->dispIf), enmMode, NULL /* old mode, we don't care about it */); 93 94 if (err == NO_ERROR) 94 95 Log(("VBoxTray: VBoxDisplayInit: DispIf switched to WDDM mode successfully\n")); … … 213 214 } 214 215 215 staticDWORD EnableAndResizeDispDev(DEVMODE *paDeviceModes, DISPLAY_DEVICE *paDisplayDevices, DWORD totalDispNum, UINT Id, DWORD aWidth, DWORD aHeight,216 DWORD aBitsPerPixel, DWORD aPosX, DWORD aPosY, BOOL fEnabled, BOOL fExtDispSup , VBOXDISPLAYCONTEXT *pCtx)216 DWORD EnableAndResizeDispDev(DEVMODE *paDeviceModes, DISPLAY_DEVICE *paDisplayDevices, DWORD totalDispNum, UINT Id, DWORD aWidth, DWORD aHeight, 217 DWORD aBitsPerPixel, DWORD aPosX, DWORD aPosY, BOOL fEnabled, BOOL fExtDispSup) 217 218 { 218 219 DISPLAY_DEVICE displayDeviceTmp; … … 307 308 } 308 309 return dwStatus; 309 } 310 311 /* Returns TRUE to try again. */ 312 static BOOL ResizeDisplayDevice(UINT Id, DWORD Width, DWORD Height, DWORD BitsPerPixel, 313 BOOL fEnabled, DWORD dwNewPosX, DWORD dwNewPosY, 314 VBOXDISPLAYCONTEXT *pCtx, BOOL fExtDispSup) 310 } 311 312 DWORD VBoxGetDisplayConfigCount() 315 313 { 316 BOOL fDispAlreadyEnabled = false; /* check whether the monitor with ID is already enabled. */317 BOOL fModeReset = (Width == 0 && Height == 0 && BitsPerPixel == 0 &&318 dwNewPosX == 0 && dwNewPosY == 0);319 BOOL fChangePosRequest = false; /* change in position requested */320 321 Log(("VBoxTray: ResizeDisplayDevice Width= %d, Height=%d , PosX=%d and PosY=%d \322 fEnabled = %d, fExtDisSup = %d\n",323 Width, Height, dwNewPosX, dwNewPosY, fEnabled, fExtDispSup));324 325 if (!gCtx.fAnyX)326 Width &= 0xFFF8;327 328 314 DISPLAY_DEVICE DisplayDevice; 329 DWORD dwStatus;330 315 331 316 ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE)); 332 317 DisplayDevice.cb = sizeof(DISPLAY_DEVICE); 333 334 VBoxDispIfCancelPendingResize(&pCtx->pEnv->dispIf);335 318 336 319 /* Find out how many display devices the system has */ … … 358 341 } 359 342 360 Log(("VBoxTray: ResizeDisplayDevice: Found total %d devices. err %d\n", NumDevices, GetLastError ())); 361 362 if (NumDevices == 0 || Id >= NumDevices) 363 { 364 Log(("VBoxTray: ResizeDisplayDevice: Requested identifier %d is invalid. err %d\n", Id, GetLastError ())); 365 return FALSE; 366 } 367 368 DISPLAY_DEVICE *paDisplayDevices = (DISPLAY_DEVICE *)alloca (sizeof (DISPLAY_DEVICE) * NumDevices); 369 DEVMODE *paDeviceModes = (DEVMODE *)alloca (sizeof (DEVMODE) * NumDevices); 370 RECTL *paRects = (RECTL *)alloca (sizeof (RECTL) * NumDevices); 371 343 return NumDevices; 344 } 345 346 DWORD VBoxGetDisplayConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes) 347 { 372 348 /* Fetch information about current devices and modes. */ 373 349 DWORD DevNum = 0; 374 350 DWORD DevPrimaryNum = 0; 375 351 352 DISPLAY_DEVICE DisplayDevice; 353 376 354 ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE)); 377 355 DisplayDevice.cb = sizeof(DISPLAY_DEVICE); 378 356 379 i = 0;357 DWORD i = 0; 380 358 while (EnumDisplayDevices (NULL, i, &DisplayDevice, 0)) 381 359 { … … 401 379 if (DevNum >= NumDevices) 402 380 { 403 Log(("VBoxTray: ResizeDisplayDevice: %d >= %d\n", NumDevices, DevNum));404 return FALSE;381 WARN(("VBoxTray: ResizeDisplayDevice: %d >= %d\n", NumDevices, DevNum)); 382 return ERROR_BUFFER_OVERFLOW; 405 383 } 406 384 … … 438 416 } 439 417 440 if (fExtDispSup) 441 { 442 LogRel(("VBoxTray: Extended Display Support.\n")); 443 Log(("VBoxTray: ResizeDisplayDevice1: %dx%dx%d at %d,%d . Id = %d and DevNum=%d, fEnabled=%d\n", 444 paDeviceModes[Id].dmPelsWidth, 445 paDeviceModes[Id].dmPelsHeight, 446 paDeviceModes[Id].dmBitsPerPel, 447 paDeviceModes[Id].dmPosition.x, 448 paDeviceModes[Id].dmPosition.y, 449 Id, DevNum, fEnabled)); 450 if ((DevNum == Id && fEnabled == 1)) 451 { 452 /* Calculation of new position for enabled 453 * secondary monitor . 454 */ 455 /* Used when a secondary monitor just needs to be enabled, without any 456 * change in its position 457 */ 458 if (dwNewPosX != 0) 459 { 460 LogRel(("VBoxTray: Setting Rectangle position x=%d*y=%d\n", dwNewPosX, dwNewPosY)); 461 paDeviceModes[DevNum].dmPosition.x = dwNewPosX; 462 paDeviceModes[DevNum].dmPosition.y = dwNewPosY; 463 fChangePosRequest = true; 464 } 465 paRects[DevNum].left = paDeviceModes[DevNum].dmPosition.x; 466 paRects[DevNum].top = paDeviceModes[DevNum].dmPosition.y; 467 paRects[DevNum].right = paDeviceModes[DevNum].dmPosition.x + paDeviceModes[DevNum].dmPelsWidth; 468 paRects[DevNum].bottom = paDeviceModes[DevNum].dmPosition.y + paDeviceModes[DevNum].dmPelsHeight; 469 } 470 else 471 { 472 paRects[DevNum].left = paDeviceModes[DevNum].dmPosition.x; 473 paRects[DevNum].top = paDeviceModes[DevNum].dmPosition.y; 474 paRects[DevNum].right = paDeviceModes[DevNum].dmPosition.x + paDeviceModes[DevNum].dmPelsWidth; 475 paRects[DevNum].bottom = paDeviceModes[DevNum].dmPosition.y + paDeviceModes[DevNum].dmPelsHeight; 476 } 477 } 478 else 479 { 480 LogRel(("VBoxTray: NO Ext Display Support \n")); 481 paRects[DevNum].left = paDeviceModes[DevNum].dmPosition.x; 482 paRects[DevNum].top = paDeviceModes[DevNum].dmPosition.y; 483 paRects[DevNum].right = paDeviceModes[DevNum].dmPosition.x + paDeviceModes[DevNum].dmPelsWidth; 484 paRects[DevNum].bottom = paDeviceModes[DevNum].dmPosition.y + paDeviceModes[DevNum].dmPelsHeight; 485 } 418 486 419 DevNum++; 487 420 } … … 491 424 i++; 492 425 } 426 427 *pNumDevices = DevNum; 428 429 return NO_ERROR; 430 } 431 432 /* Returns TRUE to try again. */ 433 static BOOL ResizeDisplayDevice(UINT Id, DWORD Width, DWORD Height, DWORD BitsPerPixel, 434 BOOL fEnabled, DWORD dwNewPosX, DWORD dwNewPosY, 435 VBOXDISPLAYCONTEXT *pCtx, BOOL fExtDispSup) 436 { 437 BOOL fDispAlreadyEnabled = false; /* check whether the monitor with ID is already enabled. */ 438 BOOL fModeReset = (Width == 0 && Height == 0 && BitsPerPixel == 0 && 439 dwNewPosX == 0 && dwNewPosY == 0); 440 DWORD dmFields = 0; 441 442 Log(("VBoxTray: ResizeDisplayDevice Width= %d, Height=%d , PosX=%d and PosY=%d \ 443 fEnabled = %d, fExtDisSup = %d\n", 444 Width, Height, dwNewPosX, dwNewPosY, fEnabled, fExtDispSup)); 445 446 if (!gCtx.fAnyX) 447 Width &= 0xFFF8; 448 449 VBoxDispIfCancelPendingResize(&pCtx->pEnv->dispIf); 450 451 DWORD NumDevices = VBoxGetDisplayConfigCount(); 452 453 if (NumDevices == 0 || Id >= NumDevices) 454 { 455 WARN(("VBoxTray: ResizeDisplayDevice: Requested identifier %d is invalid. err %d\n", Id, GetLastError ())); 456 return FALSE; 457 } 458 459 Log(("VBoxTray: ResizeDisplayDevice: Found total %d devices. err %d\n", NumDevices, GetLastError ())); 460 461 DISPLAY_DEVICE *paDisplayDevices = (DISPLAY_DEVICE *)alloca (sizeof (DISPLAY_DEVICE) * NumDevices); 462 DEVMODE *paDeviceModes = (DEVMODE *)alloca (sizeof (DEVMODE) * NumDevices); 463 RECTL *paRects = (RECTL *)alloca (sizeof (RECTL) * NumDevices); 464 DWORD DevNum = 0; 465 DWORD DevPrimaryNum = 0; 466 DWORD dwStatus = VBoxGetDisplayConfig(NumDevices, &DevPrimaryNum, &DevNum, paDisplayDevices, paDeviceModes); 467 if (dwStatus != NO_ERROR) 468 { 469 WARN(("VBoxTray: ResizeDisplayDevice: VBoxGetDisplayConfig failed, %d\n", dwStatus)); 470 return dwStatus; 471 } 472 473 if (NumDevices != DevNum) 474 WARN(("VBoxTray: ResizeDisplayDevice: NumDevices(%d) != DevNum(%d)\n", NumDevices, DevNum)); 475 476 DWORD i = 0; 477 478 for (i = 0; i < DevNum; ++i) 479 { 480 if (fExtDispSup) 481 { 482 LogRel(("VBoxTray: Extended Display Support.\n")); 483 Log(("VBoxTray: ResizeDisplayDevice1: %dx%dx%d at %d,%d . Id = %d and DevNum=%d, fEnabled=%d\n", 484 paDeviceModes[Id].dmPelsWidth, 485 paDeviceModes[Id].dmPelsHeight, 486 paDeviceModes[Id].dmBitsPerPel, 487 paDeviceModes[Id].dmPosition.x, 488 paDeviceModes[Id].dmPosition.y, 489 Id, DevNum, fEnabled)); 490 } 491 else 492 { 493 LogRel(("VBoxTray: NO Ext Display Support \n")); 494 } 495 496 paRects[i].left = paDeviceModes[i].dmPosition.x; 497 paRects[i].top = paDeviceModes[i].dmPosition.y; 498 paRects[i].right = paDeviceModes[i].dmPosition.x + paDeviceModes[i].dmPelsWidth; 499 paRects[i].bottom = paDeviceModes[i].dmPosition.y + paDeviceModes[i].dmPelsHeight; 500 } 501 493 502 /* Keep a record if the display with ID is already active or not. */ 494 503 if (paDisplayDevices[Id].StateFlags & DISPLAY_DEVICE_ACTIVE) … … 504 513 */ 505 514 if (Width == 0) 506 {507 515 Width = paRects[Id].right - paRects[Id].left; 508 } 516 else 517 dmFields |= DM_PELSWIDTH; 509 518 510 519 if (Height == 0) 511 {512 520 Height = paRects[Id].bottom - paRects[Id].top; 513 } 521 else 522 dmFields |= DM_PELSHEIGHT; 523 524 if (BitsPerPixel == 0) 525 BitsPerPixel = paDeviceModes[Id].dmBitsPerPel; 526 else 527 dmFields |= DM_BITSPERPEL; 528 529 if (!dwNewPosX && !dwNewPosY) 530 { 531 /* @fixme: zero position is a valid state, so another values should be used as a special case !!! */ 532 dwNewPosX = paRects[Id].left; 533 dwNewPosY = paRects[Id].top; 534 } 535 else 536 dmFields |= DM_POSITION; 514 537 515 538 /* Check whether a mode reset or a change is requested. … … 529 552 * all rect conditions are true. Thus in this case nothing has to be done. 530 553 */ 531 if ( !fModeReset && fEnabled && fDispAlreadyEnabled && !fChangePosRequest 554 if ( !fModeReset && (!fEnabled == !fDispAlreadyEnabled) 555 && paRects[Id].left == dwNewPosX 556 && paRects[Id].top == dwNewPosY 532 557 && paRects[Id].right - paRects[Id].left == Width 533 558 && paRects[Id].bottom - paRects[Id].top == Height … … 538 563 } 539 564 540 hlpResizeRect(paRects, NumDevices, DevPrimaryNum, Id, Width, Height); 565 hlpResizeRect(paRects, NumDevices, DevPrimaryNum, Id, 566 fEnabled ? Width : 0, fEnabled ? Height : 0, dwNewPosX, dwNewPosY); 541 567 #ifdef Log 542 568 for (i = 0; i < NumDevices; i++) … … 561 587 paDeviceModes[i].dmPelsHeight = paRects[i].bottom - paRects[i].top; 562 588 589 if (i == Id) 590 paDeviceModes[i].dmBitsPerPel = BitsPerPixel; 591 592 paDeviceModes[i].dmFields |= dmFields; 593 563 594 /* On Vista one must specify DM_BITSPERPEL. 564 595 * Note that the current mode dmBitsPerPel is already in the DEVMODE structure. 565 596 */ 566 paDeviceModes[i].dmFields = DM_PELSHEIGHT | DM_PELSWIDTH | DM_BITSPERPEL; 567 568 if (i == Id && BitsPerPixel != 0) 597 if (!(paDeviceModes[i].dmFields & DM_BITSPERPEL)) 569 598 { 570 LogRel(("VBoxTray: (WDDM)Changing resolution and position. \n")); 571 /* Change dmBitsPerPel if requested. */ 572 paDeviceModes[i].dmBitsPerPel = BitsPerPixel; 573 paDeviceModes[i].dmPelsWidth = Width; 574 paDeviceModes[i].dmPelsHeight = Height; 575 if (dwNewPosX != 0 || dwNewPosY != 0) 576 { 577 paDeviceModes[Id].dmPosition.x = dwNewPosX; 578 paDeviceModes[Id].dmPosition.y = dwNewPosY; 579 } 580 else 581 { 582 paDeviceModes[i].dmFields |= DM_POSITION; 583 paDeviceModes[Id].dmPosition.x = 0; 584 paDeviceModes[Id].dmPosition.y = 0; 585 } 599 WARN(("VBoxTray: (WDDM) no DM_BITSPERPEL\n")); 600 paDeviceModes[i].dmFields |= DM_BITSPERPEL; 601 paDeviceModes[i].dmBitsPerPel = 32; 586 602 } 587 603 … … 593 609 paDeviceModes[i].dmPosition.x, 594 610 paDeviceModes[i].dmPosition.y)); 595 596 } 597 /* Reques to enable /disable the secondary Display Device. Won't take the resize request now.*/ 598 if (!fDispAlreadyEnabled && fEnabled || fDispAlreadyEnabled && !fEnabled) 599 { 600 OSVERSIONINFO OSinfo; 601 OSinfo.dwOSVersionInfoSize = sizeof (OSinfo); 602 GetVersionEx (&OSinfo); 603 604 /* for win 7 and above */ 605 if (OSinfo.dwMajorVersion >= 6 && OSinfo.dwMinorVersion >= 1) 606 { 607 LogRel(("VBoxTray: (WDDM) Request to enable/disable %d display device\n", fEnabled)); 608 DWORD dwStatus = vboxDispIfWddmEnableDisplay(&pCtx->pEnv->dispIf, Id, RT_BOOL(fEnabled)); 609 if(dwStatus != ERROR_SUCCESS) 610 { 611 /* Not going to retry for enabling or disabling of the secondary display device.*/ 612 LogRel(("VBoxTray: (WDDM) Failed to enable the Display Device \n")); 613 } 614 } 615 else /* case: vista in wddm mode. SetDisplayConfig APIs etc is not avilable in this mode. */ 616 { 617 /* use traditional approach of ChangeDisplaySettingEx to enable/disable secondary monitor for Vista WDDM mode.*/ 618 dwStatus = EnableAndResizeDispDev(paDeviceModes, paDisplayDevices, DevNum, Id, Width, Height, BitsPerPixel, 619 dwNewPosX, dwNewPosY, fEnabled, fExtDispSup, pCtx); 620 if (dwStatus != DISP_CHANGE_SUCCESSFUL ) 621 { 622 /* Successfully set new video mode or our driver can not set 623 * the requested mode. Stop trying. 624 */ 625 LogRel(("VBoxTray: (WDDM) Failed to enable/disable the Display Device \n")); 626 } 627 } 628 return FALSE; /* for enable disable not retrying */ 629 } 630 else 631 { 632 /* Resize request. Secondary display device should be in an enabled state. */ 633 LogRel(("VBoxTray: (WDDM) Request to resize the display \n")); 634 DWORD err = VBoxDispIfResizeModes(&pCtx->pEnv->dispIf, Id, paDisplayDevices, paDeviceModes, NumDevices); 635 if (err == NO_ERROR || err != ERROR_RETRY) 636 { 637 if (err == NO_ERROR) 638 LogRel(("VBoxTray: VBoxDisplayThread: (WDDM) VBoxDispIfResizeModes succeeded\n")); 639 else 640 LogRel(("VBoxTray: VBoxDisplayThread: (WDDM) Failure VBoxDispIfResizeModes (%d)\n", err)); 641 return FALSE; 642 } 643 } 611 } 612 613 Log(("VBoxTray: (WDDM) Request to resize the displa\n")); 614 DWORD err = VBoxDispIfResizeModes(&pCtx->pEnv->dispIf, Id, fEnabled, fExtDispSup, paDisplayDevices, paDeviceModes, DevNum); 615 if (err == NO_ERROR || err != ERROR_RETRY) 616 { 617 if (err == NO_ERROR) 618 Log(("VBoxTray: VBoxDisplayThread: (WDDM) VBoxDispIfResizeModes succeeded\n")); 619 else 620 WARN(("VBoxTray: VBoxDisplayThread: (WDDM) Failure VBoxDispIfResizeModes (%d)\n", err)); 621 return FALSE; 622 } 623 644 624 Log(("VBoxTray: ResizeDisplayDevice: (WDDM) RETRY requested\n")); 645 625 return TRUE; … … 695 675 Id, Width, Height, dwNewPosX, dwNewPosY, fEnabled, fExtDispSup)); 696 676 dwStatus = EnableAndResizeDispDev(paDeviceModes, paDisplayDevices, DevNum, Id, Width, Height, BitsPerPixel, 697 dwNewPosX, dwNewPosY, fEnabled, fExtDispSup , pCtx);677 dwNewPosX, dwNewPosY, fEnabled, fExtDispSup); 698 678 if (dwStatus == DISP_CHANGE_SUCCESSFUL || dwStatus == DISP_CHANGE_BADMODE) 699 679 { … … 730 710 731 711 PostMessage(ghwndToolWindow, WM_VBOX_GRAPHICS_SUPPORTED, 0, 0); 712 713 VBoxDispIfResizeStarted(&pCtx->pEnv->dispIf); 732 714 733 715 do … … 979 961 if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED) 980 962 hlpReloadCursor(); 981 } else 963 } 964 else 982 965 { 983 966 Log(("VBoxTray: VBoxDisplayThread: error 0 from DeviceIoControl VBOXGUEST_IOCTL_WAITEVENT\n")); -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.h
r44528 r48070 23 23 void VBoxDisplayDestroy (const VBOXSERVICEENV *pEnv, void *pInstance); 24 24 25 DWORD VBoxGetDisplayConfigCount(); 26 DWORD VBoxGetDisplayConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes); 27 25 28 #ifndef VBOX_WITH_WDDM 26 29 static bool isVBoxDisplayDriverActive (void); -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHelpers.cpp
r35907 r48070 112 112 113 113 void hlpResizeRect(RECTL *paRects, unsigned nRects, unsigned uPrimary, 114 unsigned uResized, int iNewWidth, int iNewHeight) 114 unsigned uResized, int iNewWidth, int iNewHeight, 115 int iNewPosX, int iNewPosY) 115 116 { 116 117 DDCLOG(("nRects %d, iPrimary %d, iResized %d, NewWidth %d, NewHeight %d\n", nRects, uPrimary, uResized, iNewWidth, iNewHeight)); … … 120 121 paNewRects[uResized].right += iNewWidth - (paNewRects[uResized].right - paNewRects[uResized].left); 121 122 paNewRects[uResized].bottom += iNewHeight - (paNewRects[uResized].bottom - paNewRects[uResized].top); 123 paNewRects[uResized].right += iNewPosX - paNewRects[uResized].left; 124 paNewRects[uResized].bottom += iNewPosY - paNewRects[uResized].top; 125 paNewRects[uResized].left = iNewPosX; 126 paNewRects[uResized].top = iNewPosY; 122 127 123 128 /* Verify all pairs of originally adjacent rectangles for all 4 directions. -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHelpers.h
r44528 r48070 29 29 extern int hlpReportStatus(VBoxGuestFacilityStatus statusCurrent); 30 30 extern void hlpReloadCursor(void); 31 extern void hlpResizeRect(RECTL *paRects, unsigned nRects, unsigned uPrimary, unsigned uResized, int iNewWidth, int iNewHeight );31 extern void hlpResizeRect(RECTL *paRects, unsigned nRects, unsigned uPrimary, unsigned uResized, int iNewWidth, int iNewHeight, int iNewPosX, int iNewPosY); 32 32 extern int hlpShowBalloonTip(HINSTANCE hInst, HWND hWnd, UINT uID, const char *pszMsg, const char *pszTitle, UINT uTimeout, DWORD dwInfoFlags); 33 33 -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxSeamless.cpp
r46593 r48070 116 116 } 117 117 118 void VBoxSeamlessInstallHook()118 static void VBoxSeamlessInstallHook() 119 119 { 120 120 if (gCtx.pfnVBoxHookInstallWindowTracker) 121 121 { 122 122 /* Check current visible region state */ 123 VBoxSeamlessCheckWindows( );123 VBoxSeamlessCheckWindows(true); 124 124 125 125 HMODULE hMod = (HMODULE)RTLdrGetNativeHandle(gCtx.hModHook); … … 129 129 } 130 130 131 void VBoxSeamlessRemoveHook()131 static void VBoxSeamlessRemoveHook() 132 132 { 133 133 if (gCtx.pfnVBoxHookRemoveWindowTracker) … … 139 139 gCtx.lpEscapeData = NULL; 140 140 } 141 } 142 143 extern HANDLE ghSeamlessKmNotifyEvent; 144 145 static VBOXDISPIF_SEAMLESS gVBoxDispIfSeamless; 146 147 148 void VBoxSeamlessEnable() 149 { 150 Assert(ghSeamlessKmNotifyEvent); 151 152 VBoxDispIfSeamlesCreate(&gCtx.pEnv->dispIf, &gVBoxDispIfSeamless, ghSeamlessKmNotifyEvent); 153 154 VBoxSeamlessInstallHook(); 155 } 156 157 void VBoxSeamlessDisable() 158 { 159 VBoxSeamlessRemoveHook(); 160 161 VBoxDispIfSeamlesTerm(&gVBoxDispIfSeamless); 141 162 } 142 163 … … 245 266 } 246 267 247 void VBoxSeamlessCheckWindows() 248 { 268 void VBoxSeamlessCheckWindows(bool fForce) 269 { 270 if (!VBoxDispIfSeamlesIsValid(&gVBoxDispIfSeamless)) 271 return; 272 249 273 VBOX_ENUM_PARAM param; 250 274 … … 280 304 #endif 281 305 LPRGNDATA lpCtxRgnData = VBOXDISPIFESCAPE_DATA(gCtx.lpEscapeData, RGNDATA); 282 if ( !gCtx.lpEscapeData 306 if (fForce 307 || !gCtx.lpEscapeData 283 308 || (lpCtxRgnData->rdh.dwSize + lpCtxRgnData->rdh.nRgnSize != cbSize) 284 309 || memcmp(lpCtxRgnData, lpRgnData, cbSize)) 285 310 { 286 311 /* send to display driver */ 287 VBoxDispIf Escape(&gCtx.pEnv->dispIf, lpEscapeData, cbSize);312 VBoxDispIfSeamlesSubmit(&gVBoxDispIfSeamless, lpEscapeData, cbSize); 288 313 289 314 if (gCtx.lpEscapeData) -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxSeamless.h
r45760 r48070 24 24 25 25 26 void VBoxSeamless InstallHook();27 void VBoxSeamless RemoveHook();28 void VBoxSeamlessCheckWindows( );26 void VBoxSeamlessEnable(); 27 void VBoxSeamlessDisable(); 28 void VBoxSeamlessCheckWindows(bool fForce); 29 29 30 30 void VBoxSeamlessSetSupported(BOOL fSupported); -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp
r47195 r48070 46 46 #include <Wtsapi32.h> 47 47 48 #ifdef DEBUG_misha49 #define WARN(_m) do { \50 Assert(0); \51 Log(_m); \52 } while (0)53 #else54 #define WARN(_m) do { \55 Log(_m); \56 } while (0)57 #endif58 59 48 /* 60 49 * St (session [state] tracking) functionality API … … 136 125 HANDLE ghStopSem; 137 126 HANDLE ghSeamlessWtNotifyEvent = 0; 127 HANDLE ghSeamlessKmNotifyEvent = 0; 138 128 SERVICE_STATUS gVBoxServiceStatus; 139 129 SERVICE_STATUS_HANDLE gVBoxServiceStatusHandle; … … 629 619 Log(("VBoxTray: CreateEvent for Seamless failed, last error = %08X\n", dwErr)); 630 620 } 621 622 ghSeamlessKmNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 623 if (ghSeamlessKmNotifyEvent == NULL) 624 { 625 dwErr = GetLastError(); 626 Log(("VBoxTray: CreateEvent for Seamless failed, last error = %08X\n", dwErr)); 627 } 631 628 } 632 629 } … … 640 637 CloseHandle(ghSeamlessWtNotifyEvent); 641 638 ghSeamlessWtNotifyEvent = NULL; 639 } 640 641 if (ghSeamlessKmNotifyEvent) 642 { 643 CloseHandle(ghSeamlessKmNotifyEvent); 644 ghSeamlessKmNotifyEvent = NULL; 642 645 } 643 646 } … … 725 728 */ 726 729 727 HANDLE hWaitEvent[ 3] = {0};730 HANDLE hWaitEvent[4] = {0}; 728 731 DWORD dwEventCount = 0; 729 732 … … 734 737 { 735 738 hWaitEvent[dwEventCount++] = ghSeamlessWtNotifyEvent; 739 } 740 741 if (0 != ghSeamlessKmNotifyEvent) 742 { 743 hWaitEvent[dwEventCount++] = ghSeamlessKmNotifyEvent; 736 744 } 737 745 … … 768 776 769 777 /* seamless window notification */ 770 VBoxSeamlessCheckWindows(); 778 VBoxSeamlessCheckWindows(false); 779 fHandled = TRUE; 780 } 781 else if (hWaitEvent[waitResult] == ghSeamlessKmNotifyEvent) 782 { 783 Log(("VBoxTray: Event 'Km Seamless' triggered\n")); 784 785 /* seamless window notification */ 786 VBoxSeamlessCheckWindows(true); 771 787 fHandled = TRUE; 772 788 } … … 988 1004 case WM_VBOX_SEAMLESS_UPDATE: 989 1005 if (VBoxCapsEntryIsEnabled(VBOXCAPS_ENTRY_IDX_SEAMLESS)) 990 VBoxSeamlessCheckWindows( );1006 VBoxSeamlessCheckWindows(true); 991 1007 return 0; 992 1008 … … 1297 1313 if (GetVersionEx(&info)) 1298 1314 { 1299 WARN(("VBoxTray: Windows version %ld.%ld\n", info.dwMajorVersion, info.dwMinorVersion));1315 LogRel(("VBoxTray: Windows version %ld.%ld\n", info.dwMajorVersion, info.dwMinorVersion)); 1300 1316 gMajorVersion = info.dwMajorVersion; 1301 1317 } … … 1507 1523 Assert(pCap->enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED); 1508 1524 Assert(pCap->enmFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED); 1509 VBoxSeamless InstallHook();1525 VBoxSeamlessEnable(); 1510 1526 } 1511 1527 else … … 1513 1529 Log(("VBoxTray: vboxCapsOnEnableSeamles: DISABLED\n")); 1514 1530 Assert(pCap->enmAcState != VBOXCAPS_ENTRY_ACSTATE_ACQUIRED || pCap->enmFuncState != VBOXCAPS_ENTRY_FUNCSTATE_STARTED); 1515 VBoxSeamless RemoveHook();1531 VBoxSeamlessDisable(); 1516 1532 } 1517 1533 } -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.h
r47195 r48070 54 54 55 55 #include "VBoxDispIf.h" 56 57 #ifdef DEBUG_misha 58 #define WARN(_m) do { \ 59 Assert(0); \ 60 Log(_m); \ 61 } while (0) 62 #else 63 #define WARN(_m) do { \ 64 Log(_m); \ 65 } while (0) 66 #endif 56 67 57 68 /*
Note:
See TracChangeset
for help on using the changeset viewer.