VirtualBox

Changeset 48070 in vbox for trunk


Ignore:
Timestamp:
Aug 26, 2013 6:13:22 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
88439
Message:

wddm,vboxtray: forward-port autoresize, multimon, and seamless fixes from 4.2 r87071, r87353, r87356, r87528, r87568, r87581, r87584, r87608, r87673, r87678, r87708, r87629, r87529; additional fixes

Location:
trunk/src/VBox
Files:
31 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/common/wddm/VBoxMPIf.h

    r46966 r48070  
    252252    VBOXWDDM_CONTEXT_TYPE_CUSTOM_UHGSMI_GL,
    253253    /* context created by the kernel->user communication mechanism for visible rects reporting, etc.  */
    254     VBOXWDDM_CONTEXT_TYPE_CUSTOM_SESSION
     254    VBOXWDDM_CONTEXT_TYPE_CUSTOM_SESSION,
     255    /* context created by VBoxTray to handle resize operations */
     256    VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE,
     257    /* context created by VBoxTray to handle seamless operations */
     258    VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_SEAMLESS
    255259} VBOXWDDM_CONTEXT_TYPE;
    256260
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h

    r46783 r48070  
    2121
    2222#include "VBoxDispD3DIf.h"
    23 #include "common/wddm/VBoxMPIf.h"
     23#include "../../common/wddm/VBoxMPIf.h"
    2424#ifdef VBOX_WITH_CRHGSMI
    2525#include "VBoxUhgsmiDisp.h"
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DCmn.h

    r46783 r48070  
    1919#define ___VBoxDispD3DCmn_h___
    2020
    21 #       define _InterlockedExchange           _InterlockedExchange_StupidDDKVsCompilerCrap
    22 #       define _InterlockedExchangeAdd        _InterlockedExchangeAdd_StupidDDKVsCompilerCrap
    23 #       define _InterlockedCompareExchange    _InterlockedCompareExchange_StupidDDKVsCompilerCrap
    24 #       define _InterlockedAddLargeStatistic  _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
    25 #       define _interlockedbittestandset      _interlockedbittestandset_StupidDDKVsCompilerCrap
    26 #       define _interlockedbittestandreset    _interlockedbittestandreset_StupidDDKVsCompilerCrap
    27 #       define _interlockedbittestandset64    _interlockedbittestandset64_StupidDDKVsCompilerCrap
    28 #       define _interlockedbittestandreset64  _interlockedbittestandreset64_StupidDDKVsCompilerCrap
    29 #       pragma warning(disable : 4163)
    30 #include <windows.h>
    31 #       pragma warning(default : 4163)
    32 #       undef  _InterlockedExchange
    33 #       undef  _InterlockedExchangeAdd
    34 #       undef  _InterlockedCompareExchange
    35 #       undef  _InterlockedAddLargeStatistic
    36 #       undef  _interlockedbittestandset
    37 #       undef  _interlockedbittestandreset
    38 #       undef  _interlockedbittestandset64
    39 #       undef  _interlockedbittestandreset64
    40 
    41 #include <d3d9types.h>
    42 //#include <d3dtypes.h>
    43 #include <D3dumddi.h>
    44 #include <d3dhal.h>
     21#include "VBoxDispD3DBase.h"
    4522
    4623#include <iprt/initterm.h>
     
    5431#include "VBoxDispDbg.h"
    5532#include "VBoxDispD3DIf.h"
    56 #include "common/wddm/VBoxMPIf.h"
     33#include "../../common/wddm/VBoxMPIf.h"
    5734#include "VBoxDispCm.h"
    5835#include "VBoxDispMpInternal.h"
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp

    r46593 r48070  
    1717 */
    1818
    19 #include "VBoxDispD3DCmn.h"
     19#include "VBoxDispD3DBase.h"
     20#include "VBoxDispKmt.h"
     21
     22#include <iprt/assert.h>
     23#include <iprt/log.h>
    2024
    2125#ifndef NT_SUCCESS
     
    103107        Log((__FUNCTION__": pfnD3DKMTUnlock = %p\n", pCallbacks->pfnD3DKMTUnlock));
    104108        bSupported &= !!(pCallbacks->pfnD3DKMTUnlock);
     109
     110        pCallbacks->pfnD3DKMTInvalidateActiveVidPn = (PFND3DKMT_INVALIDATEACTIVEVIDPN)GetProcAddress(pCallbacks->hGdi32, "D3DKMTInvalidateActiveVidPn");
     111        Log((__FUNCTION__": pfnD3DKMTInvalidateActiveVidPn = %p\n", pCallbacks->pfnD3DKMTInvalidateActiveVidPn));
     112        bSupported &= !!(pCallbacks->pfnD3DKMTInvalidateActiveVidPn);
     113
     114        pCallbacks->pfnD3DKMTPollDisplayChildren = (PFND3DKMT_POLLDISPLAYCHILDREN)GetProcAddress(pCallbacks->hGdi32, "D3DKMTPollDisplayChildren");
     115        Log((__FUNCTION__": pfnD3DKMTPollDisplayChildren = %p\n", pCallbacks->pfnD3DKMTPollDisplayChildren));
     116        bSupported &= !!(pCallbacks->pfnD3DKMTPollDisplayChildren);
    105117
    106118        pCallbacks->pfnD3DKMTEnumAdapters = (PFND3DKMT_ENUMADAPTERS)GetProcAddress(pCallbacks->hGdi32, "D3DKMTEnumAdapters");
     
    204216}
    205217
    206 static HRESULT vboxDispKmtOpenAdapterViaHdc(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
     218static HRESULT vboxDispKmtOpenAdapterViaHdc(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
    207219{
    208220    D3DKMT_OPENADAPTERFROMHDC OpenAdapterData = {0};
     
    232244}
    233245
    234 static HRESULT vboxDispKmtOpenAdapterViaLuid(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
     246static HRESULT vboxDispKmtOpenAdapterViaLuid(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
    235247{
    236248    if (pCallbacks->enmVersion < VBOXDISPKMT_CALLBACKS_VERSION_WIN8)
     
    281293}
    282294
    283 HRESULT vboxDispKmtOpenAdapter(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
     295HRESULT vboxDispKmtOpenAdapter(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
    284296{
    285297    HRESULT hr = vboxDispKmtOpenAdapterViaHdc(pCallbacks, pAdapter);
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.h

    r44529 r48070  
    2121
    2222#include <D3dkmthk.h>
     23
     24#include "../../common/wddm/VBoxMPIf.h"
    2325
    2426/* win8 release preview-specific stuff */
     
    8284    PFND3DKMT_UNLOCK pfnD3DKMTUnlock;
    8385
     86    /* auto resize support */
     87    PFND3DKMT_INVALIDATEACTIVEVIDPN pfnD3DKMTInvalidateActiveVidPn;
     88    PFND3DKMT_POLLDISPLAYCHILDREN pfnD3DKMTPollDisplayChildren;
     89
     90    /* win8 specifics */
    8491    PFND3DKMT_ENUMADAPTERS pfnD3DKMTEnumAdapters;
    8592    PFND3DKMT_OPENADAPTERFROMLUID pfnD3DKMTOpenAdapterFromLuid;
     
    9198    HDC hDc;
    9299    LUID Luid;
    93     PVBOXDISPKMT_CALLBACKS pCallbacks;
     100    const VBOXDISPKMT_CALLBACKS *pCallbacks;
    94101}VBOXDISPKMT_ADAPTER, *PVBOXDISPKMT_ADAPTER;
    95102
     
    121128HRESULT vboxDispKmtCallbacksTerm(PVBOXDISPKMT_CALLBACKS pCallbacks);
    122129
    123 HRESULT vboxDispKmtOpenAdapter(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter);
     130HRESULT vboxDispKmtOpenAdapter(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter);
    124131HRESULT vboxDispKmtCloseAdapter(PVBOXDISPKMT_ADAPTER pAdapter);
    125132HRESULT vboxDispKmtCreateDevice(PVBOXDISPKMT_ADAPTER pAdapter, PVBOXDISPKMT_DEVICE pDevice);
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPCommon.h

    r44529 r48070  
    4242
    4343#ifdef VBOX_WDDM_MINIPORT
    44 void VBoxWddmInvalidateAllVideoModesInfos(PVBOXMP_DEVEXT pExt);
    45 void VBoxWddmInvalidateVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId);
    4644PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateVideoModesInfoByMask(PVBOXMP_DEVEXT pExt, uint8_t *pScreenIdMask);
    47 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateAllVideoModesInfos(PVBOXMP_DEVEXT pExt);
     45void VBoxWddmInitVideoModes(PVBOXMP_DEVEXT pExt);
    4846NTSTATUS VBoxWddmGetModesForResolution(VIDEO_MODE_INFORMATION *pAllModes, uint32_t cAllModes, int iSearchPreferredMode,
    4947                                       const D3DKMDT_2DREGION *pResolution, VIDEO_MODE_INFORMATION * pModes,
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h

    r47070 r48070  
    100100
    101101   VBOXVIDEOCM_MGR CmMgr;
     102   VBOXVIDEOCM_MGR SeamlessCtxMgr;
    102103   /* hgsmi allocation manager */
    103104   VBOXVIDEOCM_ALLOC_MGR AllocMgr;
     
    110111   volatile uint32_t cContexts3D;
    111112   volatile uint32_t cContexts2D;
     113   volatile uint32_t cContextsDispIfResize;
    112114   volatile uint32_t cRenderFromShadowDisabledContexts;
    113115   volatile uint32_t cUnlockedVBVADisabled;
     116
     117   DWORD dwDrvCfgFlags;
    114118   /* this is examined and swicthed by DxgkDdiSubmitCommand only! */
    115119   volatile BOOLEAN fRenderToShadowDisabled;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPVidModes.cpp

    r46876 r48070  
    900900#ifdef VBOX_WDDM_MINIPORT
    901901static VBOXWDDM_VIDEOMODES_INFO g_aVBoxVideoModeInfos[VBOX_VIDEO_MAX_SCREENS] = {0};
     902static VBOXWDDM_VIDEOMODES_INFO g_VBoxVideoModeTmp;
    902903
    903904bool VBoxWddmFillMode(PVBOXMP_DEVEXT pExt, uint32_t iDisplay, VIDEO_MODE_INFORMATION *pInfo, D3DDDIFORMAT enmFormat, ULONG w, ULONG h)
     
    954955
    955956    *piPreferredResolution = -1;
     957    *pcResolutions = 0;
    956958
    957959    for (uint32_t i=0; i<tableSize; ++i)
     
    10031005    Assert(pModes->aResolutions[pModes->iPreferredResolution].cx == pModes->aModes[pModes->iPreferredMode].VisScreenWidth
    10041006            && pModes->aResolutions[pModes->iPreferredResolution].cy == pModes->aModes[pModes->iPreferredMode].VisScreenHeight);
     1007    Assert(pModes->cModes >= pModes->cResolutions);
    10051008}
    10061009
     
    12251228}
    12261229
    1227 void VBoxWddmInvalidateVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
    1228 {
    1229     if (VidPnTargetId != D3DDDI_ID_ALL)
    1230     {
    1231         if (VidPnTargetId >= RT_ELEMENTS(g_aVBoxVideoModeInfos))
    1232         {
    1233             WARN(("VidPnTargetId (%d) must be less than (%d)", VidPnTargetId, RT_ELEMENTS(g_aVBoxVideoModeInfos)));
    1234             return;
    1235         }
    1236         LOG(("invalidating videomede info for screen %d", VidPnTargetId));
    1237         g_aVBoxVideoModeInfos[VidPnTargetId].cModes = 0;
     1230static void VBoxWddmInitVideoMode(PVBOXMP_DEVEXT pExt, int i)
     1231{
     1232    VBoxWddmBuildVideoModesInfo(pExt, (D3DDDI_VIDEO_PRESENT_TARGET_ID)i, &g_aVBoxVideoModeInfos[i], NULL, 0);
     1233}
     1234
     1235void VBoxWddmInitVideoModes(PVBOXMP_DEVEXT pExt)
     1236{
     1237    for (int i = 0; i < VBoxCommonFromDeviceExt(pExt)->cDisplays; ++i)
     1238    {
     1239        VBoxWddmInitVideoMode(pExt, i);
     1240    }
     1241}
     1242
     1243static NTSTATUS vboxWddmChildStatusReportPerform(PVBOXMP_DEVEXT pDevExt, PVBOXVDMA_CHILD_STATUS pChildStatus, D3DDDI_VIDEO_PRESENT_TARGET_ID iChild)
     1244{
     1245    DXGK_CHILD_STATUS DdiChildStatus;
     1246
     1247    Assert(iChild < UINT32_MAX/2);
     1248    Assert(iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
     1249
     1250    PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[iChild];
     1251
     1252    if ((pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_DISCONNECTED)
     1253            && pTarget->fConnected)
     1254    {
     1255        /* report disconnected */
     1256        memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));
     1257        DdiChildStatus.Type = StatusConnection;
     1258        DdiChildStatus.ChildUid = iChild;
     1259        DdiChildStatus.HotPlug.Connected = FALSE;
     1260
     1261        LOG(("Reporting DISCONNECT to child %d", DdiChildStatus.ChildUid));
     1262
     1263        NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);
     1264        if (!NT_SUCCESS(Status))
     1265        {
     1266            WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));
     1267            return Status;
     1268        }
     1269        pTarget->fConnected = FALSE;
     1270    }
     1271
     1272    if ((pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_CONNECTED)
     1273            && !pTarget->fConnected)
     1274    {
     1275        /* report disconnected */
     1276        memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));
     1277        DdiChildStatus.Type = StatusConnection;
     1278        DdiChildStatus.ChildUid = iChild;
     1279        DdiChildStatus.HotPlug.Connected = TRUE;
     1280
     1281        LOG(("Reporting CONNECT to child %d", DdiChildStatus.ChildUid));
     1282
     1283        NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);
     1284        if (!NT_SUCCESS(Status))
     1285        {
     1286            WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));
     1287            return Status;
     1288        }
     1289        pTarget->fConnected = TRUE;
     1290    }
     1291
     1292    if (pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_ROTATED)
     1293    {
     1294        /* report disconnected */
     1295        memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));
     1296        DdiChildStatus.Type = StatusRotation;
     1297        DdiChildStatus.ChildUid = iChild;
     1298        DdiChildStatus.Rotation.Angle = pChildStatus->u8RotationAngle;
     1299
     1300        LOG(("Reporting ROTATED to child %d", DdiChildStatus.ChildUid));
     1301
     1302        NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);
     1303        if (!NT_SUCCESS(Status))
     1304        {
     1305            WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));
     1306            return Status;
     1307        }
     1308    }
     1309
     1310    return STATUS_SUCCESS;
     1311}
     1312
     1313static NTSTATUS vboxWddmChildStatusHandleRequest(PVBOXMP_DEVEXT pDevExt, VBOXVDMACMD_CHILD_STATUS_IRQ *pBody)
     1314{
     1315    NTSTATUS Status = STATUS_SUCCESS;
     1316
     1317    for (UINT i = 0; i < pBody->cInfos; ++i)
     1318    {
     1319        PVBOXVDMA_CHILD_STATUS pInfo = &pBody->aInfos[i];
     1320        if (pBody->fFlags & VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL)
     1321        {
     1322            for (D3DDDI_VIDEO_PRESENT_TARGET_ID iChild = 0; iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++iChild)
     1323            {
     1324                Status = vboxWddmChildStatusReportPerform(pDevExt, pInfo, iChild);
     1325                if (!NT_SUCCESS(Status))
     1326                {
     1327                    WARN(("vboxWddmChildStatusReportPerform failed with Status (0x%x)", Status));
     1328                    break;
     1329                }
     1330            }
     1331        }
     1332        else
     1333        {
     1334            Status = vboxWddmChildStatusReportPerform(pDevExt, pInfo, pInfo->iChild);
     1335            if (!NT_SUCCESS(Status))
     1336            {
     1337                WARN(("vboxWddmChildStatusReportPerform failed with Status (0x%x)", Status));
     1338                break;
     1339            }
     1340        }
     1341    }
     1342
     1343    return Status;
     1344}
     1345
     1346#ifdef VBOX_WDDM_MONITOR_REPLUG_IRQ
     1347typedef struct VBOXWDDMCHILDSTATUSCB
     1348{
     1349    PVBOXVDMACBUF_DR pDr;
     1350    PKEVENT pEvent;
     1351} VBOXWDDMCHILDSTATUSCB, *PVBOXWDDMCHILDSTATUSCB;
     1352
     1353static DECLCALLBACK(VOID) vboxWddmChildStatusReportCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
     1354{
     1355    /* we should be called from our DPC routine */
     1356    Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
     1357
     1358    PVBOXWDDMCHILDSTATUSCB pCtx = (PVBOXWDDMCHILDSTATUSCB)pvContext;
     1359    PVBOXVDMACBUF_DR pDr = pCtx->pDr;
     1360    PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
     1361    VBOXVDMACMD_CHILD_STATUS_IRQ *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHILD_STATUS_IRQ);
     1362
     1363    vboxWddmChildStatusHandleRequest(pDevExt, pBody);
     1364
     1365    vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
     1366
     1367    if (pCtx->pEvent)
     1368    {
     1369        KeSetEvent(pCtx->pEvent, 0, FALSE);
     1370    }
     1371}
     1372#endif
     1373
     1374static NTSTATUS vboxWddmChildStatusReportReconnected(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID idTarget)
     1375{
     1376#ifdef VBOX_WDDM_MONITOR_REPLUG_IRQ
     1377    NTSTATUS Status = STATUS_UNSUCCESSFUL;
     1378    UINT cbCmd = VBOXVDMACMD_SIZE_FROMBODYSIZE(sizeof (VBOXVDMACMD_CHILD_STATUS_IRQ));
     1379
     1380    PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbCmd);
     1381    if (pDr)
     1382    {
     1383        // vboxVdmaCBufDrCreate zero initializes the pDr
     1384        /* the command data follows the descriptor */
     1385        pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;
     1386        pDr->cbBuf = cbCmd;
     1387        pDr->rc = VERR_NOT_IMPLEMENTED;
     1388
     1389        PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
     1390        pHdr->enmType = VBOXVDMACMD_TYPE_CHILD_STATUS_IRQ;
     1391        pHdr->u32CmdSpecific = 0;
     1392        PVBOXVDMACMD_CHILD_STATUS_IRQ pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHILD_STATUS_IRQ);
     1393        pBody->cInfos = 1;
     1394        if (idTarget == D3DDDI_ID_ALL)
     1395        {
     1396            pBody->fFlags |= VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL;
     1397        }
     1398        pBody->aInfos[0].iChild = idTarget;
     1399        pBody->aInfos[0].fFlags = VBOXVDMA_CHILD_STATUS_F_DISCONNECTED | VBOXVDMA_CHILD_STATUS_F_CONNECTED;
     1400        /* we're going to KeWaitForSingleObject */
     1401        Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
     1402
     1403        PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);
     1404        VBOXWDDMCHILDSTATUSCB Ctx;
     1405        KEVENT Event;
     1406        KeInitializeEvent(&Event, NotificationEvent, FALSE);
     1407        Ctx.pDr = pDr;
     1408        Ctx.pEvent = &Event;
     1409        vboxVdmaDdiCmdInit(pDdiCmd, 0, 0, vboxWddmChildStatusReportCompletion, &Ctx);
     1410        /* mark command as submitted & invisible for the dx runtime since dx did not originate it */
     1411        vboxVdmaDdiCmdSubmittedNotDx(pDdiCmd);
     1412        int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
     1413        Assert(rc == VINF_SUCCESS);
     1414        if (RT_SUCCESS(rc))
     1415        {
     1416            Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
     1417            Assert(Status == STATUS_SUCCESS);
     1418            return STATUS_SUCCESS;
     1419        }
     1420
     1421        Status = STATUS_UNSUCCESSFUL;
     1422
     1423        vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
     1424    }
     1425    else
     1426    {
     1427        /* @todo: try flushing.. */
     1428        WARN(("vboxVdmaCBufDrCreate returned NULL"));
     1429        Status = STATUS_INSUFFICIENT_RESOURCES;
     1430    }
     1431
     1432    return Status;
     1433#else
     1434    VBOXVDMACMD_CHILD_STATUS_IRQ Body = {0};
     1435    Body.cInfos = 1;
     1436    if (idTarget == D3DDDI_ID_ALL)
     1437    {
     1438        Body.fFlags |= VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL;
     1439    }
     1440    Body.aInfos[0].iChild = idTarget;
     1441    Body.aInfos[0].fFlags = VBOXVDMA_CHILD_STATUS_F_DISCONNECTED | VBOXVDMA_CHILD_STATUS_F_CONNECTED;
     1442    Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
     1443    return vboxWddmChildStatusHandleRequest(pDevExt, &Body);
     1444#endif
     1445}
     1446
     1447NTSTATUS vboxWddmChildStatusConnect(PVBOXMP_DEVEXT pDevExt, uint32_t iChild, BOOLEAN fConnect)
     1448{
     1449#ifdef VBOX_WDDM_MONITOR_REPLUG_IRQ
     1450# error "port me!"
     1451#else
     1452    Assert(iChild < (uint32_t)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
     1453    NTSTATUS Status = STATUS_SUCCESS;
     1454    VBOXVDMACMD_CHILD_STATUS_IRQ Body = {0};
     1455    Body.cInfos = 1;
     1456    Body.aInfos[0].iChild = iChild;
     1457    Body.aInfos[0].fFlags = fConnect ? VBOXVDMA_CHILD_STATUS_F_CONNECTED : VBOXVDMA_CHILD_STATUS_F_DISCONNECTED;
     1458    Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
     1459    Status = vboxWddmChildStatusHandleRequest(pDevExt, &Body);
     1460    if (!NT_SUCCESS(Status))
     1461        WARN(("vboxWddmChildStatusHandleRequest failed Status 0x%x", Status));
     1462
     1463    return Status;
     1464#endif
     1465}
     1466
     1467void VBoxWddmUpdateVideoMode(PVBOXMP_DEVEXT pExt, int i)
     1468{
     1469    g_VBoxVideoModeTmp = g_aVBoxVideoModeInfos[i];
     1470
     1471    Assert(g_aVBoxVideoModeInfos[i].cModes);
     1472
     1473    VBoxWddmInitVideoMode(pExt, i);
     1474
     1475    if (!memcmp(&g_VBoxVideoModeTmp, &g_aVBoxVideoModeInfos[i], sizeof (g_VBoxVideoModeTmp)))
    12381476        return;
    1239     }
    1240 
    1241     LOG(("invalidating ALL videomede infos"));
    1242 
    1243     for (UINT i = 0; i < RT_ELEMENTS(g_aVBoxVideoModeInfos); ++i)
    1244     {
    1245         g_aVBoxVideoModeInfos[i].cModes = 0;
    1246     }
    1247 }
    1248 
    1249 void VBoxWddmInvalidateAllVideoModesInfos(PVBOXMP_DEVEXT pExt)
    1250 {
    1251     VBoxWddmInvalidateVideoModesInfo(pExt, D3DDDI_ID_ALL);
     1477
     1478#ifdef DEBUG_misha
     1479    g_VBoxDbgBreakModes = 0;
     1480#endif
     1481
     1482#ifdef DEBUG_misha
     1483    LOGREL(("modes changed for target %d", i));
     1484#else
     1485    LOG(("modes changed for target %d", i));
     1486#endif
     1487    vboxWddmChildStatusReportReconnected(pExt, (D3DDDI_VIDEO_PRESENT_TARGET_ID)i);
    12521488}
    12531489
     
    12561492    for (int i = 0; i < VBoxCommonFromDeviceExt(pExt)->cDisplays; ++i)
    12571493    {
    1258         if (ASMBitTest(pScreenIdMask, i))
    1259             VBoxWddmInvalidateVideoModesInfo(pExt, i);
    1260     }
    1261 
    1262     /* ensure we have all the rest populated */
    1263     VBoxWddmGetAllVideoModesInfos(pExt);
    1264     return g_aVBoxVideoModeInfos;
    1265 }
    1266 
    1267 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateAllVideoModesInfos(PVBOXMP_DEVEXT pExt)
    1268 {
    1269     VBoxWddmInvalidateAllVideoModesInfos(pExt);
    1270 
    1271     /* ensure we have all the rest populated */
    1272     VBoxWddmGetAllVideoModesInfos(pExt);
     1494        if (!pScreenIdMask || ASMBitTest(pScreenIdMask, i))
     1495        {
     1496            VBoxWddmUpdateVideoMode(pExt, i);
     1497        }
     1498    }
     1499
    12731500    return g_aVBoxVideoModeInfos;
    12741501}
     
    13641591}
    13651592
    1366 static PVBOXWDDM_VIDEOMODES_INFO vboxWddmGetVideoModesInfoInternal(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
    1367 {
    1368     Assert(VidPnTargetId < (D3DDDI_VIDEO_PRESENT_TARGET_ID)VBoxCommonFromDeviceExt(pExt)->cDisplays);
    1369     if (VidPnTargetId >= (D3DDDI_VIDEO_PRESENT_TARGET_ID)VBoxCommonFromDeviceExt(pExt)->cDisplays)
    1370     {
    1371         WARN(("video mode info for invalid screen (%d) requested", VidPnTargetId));
    1372         return NULL;
    1373     }
    1374 
    1375     PVBOXWDDM_VIDEOMODES_INFO pInfo = &g_aVBoxVideoModeInfos[VidPnTargetId];
    1376 
    1377     if (!pInfo->cModes)
    1378     {
    1379         VBoxWddmBuildVideoModesInfo(pExt, VidPnTargetId, pInfo, NULL, 0);
    1380         Assert(pInfo->cModes);
    1381     }
    1382 
    1383     return pInfo;
    1384 }
    1385 
    1386 static VOID vboxWddmAddVideoModes(PVBOXMP_DEVEXT pExt, PVBOXWDDM_VIDEOMODES_INFO pDstInfo, PVBOXWDDM_VIDEOMODES_INFO pSrcInfo)
    1387 {
    1388     for (int i = 0; i < (int)pSrcInfo->cModes; ++i)
    1389     {
    1390         int foundIdx = VBoxMPFindVideoMode(pDstInfo->aModes, pDstInfo->cModes, &pSrcInfo->aModes[i]);
    1391         if (foundIdx >= 0)
    1392             continue;
    1393 
    1394         Assert(0);
    1395         pDstInfo->aModes[pDstInfo->cModes] = pSrcInfo->aModes[i];
    1396         ++pDstInfo->cModes;
    1397     }
    1398 
    1399     VBoxWddmBuildResolutionTableForModes(pDstInfo);
    1400 }
    1401 
    14021593PVBOXWDDM_VIDEOMODES_INFO VBoxWddmGetAllVideoModesInfos(PVBOXMP_DEVEXT pExt)
    14031594{
    1404     /* ensure all modes are initialized */
    1405     for (int i = 0; i < VBoxCommonFromDeviceExt(pExt)->cDisplays; ++i)
    1406     {
    1407         vboxWddmGetVideoModesInfoInternal(pExt, (D3DDDI_VIDEO_PRESENT_TARGET_ID)i);
    1408     }
    1409 
    14101595    return g_aVBoxVideoModeInfos;
    14111596}
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCm.cpp

    r38112 r48070  
    7272    PKEVENT pUmEvent;
    7373    /* sync lock */
    74     FAST_MUTEX Mutex;
     74    KSPIN_LOCK SynchLock;
    7575    /* indicates whether event signaling is needed on cmd add */
    7676    bool bEventNeeded;
     
    181181    }
    182182
    183     Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
    184     ExAcquireFastMutex(&pSession->Mutex);
     183    Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
     184
     185    KIRQL OldIrql;
     186    KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
    185187
    186188    InsertHeadList(&pSession->CommandsList, &pHdr->QueueList);
     
    191193    }
    192194
    193     ExReleaseFastMutex(&pSession->Mutex);
     195    KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
    194196
    195197    if (bSignalEvent)
     
    225227    PVBOXVIDEOCM_CMD_DR pHdr;
    226228
    227     ExAcquireFastMutex(&pSession->Mutex);
     229    KIRQL OldIrql;
     230    KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
    228231
    229232    pCurEntry = pSession->CommandsList.Blink;
     
    260263
    261264
    262     ExReleaseFastMutex(&pSession->Mutex);
     265    KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
    263266
    264267    return STATUS_SUCCESS;
     
    280283void vboxVideoCmSessionCtxAdd(PVBOXVIDEOCM_SESSION pSession, PVBOXVIDEOCM_CTX pContext)
    281284{
    282     Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
    283     ExAcquireFastMutex(&pSession->Mutex);
     285    Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
     286    KIRQL OldIrql;
     287    KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
     288
    284289    vboxVideoCmSessionCtxAddLocked(pSession, pContext);
    285     ExReleaseFastMutex(&pSession->Mutex);
    286 
     290
     291    KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
     292}
     293
     294void vboxVideoCmSessionSignalEvent(PVBOXVIDEOCM_SESSION pSession)
     295{
     296    Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
     297    if (pSession->pUmEvent)
     298        KeSetEvent(pSession->pUmEvent, 0, FALSE);
    287299}
    288300
     
    346358    InitializeListHead(&RemainedList);
    347359    InitializeListHead(&RemainedPpList);
    348     Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
    349     ExAcquireFastMutex(&pSession->Mutex);
     360    Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
     361    KIRQL OldIrql;
     362    KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
     363
    350364    pContext->pSession = NULL;
    351365    RemoveEntryList(&pContext->SessionEntry);
     
    362376        vboxVideoCmSessionCtxDetachCmdsLocked(&pSession->PpCommandsList, pContext, &RemainedPpList);
    363377    }
    364     ExReleaseFastMutex(&pSession->Mutex);
     378
     379    KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
    365380
    366381    for (pCur = RemainedList.Flink; pCur != &RemainedList; pCur = RemainedList.Flink)
     
    393408        InitializeListHead(&pSession->PpCommandsList);
    394409        pSession->pUmEvent = pUmEvent;
    395         Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
    396         ExInitializeFastMutex(&pSession->Mutex);
     410        Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
     411        KeInitializeSpinLock(&pSession->SynchLock);
    397412        pSession->bEventNeeded = true;
    398413        vboxVideoCmSessionCtxAddLocked(pSession, pContext);
     
    421436    if (Status == STATUS_SUCCESS)
    422437    {
    423         Status = KeWaitForSingleObject(&pMgr->SynchEvent, Executive, KernelMode,
    424                 FALSE, /* BOOLEAN Alertable */
    425                 NULL /* PLARGE_INTEGER Timeout */
    426             );
    427         Assert(Status == STATUS_SUCCESS);
     438        KIRQL OldIrql;
     439        KeAcquireSpinLock(&pMgr->SynchLock, &OldIrql);
     440
     441        bool bFound = false;
     442        PVBOXVIDEOCM_SESSION pSession = NULL;
     443        for (PLIST_ENTRY pEntry = pMgr->SessionList.Flink; pEntry != &pMgr->SessionList; pEntry = pEntry->Flink)
     444        {
     445            pSession = VBOXCMENTRY_2_SESSION(pEntry);
     446            if (pSession->pUmEvent == pUmEvent)
     447            {
     448                bFound = true;
     449                break;
     450            }
     451        }
     452
     453        pContext->u64UmData = u64UmData;
     454
     455        if (!bFound)
     456        {
     457            Status = vboxVideoCmSessionCreateLocked(pMgr, &pSession, pUmEvent, pContext);
     458            Assert(Status == STATUS_SUCCESS);
     459        }
     460        else
     461        {
     462            /* Status = */vboxVideoCmSessionCtxAdd(pSession, pContext);
     463            /*Assert(Status == STATUS_SUCCESS);*/
     464        }
     465
     466        KeReleaseSpinLock(&pMgr->SynchLock, OldIrql);
     467
    428468        if (Status == STATUS_SUCCESS)
    429469        {
    430             bool bFound = false;
    431             PVBOXVIDEOCM_SESSION pSession = NULL;
    432             for (PLIST_ENTRY pEntry = pMgr->SessionList.Flink; pEntry != &pMgr->SessionList; pEntry = pEntry->Flink)
    433             {
    434                 pSession = VBOXCMENTRY_2_SESSION(pEntry);
    435                 if (pSession->pUmEvent == pUmEvent)
    436                 {
    437                     bFound = true;
    438                     break;
    439                 }
    440             }
    441 
    442             pContext->u64UmData = u64UmData;
    443 
    444             if (!bFound)
    445             {
    446                 Status = vboxVideoCmSessionCreateLocked(pMgr, &pSession, pUmEvent, pContext);
    447                 Assert(Status == STATUS_SUCCESS);
    448             }
    449             else
    450             {
    451                 /* Status = */vboxVideoCmSessionCtxAdd(pSession, pContext);
    452                 /*Assert(Status == STATUS_SUCCESS);*/
    453             }
    454             LONG tstL = KeSetEvent(&pMgr->SynchEvent, 0, FALSE);
    455             Assert(!tstL);
    456 
    457             if (Status == STATUS_SUCCESS)
    458             {
    459                 return STATUS_SUCCESS;
    460             }
     470            return STATUS_SUCCESS;
    461471        }
    462472
     
    472482        return STATUS_SUCCESS;
    473483
    474     NTSTATUS Status = KeWaitForSingleObject(&pMgr->SynchEvent, Executive, KernelMode,
    475                 FALSE, /* BOOLEAN Alertable */
    476                 NULL /* PLARGE_INTEGER Timeout */
    477     );
    478     Assert(Status == STATUS_SUCCESS);
    479     if (Status == STATUS_SUCCESS)
    480     {
    481         vboxVideoCmSessionCtxRemoveLocked(pSession, pContext);
    482         LONG tstL = KeSetEvent(&pMgr->SynchEvent, 0, FALSE);
    483         Assert(!tstL);
    484     }
    485 
    486     return Status;
     484    KIRQL OldIrql;
     485    KeAcquireSpinLock(&pMgr->SynchLock, &OldIrql);
     486
     487    vboxVideoCmSessionCtxRemoveLocked(pSession, pContext);
     488
     489    KeReleaseSpinLock(&pMgr->SynchLock, OldIrql);
     490
     491    return STATUS_SUCCESS;
    487492}
    488493
    489494NTSTATUS vboxVideoCmInit(PVBOXVIDEOCM_MGR pMgr)
    490495{
    491     KeInitializeEvent(&pMgr->SynchEvent, SynchronizationEvent, TRUE);
     496    KeInitializeSpinLock(&pMgr->SynchLock);
    492497    InitializeListHead(&pMgr->SessionList);
    493498    return STATUS_SUCCESS;
     
    500505}
    501506
     507NTSTATUS vboxVideoCmSignalEvents(PVBOXVIDEOCM_MGR pMgr)
     508{
     509    Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
     510    PVBOXVIDEOCM_SESSION pSession = NULL;
     511
     512    KIRQL OldIrql;
     513    KeAcquireSpinLock(&pMgr->SynchLock, &OldIrql);
     514
     515    for (PLIST_ENTRY pEntry = pMgr->SessionList.Flink; pEntry != &pMgr->SessionList; pEntry = pEntry->Flink)
     516    {
     517        pSession = VBOXCMENTRY_2_SESSION(pEntry);
     518        vboxVideoCmSessionSignalEvent(pSession);
     519    }
     520
     521    KeReleaseSpinLock(&pMgr->SynchLock, OldIrql);
     522
     523    return STATUS_SUCCESS;
     524}
     525
    502526VOID vboxVideoCmProcessKm(PVBOXVIDEOCM_CTX pContext, PVBOXVIDEOCM_CMD_CTL_KM pCmd)
    503527{
     
    515539        {
    516540            PVBOXVIDEOCM_CMD_DR pHdr = VBOXVIDEOCM_HEAD(pCmd);
    517             ExAcquireFastMutex(&pSession->Mutex);
     541            KIRQL OldIrql;
     542            KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
    518543            InsertTailList(&pSession->PpCommandsList, &pHdr->QueueList);
    519             ExReleaseFastMutex(&pSession->Mutex);
     544            KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
    520545            break;
    521546        }
     
    550575//    PVBOXWDDM_GETVBOXVIDEOCMCMD_HDR *pvCmd
    551576
    552     Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
    553     ExAcquireFastMutex(&pSession->Mutex);
     577    Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
     578    KIRQL OldIrql;
     579    KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
    554580
    555581    vboxVideoCmSessionCtxDetachCmdsLocked(&pSession->PpCommandsList, pContext, &DetachedPpList);
     
    606632    } while (1);
    607633
    608     ExReleaseFastMutex(&pSession->Mutex);
     634    KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
    609635
    610636    vboxVideoCmSessionCtxPpList(pContext, &DetachedPpList);
     
    647673}
    648674
    649 VOID vboxVideoCmLock(PVBOXVIDEOCM_CTX pContext)
    650 {
    651     ExAcquireFastMutex(&pContext->pSession->Mutex);
    652 }
    653 
    654 VOID vboxVideoCmUnlock(PVBOXVIDEOCM_CTX pContext)
    655 {
    656     ExReleaseFastMutex(&pContext->pSession->Mutex);
    657 }
    658 
    659675static BOOLEAN vboxVideoCmHasUncompletedCmdsLocked(PVBOXVIDEOCM_MGR pMgr)
    660676{
     
    663679    {
    664680        pSession = VBOXCMENTRY_2_SESSION(pEntry);
    665         ExAcquireFastMutex(&pSession->Mutex);
     681        KIRQL OldIrql;
     682        KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
     683
    666684        if (pSession->bEventNeeded)
    667685        {
    668686            /* commands still being processed */
    669             ExReleaseFastMutex(&pSession->Mutex);
     687            KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
    670688            return TRUE;
    671689        }
    672         ExReleaseFastMutex(&pSession->Mutex);
     690        KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
    673691    }
    674692    return FALSE;
    675693}
    676 
    677 /* waits for all outstanding commands to completed by client
    678  * assumptions here are:
    679  * 1. no new commands are submitted while we are waiting
    680  * 2. it is assumed that a client completes all previously received commands
    681  *    once it queries for the new set of commands */
    682 NTSTATUS vboxVideoCmWaitCompletedCmds(PVBOXVIDEOCM_MGR pMgr, uint32_t msTimeout)
    683 {
    684     LARGE_INTEGER Timeout;
    685     PLARGE_INTEGER pTimeout;
    686     uint32_t cIters;
    687 
    688     if (msTimeout != RT_INDEFINITE_WAIT)
    689     {
    690         uint32_t msIter = 2;
    691         cIters = msTimeout/msIter;
    692         if (!cIters)
    693         {
    694             msIter = msTimeout;
    695             cIters = 1;
    696         }
    697         Timeout.QuadPart = -(int64_t) msIter /* ms */ * 10000;
    698         pTimeout = &Timeout;
    699     }
    700     else
    701     {
    702         pTimeout = NULL;
    703         cIters = 1;
    704     }
    705 
    706     Assert(cIters);
    707     do
    708     {
    709         NTSTATUS Status = KeWaitForSingleObject(&pMgr->SynchEvent, Executive, KernelMode,
    710                     FALSE, /* BOOLEAN Alertable */
    711                     pTimeout /* PLARGE_INTEGER Timeout */
    712         );
    713         if (Status == STATUS_TIMEOUT)
    714         {
    715             --cIters;
    716         }
    717         else
    718         {
    719             if (!NT_SUCCESS(Status))
    720             {
    721                 WARN(("KeWaitForSingleObject failed with Status (0x%x)", Status));
    722                 return Status;
    723             }
    724 
    725             /* succeeded */
    726             if (!vboxVideoCmHasUncompletedCmdsLocked(pMgr))
    727             {
    728                 LONG tstL = KeSetEvent(&pMgr->SynchEvent, 0, FALSE);
    729                 Assert(!tstL);
    730                 return STATUS_SUCCESS;
    731             }
    732 
    733             LONG tstL = KeSetEvent(&pMgr->SynchEvent, 0, FALSE);
    734             Assert(!tstL);
    735         }
    736 
    737         if (!cIters)
    738             break;
    739 
    740         KeDelayExecutionThread(KernelMode, FALSE, pTimeout);
    741         --cIters;
    742         if (!cIters)
    743             break;
    744     } while (0);
    745 
    746     return STATUS_TIMEOUT;
    747 }
    748 
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCm.h

    r38112 r48070  
    2222typedef struct VBOXVIDEOCM_MGR
    2323{
    24     KEVENT SynchEvent;
     24    KSPIN_LOCK SynchLock;
    2525    /* session list */
    2626    LIST_ENTRY SessionList;
     
    4141NTSTATUS vboxVideoCmInit(PVBOXVIDEOCM_MGR pMgr);
    4242NTSTATUS vboxVideoCmTerm(PVBOXVIDEOCM_MGR pMgr);
     43NTSTATUS vboxVideoCmSignalEvents(PVBOXVIDEOCM_MGR pMgr);
    4344
    4445NTSTATUS vboxVideoCmCmdSubmitCompleteEvent(PVBOXVIDEOCM_CTX pContext, PKEVENT pEvent);
     
    5859NTSTATUS vboxVideoCmEscape(PVBOXVIDEOCM_CTX pContext, PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pCmd, uint32_t cbCmd);
    5960
    60 NTSTATUS vboxVideoCmWaitCompletedCmds(PVBOXVIDEOCM_MGR pMgr, uint32_t msTimeout);
    61 
    62 VOID vboxVideoCmLock(PVBOXVIDEOCM_CTX pContext);
    63 VOID vboxVideoCmUnlock(PVBOXVIDEOCM_CTX pContext);
    64 
    6561#endif /* #ifndef ___VBoxMPCm_h___ */
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp

    r47566 r48070  
    573573}
    574574
    575 #define VBOXWDDM_REG_DRVKEY_PREFIX L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\"
    576 
    577575NTSTATUS vboxWddmRegQueryDrvKeyName(PVBOXMP_DEVEXT pDevExt, ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
    578576{
     
    607605}
    608606
    609 #define VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_VISTA L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Control\\VIDEO\\"
    610 #define VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_WIN7 L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\UnitedVideo\\CONTROL\\VIDEO\\"
    611 
    612 #define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELX L"Attach.RelativeX"
    613 #define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELY L"Attach.RelativeY"
    614 #define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_DESKTOP L"Attach.ToDesktop"
    615 
    616607NTSTATUS vboxWddmRegQueryDisplaySettingsKeyName(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId,
    617608        ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
     
    660651    return Status;
    661652}
    662 
    663 #define VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\"
    664 #define VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY_SUBKEY L"\\Video"
    665653
    666654NTSTATUS vboxWddmRegQueryVideoGuidString(PVBOXMP_DEVEXT pDevExt, ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
     
    891879}
    892880
     881NTSTATUS vboxWddmRegDrvFlagsSet(PVBOXMP_DEVEXT pDevExt, DWORD fVal)
     882{
     883    HANDLE hKey = NULL;
     884    NTSTATUS Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_WRITE, &hKey);
     885    if (!NT_SUCCESS(Status))
     886    {
     887        WARN(("IoOpenDeviceRegistryKey failed, Status = 0x%x", Status));
     888        return Status;
     889    }
     890
     891    Status = vboxWddmRegSetValueDword(hKey, VBOXWDDM_REG_DRV_FLAGS_NAME, fVal);
     892    if (!NT_SUCCESS(Status))
     893        WARN(("vboxWddmRegSetValueDword failed, Status = 0x%x", Status));
     894
     895    NTSTATUS tmpStatus = ZwClose(hKey);
     896    Assert(tmpStatus == STATUS_SUCCESS);
     897
     898    return Status;
     899}
     900
     901DWORD vboxWddmRegDrvFlagsGet(PVBOXMP_DEVEXT pDevExt, DWORD fDefault)
     902{
     903    HANDLE hKey = NULL;
     904    NTSTATUS Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_READ, &hKey);
     905    if (!NT_SUCCESS(Status))
     906    {
     907        WARN(("IoOpenDeviceRegistryKey failed, Status = 0x%x", Status));
     908        return fDefault;
     909    }
     910
     911    DWORD dwVal = 0;
     912    Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_REG_DRV_FLAGS_NAME, &dwVal);
     913    if (!NT_SUCCESS(Status))
     914    {
     915        WARN(("vboxWddmRegQueryValueDword failed, Status = 0x%x", Status));
     916        dwVal = fDefault;
     917    }
     918
     919    NTSTATUS tmpStatus = ZwClose(hKey);
     920    Assert(tmpStatus == STATUS_SUCCESS);
     921
     922    return dwVal;
     923}
     924
    893925NTSTATUS vboxWddmRegQueryValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT PDWORD pDword)
    894926{
     
    920952}
    921953
    922 NTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT DWORD val)
     954NTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, IN DWORD val)
    923955{
    924956    UNICODE_STRING RtlStr;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.h

    r47566 r48070  
    9999NTSTATUS vboxWddmRegOpenKey(OUT PHANDLE phKey, IN PWCHAR pName, IN ACCESS_MASK fAccess);
    100100NTSTATUS vboxWddmRegQueryValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT PDWORD pDword);
    101 NTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT DWORD val);
     101NTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, IN DWORD val);
     102
     103NTSTATUS vboxWddmRegDrvFlagsSet(PVBOXMP_DEVEXT pDevExt, DWORD fVal);
     104DWORD vboxWddmRegDrvFlagsGet(PVBOXMP_DEVEXT pDevExt, DWORD fDefault);
    102105
    103106UNICODE_STRING* vboxWddmVGuidGet(PVBOXMP_DEVEXT pDevExt);
     
    184187#endif
    185188
     189NTSTATUS vboxWddmChildStatusConnect(PVBOXMP_DEVEXT pDevExt, uint32_t iChild, BOOLEAN fConnect);
     190
    186191#endif /* #ifndef ___VBoxMPMisc_h__ */
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h

    r47059 r48070  
    3535#include <cr_vreg.h>
    3636
     37#ifdef DEBUG_misha
     38extern DWORD g_VBoxDbgBreakModes;
     39#endif
    3740
    3841#if 0
     
    139142    uint32_t HeightVisible;
    140143    uint32_t HeightTotal;
     144    /* since there coul be multiple state changes on auto-resize,
     145     * we pend notifying host to avoi flickering */
     146    volatile bool fStateSyncPening;
     147    bool fConnected;
     148    bool fConfigured;
    141149} VBOXWDDM_TARGET, *PVBOXWDDM_TARGET;
    142150
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.cpp

    r44529 r48070  
    12631263    const DXGK_VIDPNTARGETMODESET_INTERFACE *pNewVidPnTargetModeSetInterface;
    12641264
    1265     if (VidPnSourceId != VidPnTargetId || pCbContext->apPathInfos[VidPnTargetId].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT)
    1266     {
    1267         return STATUS_SUCCESS;
    1268     }
     1265    Assert(VidPnSourceId == VidPnTargetId);
    12691266
    12701267    D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
     
    13061303        {
    13071304            Assert(hNewVidPnTargetModeSet);
    1308             if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnTargetId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
    1309             {
    1310                 Assert(VidPnSourceId == VidPnTargetId);
    1311 
     1305            Assert(VidPnSourceId == VidPnTargetId);
     1306//            if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnTargetId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
     1307            {
    13121308                for (uint32_t i = 0; i < pInfo->cResolutions; ++i)
    13131309                {
     
    13981394    const DXGK_VIDPNSOURCEMODESET_INTERFACE *pNewVidPnSourceModeSetInterface;
    13991395
    1400     if (VidPnSourceId != VidPnTargetId || pCbContext->apPathInfos[VidPnSourceId].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT)
    1401     {
    1402         return STATUS_SUCCESS;
    1403     }
     1396    Assert(VidPnSourceId == VidPnTargetId);
    14041397
    14051398    D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
     
    14411434        {
    14421435            Assert(hNewVidPnSourceModeSet);
    1443             if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnSourceId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
    1444             {
    1445                 Assert(VidPnSourceId == VidPnTargetId);
     1436            Assert(VidPnSourceId == VidPnTargetId);
     1437//            if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnSourceId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
     1438            {
    14461439                for (uint32_t i = 0; i < pInfo->cModes; ++i)
    14471440                {
     
    17551748            else
    17561749            {
    1757                 AssertFailed();
     1750                WARN(("cItems(%d) <= VidPnSourceId(%d)", pCbContext->cItems, VidPnSourceId));
    17581751                Status = STATUS_BUFFER_OVERFLOW;
    17591752                break;
     
    17661759            else
    17671760            {
    1768                 AssertFailed();
     1761                WARN(("cItems(%d) <= VidPnTargetId(%d)", pCbContext->cItems, VidPnTargetId));
    17691762                Status = STATUS_BUFFER_OVERFLOW;
    17701763                break;
     
    17751768
    17761769        /* VidPnSourceId == VidPnTargetId */
     1770        Assert(VidPnSourceId == VidPnTargetId);
    17771771        if (pCbContext->cItems > VidPnSourceId)
    17781772        {
     
    17851779        else
    17861780        {
    1787             AssertFailed();
     1781            WARN(("cItems(%d) <= VidPnSource/TargetId(%d)", pCbContext->cItems, VidPnSourceId));
    17881782            Status = STATUS_BUFFER_OVERFLOW;
    17891783            break;
     
    18011795/* we currently support only 0 -> 0, 1 -> 1, 2 -> 2 paths, AND 0 -> 0 must be present
    18021796 * this routine disables all paths unsupported */
    1803 NTSTATUS vboxVidPnCheckTopology(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
    1804                                     BOOLEAN fBreakOnDisabled, UINT cItems, PVBOXVIDPNPATHITEM paItems, BOOLEAN *pfDisabledFound)
    1805 {
     1797NTSTATUS vboxVidPnCheckTopology(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface, BOOLEAN *pfSupported)
     1798{
     1799    VBOXVIDPNPATHITEM aItems[VBOX_VIDEO_MAX_SCREENS];
     1800    const uint32_t cItems = RT_ELEMENTS(aItems);
    18061801    UINT i;
    18071802    for (i = 0; i < cItems; ++i)
    18081803    {
    1809         paItems[i].enmState = VBOXVIDPNPATHITEM_STATE_NOT_EXISTS;
     1804        aItems[i].enmState = VBOXVIDPNPATHITEM_STATE_NOT_EXISTS;
    18101805    }
    18111806    VBOXVIDPNGETPATHSINFO CbContext = {0};
    18121807    CbContext.Status = STATUS_SUCCESS;
    1813     CbContext.fBreakOnDisabled = fBreakOnDisabled;
     1808    CbContext.fBreakOnDisabled = FALSE;
    18141809    CbContext.fDisabledFound = FALSE;
    18151810    CbContext.cItems = cItems;
    1816     CbContext.paItems = paItems;
     1811    CbContext.paItems = aItems;
    18171812    NTSTATUS Status = vboxVidPnEnumPaths(hVidPnTopology, pVidPnTopologyInterface, vboxVidPnCheckTopologyEnum, &CbContext);
    18181813    if (!NT_SUCCESS(Status))
     
    18291824    }
    18301825
    1831     if (pfDisabledFound)
    1832         *pfDisabledFound = CbContext.fDisabledFound;
    1833 
    1834     if (!fBreakOnDisabled)
    1835     {
    1836         /* now check if 0->0 path is present and enabled, and if not, disable everything */
    1837         if (cItems && paItems[0].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT)
    1838         {
    1839             LOGREL(("path 0 not set to present\n"));
    1840             for (i = 0; i < cItems; ++i)
    1841             {
    1842                 if (paItems[i].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
    1843                     paItems[i].enmState = VBOXVIDPNPATHITEM_STATE_DISABLED;
    1844             }
    1845         }
    1846     }
     1826    BOOLEAN fSupported = !CbContext.fDisabledFound;
     1827
     1828    /* now check if 0->0 path is present and enabled, and if not, disable everything */
     1829//    if (cItems && aItems[0].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT)
     1830//    {
     1831//        LOG(("path 0 not set to present\n"));
     1832////        for (i = 0; i < cItems; ++i)
     1833////        {
     1834////            if (aItems[i].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
     1835////                aItems[i].enmState = VBOXVIDPNPATHITEM_STATE_DISABLED;
     1836////        }
     1837//        fSupported = FALSE;
     1838//    }
     1839
     1840    if (pfSupported)
     1841        *pfSupported = fSupported;
    18471842
    18481843    return Status;
     
    20632058                else
    20642059                {
    2065                     Assert(Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET);
    20662060                    if (Status != STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
    2067                         LOGREL(("pfnAcquireNextPathInfo Failed Status(0x%x), ignored since callback returned false", Status));
     2061                        WARN(("pfnAcquireNextPathInfo Failed Status(0x%x), ignored since callback returned false", Status));
    20682062                    Status = STATUS_SUCCESS;
    20692063                }
     
    20802074            else
    20812075            {
    2082                 AssertBreakpoint();
    2083                 LOGREL(("pfnAcquireNextPathInfo Failed Status(0x%x)", Status));
     2076                WARN(("pfnAcquireNextPathInfo Failed Status(0x%x)", Status));
    20842077                pNewVidPnPresentPathInfo = NULL;
    20852078                break;
     
    20902083        Status = STATUS_SUCCESS;
    20912084    else
    2092         LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
     2085        WARN(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
    20932086
    20942087    return Status;
     
    21812174    return Status == STATUS_SUCCESS;
    21822175}
     2176
     2177#ifdef DEBUG_misha
     2178DWORD g_VBoxDbgBreakModes = 0;
     2179#endif
    21832180
    21842181NTSTATUS vboxVidPnCommitSourceModeForSrcId(PVBOXMP_DEVEXT pDevExt, const D3DKMDT_HVIDPN hDesiredVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, PVBOXWDDM_ALLOCATION pAllocation)
     
    22352232                    }
    22362233                    else
    2237                         LOGREL(("vboxVidPnEnumTargetsForSource failed Status(0x%x)", Status));
     2234                        WARN(("vboxVidPnEnumTargetsForSource failed Status(0x%x)", Status));
    22382235                }
    22392236                else
    2240                     LOGREL(("pfnGetTopology failed Status(0x%x)", Status));
     2237                    WARN(("pfnGetTopology failed Status(0x%x)", Status));
    22412238            }
    22422239            else
    2243                 LOGREL(("vboxVidPnCommitSourceMode failed Status(0x%x)", Status));
     2240                WARN(("vboxVidPnCommitSourceMode failed Status(0x%x)", Status));
    22442241            /* release */
    22452242            pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
     
    22472244        else if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
    22482245        {
     2246#ifdef DEBUG_misha
     2247            Assert(!g_VBoxDbgBreakModes);
     2248            ++g_VBoxDbgBreakModes;
     2249#endif
    22492250            Status = vboxVidPnCommitSourceMode(pDevExt, srcId, NULL, pAllocation);
    22502251            Assert(Status == STATUS_SUCCESS);
    22512252        }
    22522253        else
    2253             LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
     2254            WARN(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
    22542255
    22552256        pVidPnInterface->pfnReleaseSourceModeSet(hDesiredVidPn, hCurVidPnSourceModeSet);
     
    22572258    else
    22582259    {
    2259         LOGREL(("pfnAcquireSourceModeSet failed Status(0x%x)", Status));
     2260        WARN(("pfnAcquireSourceModeSet failed Status(0x%x)", Status));
    22602261    }
    22612262
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.h

    r37490 r48070  
    5858    CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* pEnumCofuncModalityArg;
    5959    PVBOXWDDM_VIDEOMODES_INFO pInfos;
    60     UINT cPathInfos;
    61     PVBOXVIDPNPATHITEM apPathInfos;
     60//    UINT cPathInfos;
     61//    PVBOXVIDPNPATHITEM apPathInfos;
    6262} VBOXVIDPNCOFUNCMODALITY, *PVBOXVIDPNCOFUNCMODALITY;
    6363
     
    146146NTSTATUS vboxVidPnCofuncModalityForPath(PVBOXVIDPNCOFUNCMODALITY pCbContext, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId);
    147147
    148 NTSTATUS vboxVidPnCheckTopology(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
    149                                     BOOLEAN fBreakOnDisabled, UINT cItems, PVBOXVIDPNPATHITEM paItems, BOOLEAN *pfDisabledFound);
     148NTSTATUS vboxVidPnCheckTopology(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface, BOOLEAN *pfSupported);
    150149
    151150NTSTATUS vboxVidPnPathAdd(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp

    r47603 r48070  
    3131#include <VBox/Hardware/VBoxVideoVBE.h>
    3232
     33#include <stdio.h>
     34
    3335DWORD g_VBoxLogUm = 0;
    3436#ifdef VBOX_WDDM_WIN8
     
    187189}
    188190
     191BOOL vboxWddmGhDisplayCheckCompletePeningScreenInfo(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
     192{
     193    if (!ASMAtomicCmpXchgBool(&pDevExt->aTargets[VidPnTargetId].fStateSyncPening, false, true))
     194        return FALSE;
     195    return vboxWddmGhDisplayCheckSetInfoFromSource(pDevExt, &pDevExt->aSources[VidPnTargetId]);
     196}
     197
    189198NTSTATUS vboxWddmGhDisplayPostInfoView(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData)
    190199{
     
    302311}
    303312
    304 bool vboxWddmGhDisplayCheckSetInfoFromSource(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource)
    305 {
    306 //    Assert(VBOXVIDEOOFFSET_VOID != pSource->AllocData.Addr.offVram);
    307 
    308     if (pSource->fGhSynced)
    309         return false;
     313bool vboxWddmGhDisplaySetInfoFromSourceTarget(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource, PVBOXWDDM_TARGET pTarget)
     314{
     315    if (!pTarget->HeightVisible)
     316    {
     317        vboxWddmGhDisplayHideScreen(pDevExt, pSource->AllocData.SurfDesc.VidPnSourceId);
     318        pSource->fGhSynced = 1;
     319        return true;
     320    }
    310321
    311322    char fGhSynced = 1;
     
    346357        WARN(("vboxWddmGhDisplaySetInfo failed, Status (0x%x)", Status));
    347358
     359    vboxVideoCmSignalEvents(&pDevExt->SeamlessCtxMgr);
     360
    348361    return true;
     362}
     363
     364bool vboxWddmGhDisplayCheckSetInfoFromSource(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource)
     365{
     366    Assert(VBOXVIDEOOFFSET_VOID != pSource->AllocData.Addr.offVram
     367            || !pDevExt->aTargets[pSource->AllocData.SurfDesc.VidPnSourceId].HeightVisible);
     368
     369    if (pSource->fGhSynced)
     370        return false;
     371
     372    PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[pSource->AllocData.SurfDesc.VidPnSourceId];
     373    if (ASMAtomicUoReadBool(&pTarget->fStateSyncPening))
     374        return false;
     375
     376    return vboxWddmGhDisplaySetInfoFromSourceTarget(pDevExt, pSource, pTarget);
    349377}
    350378
     
    467495        return VBOXWDDM_HGSMICMD_TYPE_CTL;
    468496    return VBOXWDDM_HGSMICMD_TYPE_UNDEFINED;
    469 }
    470 
    471 static NTSTATUS vboxWddmChildStatusReportPerform(PVBOXMP_DEVEXT pDevExt, PVBOXVDMA_CHILD_STATUS pChildStatus, D3DDDI_VIDEO_PRESENT_TARGET_ID iChild)
    472 {
    473     DXGK_CHILD_STATUS DdiChildStatus;
    474     if (pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_DISCONNECTED)
    475     {
    476         /* report disconnected */
    477         memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));
    478         DdiChildStatus.Type = StatusConnection;
    479         if (iChild != D3DDDI_ID_UNINITIALIZED)
    480         {
    481             Assert(iChild < UINT32_MAX/2);
    482             Assert(iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
    483             DdiChildStatus.ChildUid = iChild;
    484         }
    485         else
    486         {
    487             Assert(pChildStatus->iChild < UINT32_MAX/2);
    488             Assert(pChildStatus->iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
    489             DdiChildStatus.ChildUid = pChildStatus->iChild;
    490         }
    491         LOG(("Reporting DISCONNECT to child %d", DdiChildStatus.ChildUid));
    492         DdiChildStatus.HotPlug.Connected = FALSE;
    493         NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);
    494         if (!NT_SUCCESS(Status))
    495         {
    496             WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));
    497             return Status;
    498         }
    499     }
    500 
    501     if (pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_CONNECTED)
    502     {
    503         /* report disconnected */
    504         memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));
    505         DdiChildStatus.Type = StatusConnection;
    506         if (iChild != D3DDDI_ID_UNINITIALIZED)
    507         {
    508             Assert(iChild < UINT32_MAX/2);
    509             Assert(iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
    510             DdiChildStatus.ChildUid = iChild;
    511         }
    512         else
    513         {
    514             Assert(pChildStatus->iChild < UINT32_MAX/2);
    515             Assert(pChildStatus->iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
    516             DdiChildStatus.ChildUid = pChildStatus->iChild;
    517         }
    518         LOG(("Reporting CONNECT to child %d", DdiChildStatus.ChildUid));
    519         DdiChildStatus.HotPlug.Connected = TRUE;
    520         NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);
    521         if (!NT_SUCCESS(Status))
    522         {
    523             WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));
    524             return Status;
    525         }
    526     }
    527 
    528     if (pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_ROTATED)
    529     {
    530         /* report disconnected */
    531         memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));
    532         DdiChildStatus.Type = StatusRotation;
    533         if (iChild != D3DDDI_ID_UNINITIALIZED)
    534         {
    535             Assert(iChild < UINT32_MAX/2);
    536             Assert(iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
    537             DdiChildStatus.ChildUid = iChild;
    538         }
    539         else
    540         {
    541             Assert(pChildStatus->iChild < UINT32_MAX/2);
    542             Assert(pChildStatus->iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
    543             DdiChildStatus.ChildUid = pChildStatus->iChild;
    544         }
    545         LOG(("Reporting ROTATED to child %d", DdiChildStatus.ChildUid));
    546         DdiChildStatus.Rotation.Angle = pChildStatus->u8RotationAngle;
    547         NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);
    548         if (!NT_SUCCESS(Status))
    549         {
    550             WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));
    551             return Status;
    552         }
    553     }
    554 
    555     return STATUS_SUCCESS;
    556 }
    557 
    558 static NTSTATUS vboxWddmChildStatusDoReportReconnected(PVBOXMP_DEVEXT pDevExt, VBOXVDMACMD_CHILD_STATUS_IRQ *pBody)
    559 {
    560     NTSTATUS Status = STATUS_SUCCESS;
    561 
    562     for (UINT i = 0; i < pBody->cInfos; ++i)
    563     {
    564         PVBOXVDMA_CHILD_STATUS pInfo = &pBody->aInfos[i];
    565         if (pBody->fFlags & VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL)
    566         {
    567             for (D3DDDI_VIDEO_PRESENT_TARGET_ID iChild = 0; iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++iChild)
    568             {
    569                 Status = vboxWddmChildStatusReportPerform(pDevExt, pInfo, iChild);
    570                 if (!NT_SUCCESS(Status))
    571                 {
    572                     WARN(("vboxWddmChildStatusReportPerform failed with Status (0x%x)", Status));
    573                     break;
    574                 }
    575             }
    576         }
    577         else
    578         {
    579             Status = vboxWddmChildStatusReportPerform(pDevExt, pInfo, D3DDDI_ID_UNINITIALIZED);
    580             if (!NT_SUCCESS(Status))
    581             {
    582                 WARN(("vboxWddmChildStatusReportPerform failed with Status (0x%x)", Status));
    583                 break;
    584             }
    585         }
    586     }
    587 
    588     return Status;
    589 }
    590 
    591 typedef struct VBOXWDDMCHILDSTATUSCB
    592 {
    593     PVBOXVDMACBUF_DR pDr;
    594     PKEVENT pEvent;
    595 } VBOXWDDMCHILDSTATUSCB, *PVBOXWDDMCHILDSTATUSCB;
    596 
    597 static DECLCALLBACK(VOID) vboxWddmChildStatusReportCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
    598 {
    599     /* we should be called from our DPC routine */
    600     Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
    601 
    602     PVBOXWDDMCHILDSTATUSCB pCtx = (PVBOXWDDMCHILDSTATUSCB)pvContext;
    603     PVBOXVDMACBUF_DR pDr = pCtx->pDr;
    604     PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
    605     VBOXVDMACMD_CHILD_STATUS_IRQ *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHILD_STATUS_IRQ);
    606 
    607     vboxWddmChildStatusDoReportReconnected(pDevExt, pBody);
    608 
    609     vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
    610 
    611     if (pCtx->pEvent)
    612     {
    613         KeSetEvent(pCtx->pEvent, 0, FALSE);
    614     }
    615 }
    616 
    617 static NTSTATUS vboxWddmChildStatusReportReconnected(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID idTarget)
    618 {
    619 #ifdef VBOX_WDDM_MONITOR_REPLUG_IRQ
    620     NTSTATUS Status = STATUS_UNSUCCESSFUL;
    621     UINT cbCmd = VBOXVDMACMD_SIZE_FROMBODYSIZE(sizeof (VBOXVDMACMD_CHILD_STATUS_IRQ));
    622 
    623     PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbCmd);
    624     if (pDr)
    625     {
    626         // vboxVdmaCBufDrCreate zero initializes the pDr
    627         /* the command data follows the descriptor */
    628         pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;
    629         pDr->cbBuf = cbCmd;
    630         pDr->rc = VERR_NOT_IMPLEMENTED;
    631 
    632         PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
    633         pHdr->enmType = VBOXVDMACMD_TYPE_CHILD_STATUS_IRQ;
    634         pHdr->u32CmdSpecific = 0;
    635         PVBOXVDMACMD_CHILD_STATUS_IRQ pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHILD_STATUS_IRQ);
    636         pBody->cInfos = 1;
    637         if (idTarget == D3DDDI_ID_ALL)
    638         {
    639             pBody->fFlags |= VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL;
    640         }
    641         pBody->aInfos[0].iChild = idTarget;
    642         pBody->aInfos[0].fFlags = VBOXVDMA_CHILD_STATUS_F_DISCONNECTED | VBOXVDMA_CHILD_STATUS_F_CONNECTED;
    643         /* we're going to KeWaitForSingleObject */
    644         Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
    645 
    646         PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);
    647         VBOXWDDMCHILDSTATUSCB Ctx;
    648         KEVENT Event;
    649         KeInitializeEvent(&Event, NotificationEvent, FALSE);
    650         Ctx.pDr = pDr;
    651         Ctx.pEvent = &Event;
    652         vboxVdmaDdiCmdInit(pDdiCmd, 0, 0, vboxWddmChildStatusReportCompletion, &Ctx);
    653         /* mark command as submitted & invisible for the dx runtime since dx did not originate it */
    654         vboxVdmaDdiCmdSubmittedNotDx(pDdiCmd);
    655         int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
    656         Assert(rc == VINF_SUCCESS);
    657         if (RT_SUCCESS(rc))
    658         {
    659             Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
    660             Assert(Status == STATUS_SUCCESS);
    661             return STATUS_SUCCESS;
    662         }
    663 
    664         Status = STATUS_UNSUCCESSFUL;
    665 
    666         vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
    667     }
    668     else
    669     {
    670         Assert(0);
    671         /* @todo: try flushing.. */
    672         LOGREL(("vboxVdmaCBufDrCreate returned NULL"));
    673         Status = STATUS_INSUFFICIENT_RESOURCES;
    674     }
    675 
    676     return Status;
    677 #else
    678     VBOXVDMACMD_CHILD_STATUS_IRQ Body = {0};
    679     Body.cInfos = 1;
    680     if (idTarget == D3DDDI_ID_ALL)
    681     {
    682         Body.fFlags |= VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL;
    683     }
    684     Body.aInfos[0].iChild = idTarget;
    685     Body.aInfos[0].fFlags = VBOXVDMA_CHILD_STATUS_F_DISCONNECTED | VBOXVDMA_CHILD_STATUS_F_CONNECTED;
    686     Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    687     return vboxWddmChildStatusDoReportReconnected(pDevExt, &Body);
    688 #endif
    689 }
    690 
    691 static NTSTATUS vboxWddmChildStatusCheckByMask(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_VIDEOMODES_INFO paInfos, uint8_t *pMask)
    692 {
    693     NTSTATUS Status = STATUS_SUCCESS;
    694     bool bChanged[VBOX_VIDEO_MAX_SCREENS] = {0};
    695     int i;
    696 
    697     LOG(("checking child status.."));
    698 
    699     for (i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
    700     {
    701         if (pMask && !ASMBitTest(pMask, i))
    702             continue;
    703 
    704         LOG(("requested to change child status for display %d", i));
    705 
    706         /* @todo: check that we actually need the current source->target */
    707         PVBOXWDDM_VIDEOMODES_INFO pInfo = &paInfos[i];
    708         VIDEO_MODE_INFORMATION *pModeInfo = &pInfo->aModes[pInfo->iPreferredMode];
    709         BOOLEAN fMatch = FALSE;
    710         Status = vboxVidPnMatchMonitorModes(pDevExt, i, pInfo->aResolutions, pInfo->cResolutions, &fMatch);
    711         if (!NT_SUCCESS(Status))
    712         {
    713             WARN(("vboxVidPnMatchMonitorModes failed Status(0x%x)", Status));
    714             /* ignore the failures here, although we probably should not?? */
    715             break;
    716         }
    717 
    718         bChanged[i] = !fMatch;
    719     }
    720 
    721     if (!NT_SUCCESS(Status))
    722     {
    723         WARN(("updating monitor modes failed, Status(0x%x)", Status));
    724         return Status;
    725     }
    726 
    727     for (i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
    728     {
    729         if (bChanged[i])
    730         {
    731             LOG(("modes changed for display %d", i));
    732 
    733             NTSTATUS tmpStatus = vboxWddmChildStatusReportReconnected(pDevExt, i);
    734             if (!NT_SUCCESS(tmpStatus))
    735             {
    736                 WARN(("vboxWddmChildStatusReportReconnected failed Status(0x%x)", Status));
    737                 /* ignore the failures here, although we probably should not?? */
    738                 break;
    739             }
    740         }
    741     }
    742 
    743     /* wait for the reconnected monitor data to be picked up */
    744     CONST DXGK_MONITOR_INTERFACE *pMonitorInterface;
    745     Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryMonitorInterface(pDevExt->u.primary.DxgkInterface.DeviceHandle, DXGK_MONITOR_INTERFACE_VERSION_V1, &pMonitorInterface);
    746     if (!NT_SUCCESS(Status))
    747     {
    748         WARN(("DxgkCbQueryMonitorInterface failed, Status()0x%x", Status));
    749         return Status;
    750     }
    751 
    752     for (i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
    753     {
    754         D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS;
    755         CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf;
    756         if (!bChanged[i])
    757             continue;
    758 
    759         while (1)
    760         {
    761             Status = pMonitorInterface->pfnAcquireMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle,
    762                                                 i,
    763                                                 &hMonitorSMS,
    764                                                 &pMonitorSMSIf);
    765             if (NT_SUCCESS(Status))
    766             {
    767                 NTSTATUS tmpStatus = pMonitorInterface->pfnReleaseMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle, hMonitorSMS);
    768                 if (!NT_SUCCESS(tmpStatus))
    769                 {
    770                     WARN(("pfnReleaseMonitorSourceModeSet failed tmpStatus(0x%x)", tmpStatus));
    771                 }
    772                 break;
    773             }
    774 
    775             if (Status != STATUS_GRAPHICS_MONITOR_NOT_CONNECTED)
    776             {
    777                 WARN(("DxgkCbQueryMonitorInterface failed, Status()0x%x", Status));
    778                 break;
    779             }
    780 
    781             Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
    782 
    783             LARGE_INTEGER Interval;
    784             Interval.QuadPart = -(int64_t) 2 /* ms */ * 10000;
    785             NTSTATUS tmpStatus = KeDelayExecutionThread(KernelMode, FALSE, &Interval);
    786             if (!NT_SUCCESS(tmpStatus))
    787             {
    788                 WARN(("KeDelayExecutionThread failed tmpStatus(0x%x)", tmpStatus));
    789             }
    790         }
    791     }
    792 
    793     return STATUS_SUCCESS;
    794497}
    795498
     
    1154857                    vboxVdmaDdiNodesInit(pDevExt);
    1155858                    vboxVideoCmInit(&pDevExt->CmMgr);
     859                    vboxVideoCmInit(&pDevExt->SeamlessCtxMgr);
    1156860                    InitializeListHead(&pDevExt->SwapchainList3D);
    1157861                    pDevExt->cContexts3D = 0;
    1158862                    pDevExt->cContexts2D = 0;
     863                    pDevExt->cContextsDispIfResize = 0;
    1159864                    pDevExt->cUnlockedVBVADisabled = 0;
    1160865                    VBOXWDDM_CTXLOCK_INIT(pDevExt);
     
    1162867
    1163868                    VBoxMPCmnInitCustomVideoModes(pDevExt);
    1164                     VBoxWddmInvalidateAllVideoModesInfos(pDevExt);
    1165869
    1166870                    VBoxCommonFromDeviceExt(pDevExt)->fAnyX = VBoxVideoAnyWidthAllowed();
     
    1192896                    }
    1193897
     898                    DWORD dwVal = VBOXWDDM_CFG_DRV_DEFAULT;
     899                    HANDLE hKey = NULL;
     900                    WCHAR aNameBuf[100];
     901
     902                    Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_READ, &hKey);
     903                    if (!NT_SUCCESS(Status))
     904                    {
     905                        WARN(("IoOpenDeviceRegistryKey failed, Status = 0x%x", Status));
     906                        hKey = NULL;
     907                    }
     908
     909
     910                    if (hKey)
     911                    {
     912                        Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_REG_DRV_FLAGS_NAME, &dwVal);
     913                        if (!NT_SUCCESS(Status))
     914                        {
     915                            LOG(("vboxWddmRegQueryValueDword failed, Status = 0x%x", Status));
     916                            dwVal = VBOXWDDM_CFG_DRV_DEFAULT;
     917                        }
     918                    }
     919
     920                    pDevExt->dwDrvCfgFlags = dwVal;
     921
     922                    for (UINT i = 0; i < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     923                    {
     924                        PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];
     925                        if (i == 0 || (pDevExt->dwDrvCfgFlags & VBOXWDDM_CFG_DRV_SECONDARY_TARGETS_CONNECTED) || !hKey)
     926                        {
     927                            pTarget->fConnected = true;
     928                            pTarget->fConfigured = true;
     929                        }
     930                        else if (hKey)
     931                        {
     932                            swprintf(aNameBuf, L"%s%d", VBOXWDDM_REG_DRV_DISPFLAGS_PREFIX, i);
     933                            Status = vboxWddmRegQueryValueDword(hKey, aNameBuf, &dwVal);
     934                            if (NT_SUCCESS(Status))
     935                            {
     936                                pTarget->fConnected = !!(dwVal & VBOXWDDM_CFG_DRVTARGET_CONNECTED);
     937                                pTarget->fConfigured = true;
     938                            }
     939                            else
     940                            {
     941                                WARN(("vboxWddmRegQueryValueDword failed, Status = 0x%x", Status));
     942                                pTarget->fConnected = false;
     943                                pTarget->fConfigured = false;
     944                            }
     945                        }
     946                    }
     947
     948                    if (hKey)
     949                    {
     950                        NTSTATUS tmpStatus = ZwClose(hKey);
     951                        Assert(tmpStatus == STATUS_SUCCESS);
     952                    }
     953
     954                    Status = STATUS_SUCCESS;
    1194955#ifdef VBOX_WDDM_WIN8
    1195956                    DXGK_DISPLAY_INFORMATION DisplayInfo;
     
    1230991                    }
    1231992#endif
     993
     994                    VBoxWddmInitVideoModes(pDevExt);
    1232995                }
    1233996                else
     
    12801043
    12811044    vboxVideoCmTerm(&pDevExt->CmMgr);
     1045
     1046    vboxVideoCmTerm(&pDevExt->SeamlessCtxMgr);
    12821047
    12831048    /* do everything we did on DxgkDdiStartDevice in the reverse order */
     
    16911456        ChildRelations[i].ChildDeviceType = TypeVideoOutput;
    16921457        ChildRelations[i].ChildCapabilities.Type.VideoOutput.InterfaceTechnology = D3DKMDT_VOT_HD15; /* VGA */
    1693         ChildRelations[i].ChildCapabilities.Type.VideoOutput.MonitorOrientationAwareness = D3DKMDT_MOA_INTERRUPTIBLE; /* ?? D3DKMDT_MOA_NONE*/
     1458        ChildRelations[i].ChildCapabilities.Type.VideoOutput.MonitorOrientationAwareness = D3DKMDT_MOA_NONE; //D3DKMDT_MOA_INTERRUPTIBLE; /* ?? D3DKMDT_MOA_NONE*/
    16941459        ChildRelations[i].ChildCapabilities.Type.VideoOutput.SupportsSdtvModes = FALSE;
    16951460        ChildRelations[i].ChildCapabilities.HpdAwareness = HpdAwarenessInterruptible; /* ?? HpdAwarenessAlwaysConnected; */
     
    17141479    LOGF(("ENTER, context(0x%x)", MiniportDeviceContext));
    17151480
     1481    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)MiniportDeviceContext;
     1482
    17161483    NTSTATUS Status = STATUS_SUCCESS;
    17171484    switch (ChildStatus->Type)
    17181485    {
    17191486        case StatusConnection:
    1720             ChildStatus->HotPlug.Connected = TRUE;
     1487        {
    17211488            LOGF(("StatusConnection"));
     1489            VBOXWDDM_TARGET *pTarget = &pDevExt->aTargets[ChildStatus->ChildUid];
     1490            ChildStatus->HotPlug.Connected = !!pTarget->fConnected;
    17221491            break;
     1492        }
    17231493        case StatusRotation:
     1494            LOGF(("StatusRotation"));
    17241495            ChildStatus->Rotation.Angle = 0;
    1725             LOGF(("StatusRotation"));
    17261496            break;
    17271497        default:
    1728             LOGREL(("ERROR: status type: %d", ChildStatus->Type));
    1729             AssertBreakpoint();
     1498            WARN(("ERROR: status type: %d", ChildStatus->Type));
    17301499            Status = STATUS_INVALID_PARAMETER;
    17311500            break;
     
    29932762            VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pS2P->Shadow2Primary.VidPnSourceId];
    29942763            PVBOXWDDM_ALLOCATION pSrcAlloc = pS2P->Shadow2Primary.ShadowAlloc.pAlloc;
    2995             vboxWddmAddrSetVram(&pSrcAlloc->AllocData.Addr, pS2P->Shadow2Primary.ShadowAlloc.segmentIdAlloc, pS2P->Shadow2Primary.ShadowAlloc.offAlloc);
     2764            BOOLEAN fShadowChanged = vboxWddmAddrSetVram(&pSrcAlloc->AllocData.Addr, pS2P->Shadow2Primary.ShadowAlloc.segmentIdAlloc, pS2P->Shadow2Primary.ShadowAlloc.offAlloc);
     2765            if (fShadowChanged)
     2766                pSource->fGhSynced = 0;
    29962767            vboxWddmAssignShadow(pDevExt, pSource, pSrcAlloc, pS2P->Shadow2Primary.VidPnSourceId);
    29972768            vboxWddmModeRenderFromShadowCheckOnSubmitCommand(pDevExt, NULL);
     
    30192790            PVBOXWDDM_ALLOCATION pDstAlloc = pBlt->Blt.DstAlloc.pAlloc;
    30202791            PVBOXWDDM_ALLOCATION pSrcAlloc = pBlt->Blt.SrcAlloc.pAlloc;
     2792            BOOLEAN fSrcChanged;
    30212793
    30222794            vboxWddmAddrSetVram(&pDstAlloc->AllocData.Addr, pBlt->Blt.DstAlloc.segmentIdAlloc, pBlt->Blt.DstAlloc.offAlloc);
    3023             vboxWddmAddrSetVram(&pSrcAlloc->AllocData.Addr, pBlt->Blt.SrcAlloc.segmentIdAlloc, pBlt->Blt.SrcAlloc.offAlloc);
     2795            fSrcChanged = vboxWddmAddrSetVram(&pSrcAlloc->AllocData.Addr, pBlt->Blt.SrcAlloc.segmentIdAlloc, pBlt->Blt.SrcAlloc.offAlloc);
    30242796
    30252797            if (VBOXWDDM_IS_REAL_FB_ALLOCATION(pDevExt, pDstAlloc))
     
    30292801
    30302802                if (pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE)
     2803                {
     2804                    if (fSrcChanged)
     2805                        pSource->fGhSynced = 0;
     2806
    30312807                    vboxWddmAssignShadow(pDevExt, pSource, pSrcAlloc, pDstAlloc->AllocData.SurfDesc.VidPnSourceId);
     2808                }
    30322809                vboxWddmModeRenderFromShadowCheckOnSubmitCommand(pDevExt, NULL);
    30332810                if(pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D
     
    39103687            case VBOXESC_SETVISIBLEREGION:
    39113688            {
     3689                PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
     3690                if (!pContext)
     3691                {
     3692                    WARN(("VBOXESC_SETVISIBLEREGION no context supplied!"));
     3693                    Status = STATUS_INVALID_PARAMETER;
     3694                    break;
     3695                }
     3696
     3697                if (pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_SEAMLESS)
     3698                {
     3699                    WARN(("VBOXESC_SETVISIBLEREGION invalid context supplied %d!", pContext->enmType));
     3700                    Status = STATUS_INVALID_PARAMETER;
     3701                    break;
     3702                }
     3703
    39123704                /* visible regions for seamless */
    39133705                LPRGNDATA lpRgnData = VBOXDISPIFESCAPE_DATA(pEscapeHdr, RGNDATA);
     
    39483740                        rc = VbglGRPerform (&req->header);
    39493741                        AssertRC(rc);
    3950                         if (!RT_SUCCESS(rc))
     3742                        if (RT_SUCCESS(rc))
     3743                            Status = STATUS_SUCCESS;
     3744                        else
    39513745                        {
    3952                             LOGREL(("VbglGRPerform failed rc (%d)", rc));
     3746                            WARN(("VbglGRPerform failed rc (%d)", rc));
    39533747                            Status = STATUS_UNSUCCESSFUL;
    39543748                        }
     
    39563750                    else
    39573751                    {
    3958                         LOGREL(("VbglGRAlloc failed rc (%d)", rc));
     3752                        WARN(("VbglGRAlloc failed rc (%d)", rc));
    39593753                        Status = STATUS_UNSUCCESSFUL;
    39603754                    }
     
    39623756                else
    39633757                {
    3964                     LOGREL(("VBOXESC_SETVISIBLEREGION: incorrect buffer size (%d), reported count (%d)", cbRects, lpRgnData->rdh.nCount));
    3965                     AssertBreakpoint();
     3758                    WARN(("VBOXESC_SETVISIBLEREGION: incorrect buffer size (%d), reported count (%d)", cbRects, lpRgnData->rdh.nCount));
    39663759                    Status = STATUS_INVALID_PARAMETER;
    39673760                }
     
    40543847            case VBOXESC_REINITVIDEOMODES:
    40553848            {
    4056                 if (pEscape->Flags.HardwareAccess)
    4057                 {
    4058                     WARN(("VBOXESC_REINITVIDEOMODES called with HardwareAccess flag set, failing"));
     3849                if (!pEscape->Flags.HardwareAccess)
     3850                {
     3851                    WARN(("VBOXESC_REINITVIDEOMODESBYMASK called without HardwareAccess flag set, failing"));
    40593852                    Status = STATUS_INVALID_PARAMETER;
    40603853                    break;
    40613854                }
    4062                 WARN(("VBOXESC_REINITVIDEOMODESBYMASK should be called instead"));
    4063                 PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddmUpdateAllVideoModesInfos(pDevExt);
    4064                 Status = vboxWddmChildStatusCheckByMask(pDevExt, pInfos, NULL);
    4065                 if (!NT_SUCCESS(Status))
    4066                 {
    4067                     WARN(("vboxWddmChildStatusCheckByMask failed, Status 0x%x", Status));
    4068                 }
    4069                 break;
    4070             }
    4071             case VBOXESC_REINITVIDEOMODESBYMASK:
    4072             {
    4073                 BOOLEAN fCheckDisplayRecconect = (pEscapeHdr->u32CmdSpecific & VBOXWDDM_REINITVIDEOMODESBYMASK_F_RECONNECT_DISPLAYS_ON_CHANGE);
    4074                 if (fCheckDisplayRecconect && pEscape->Flags.HardwareAccess)
    4075                 {
    4076                     WARN(("VBOXESC_REINITVIDEOMODESBYMASK called with HardwareAccess flag set, failing"));
     3855
     3856                PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
     3857                if (!pContext)
     3858                {
     3859                    WARN(("VBOXESC_REINITVIDEOMODES no context supplied!"));
    40773860                    Status = STATUS_INVALID_PARAMETER;
    40783861                    break;
    40793862                }
     3863
     3864                if (pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE)
     3865                {
     3866                    WARN(("VBOXESC_REINITVIDEOMODES invalid context supplied %d!", pContext->enmType));
     3867                    Status = STATUS_INVALID_PARAMETER;
     3868                    break;
     3869                }
     3870
     3871                WARN(("VBOXESC_REINITVIDEOMODESBYMASK should be called instead"));
     3872                VBoxWddmUpdateVideoModesInfoByMask(pDevExt, NULL);
     3873                Status = STATUS_SUCCESS;
     3874                break;
     3875            }
     3876            case VBOXESC_REINITVIDEOMODESBYMASK:
     3877            {
     3878                if (!pEscape->Flags.HardwareAccess)
     3879                {
     3880                    WARN(("VBOXESC_REINITVIDEOMODESBYMASK called without HardwareAccess flag set, failing"));
     3881                    Status = STATUS_INVALID_PARAMETER;
     3882                    break;
     3883                }
     3884
     3885                PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
     3886                if (!pContext)
     3887                {
     3888                    WARN(("VBOXESC_REINITVIDEOMODESBYMASK no context supplied!"));
     3889                    Status = STATUS_INVALID_PARAMETER;
     3890                    break;
     3891                }
     3892
     3893                if (pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE)
     3894                {
     3895                    WARN(("VBOXESC_REINITVIDEOMODESBYMASK invalid context supplied %d!", pContext->enmType));
     3896                    Status = STATUS_INVALID_PARAMETER;
     3897                    break;
     3898                }
     3899
    40803900                if (pEscape->PrivateDriverDataSize != sizeof (VBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK))
    40813901                {
     
    40863906                LOG(("=> VBOXESC_REINITVIDEOMODESBYMASK"));
    40873907                PVBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK pData = (PVBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK)pEscapeHdr;
    4088                 PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddmUpdateVideoModesInfoByMask(pDevExt, pData->ScreenMask);
    4089                 if (fCheckDisplayRecconect)
    4090                 {
    4091                     Status = vboxWddmChildStatusCheckByMask(pDevExt, pInfos, pData->ScreenMask);
     3908                VBoxWddmUpdateVideoModesInfoByMask(pDevExt, pData->ScreenMask);
     3909                Status = STATUS_SUCCESS;
     3910                LOG(("<= VBOXESC_REINITVIDEOMODESBYMASK"));
     3911                break;
     3912            }
     3913            case VBOXESC_CONFIGURETARGETS:
     3914            {
     3915                LOG(("=> VBOXESC_CONFIGURETARGETS"));
     3916
     3917                if (!pEscape->Flags.HardwareAccess)
     3918                {
     3919                    WARN(("VBOXESC_CONFIGURETARGETS called without HardwareAccess flag set, failing"));
     3920                    Status = STATUS_INVALID_PARAMETER;
     3921                    break;
     3922                }
     3923
     3924                PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
     3925                if (!pContext)
     3926                {
     3927                    WARN(("VBOXESC_CONFIGURETARGETS no context supplied!"));
     3928                    Status = STATUS_INVALID_PARAMETER;
     3929                    break;
     3930                }
     3931
     3932                if (pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE)
     3933                {
     3934                    WARN(("VBOXESC_CONFIGURETARGETS invalid context supplied %d!", pContext->enmType));
     3935                    Status = STATUS_INVALID_PARAMETER;
     3936                    break;
     3937                }
     3938
     3939                if (pEscape->PrivateDriverDataSize != sizeof (*pEscapeHdr))
     3940                {
     3941                    WARN(("VBOXESC_CONFIGURETARGETS invalid private driver size %d", pEscape->PrivateDriverDataSize));
     3942                    Status = STATUS_INVALID_PARAMETER;
     3943                    break;
     3944                }
     3945
     3946                if (pEscapeHdr->u32CmdSpecific)
     3947                {
     3948                    WARN(("VBOXESC_CONFIGURETARGETS invalid command %d", pEscapeHdr->u32CmdSpecific));
     3949                    Status = STATUS_INVALID_PARAMETER;
     3950                    break;
     3951                }
     3952
     3953                HANDLE hKey = NULL;
     3954                WCHAR aNameBuf[100];
     3955                uint32_t cAdjusted = 0;
     3956
     3957                for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     3958                {
     3959                    VBOXWDDM_TARGET *pTarget = &pDevExt->aTargets[i];
     3960                    if (pTarget->fConfigured)
     3961                        continue;
     3962
     3963                    pTarget->fConfigured = true;
     3964
     3965                    if (!pTarget->fConnected)
     3966                    {
     3967                        Status = vboxWddmChildStatusConnect(pDevExt, (uint32_t)i, TRUE);
     3968                        if (NT_SUCCESS(Status))
     3969                            ++cAdjusted;
     3970                        else
     3971                            WARN(("VBOXESC_CONFIGURETARGETS vboxWddmChildStatusConnectSecondaries failed Status 0x%x\n", Status));
     3972                    }
     3973
     3974                    if (!hKey)
     3975                    {
     3976                        Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_WRITE, &hKey);
     3977                        if (!NT_SUCCESS(Status))
     3978                        {
     3979                            WARN(("VBOXESC_CONFIGURETARGETS IoOpenDeviceRegistryKey failed, Status = 0x%x", Status));
     3980                            hKey = NULL;
     3981                            continue;
     3982                        }
     3983                    }
     3984
     3985                    Assert(hKey);
     3986
     3987                    swprintf(aNameBuf, L"%s%d", VBOXWDDM_REG_DRV_DISPFLAGS_PREFIX, i);
     3988                    Status = vboxWddmRegSetValueDword(hKey, aNameBuf, VBOXWDDM_CFG_DRVTARGET_CONNECTED);
    40923989                    if (!NT_SUCCESS(Status))
    4093                     {
    4094                         WARN(("vboxWddmChildStatusCheckByMask failed, Status 0x%x", Status));
    4095                     }
    4096                 }
    4097                 LOG(("<= VBOXESC_REINITVIDEOMODESBYMASK"));
     3990                        WARN(("VBOXESC_CONFIGURETARGETS vboxWddmRegSetValueDword (%d) failed Status 0x%x\n", aNameBuf, Status));
     3991
     3992                }
     3993
     3994                if (hKey)
     3995                {
     3996                    NTSTATUS tmpStatus = ZwClose(hKey);
     3997                    Assert(tmpStatus == STATUS_SUCCESS);
     3998                }
     3999
     4000                pEscapeHdr->u32CmdSpecific = cAdjusted;
     4001
     4002                Status = STATUS_SUCCESS;
     4003
     4004                LOG(("<= VBOXESC_CONFIGURETARGETS"));
    40984005                break;
    40994006            }
     
    42214128            }
    42224129            default:
    4223                 Assert(0);
    4224                 LOGREL(("unsupported escape code (0x%x)", pEscapeHdr->escapeCode));
     4130                WARN(("unsupported escape code (0x%x)", pEscapeHdr->escapeCode));
    42254131                break;
    42264132        }
     
    42284134    else
    42294135    {
    4230         LOGREL(("pEscape->PrivateDriverDataSize(%d) < (%d)", pEscape->PrivateDriverDataSize, sizeof (VBOXDISPIFESCAPE)));
    4231         AssertBreakpoint();
     4136        WARN(("pEscape->PrivateDriverDataSize(%d) < (%d)", pEscape->PrivateDriverDataSize, sizeof (VBOXDISPIFESCAPE)));
    42324137        Status = STATUS_BUFFER_TOO_SMALL;
    42334138    }
     
    43154220
    43164221    NTSTATUS Status = STATUS_SUCCESS;
    4317     BOOLEAN bSupported = TRUE;
    43184222
    43194223    PVBOXMP_DEVEXT pContext = (PVBOXMP_DEVEXT)hAdapter;
     
    43394243    }
    43404244
    4341     VBOXVIDPNPATHITEM aItems[VBOX_VIDEO_MAX_SCREENS];
    4342     BOOLEAN fDisabledFound = FALSE;
    4343     Status = vboxVidPnCheckTopology(hVidPnTopology, pVidPnTopologyInterface, TRUE /* fBreakOnDisabled */, RT_ELEMENTS(aItems), aItems, &fDisabledFound);
    4344     Assert(Status == STATUS_SUCCESS);
     4245    BOOLEAN fSupported = FALSE;
     4246    Status = vboxVidPnCheckTopology(hVidPnTopology, pVidPnTopologyInterface, &fSupported);
    43454247    if (!NT_SUCCESS(Status))
    43464248    {
     
    43494251    }
    43504252
    4351     if (fDisabledFound)
    4352     {
     4253    if (!fSupported)
    43534254        LOG(("found unsupported path"));
    4354         bSupported = FALSE;
    4355     }
    4356 
    4357     pIsSupportedVidPnArg->IsVidPnSupported = bSupported;
     4255
     4256    pIsSupportedVidPnArg->IsVidPnSupported = fSupported;
    43584257
    43594258#ifdef VBOXWDDM_DEBUG_VIDPN
     
    43804279    vboxVDbgBreakFv();
    43814280
     4281#ifdef DEBUG_misha
     4282    Assert(0);
     4283#endif
     4284
    43824285    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
    43834286    NTSTATUS Status;
    43844287    PVBOXWDDM_RECOMMENDVIDPN pVidPnInfo = pRecommendFunctionalVidPnArg->PrivateDriverDataSize >= sizeof (VBOXWDDM_RECOMMENDVIDPN) ?
    43854288            (PVBOXWDDM_RECOMMENDVIDPN)pRecommendFunctionalVidPnArg->pPrivateDriverData : NULL;
    4386     PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddmUpdateAllVideoModesInfos(pDevExt);
     4289    PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddmGetAllVideoModesInfos(pDevExt);
    43874290    int i;
    43884291
     
    45294432    }
    45304433
    4531     VBOXVIDPNPATHITEM aItems[VBOX_VIDEO_MAX_SCREENS];
    4532     Status = vboxVidPnCheckTopology(hVidPnTopology, pVidPnTopologyInterface, FALSE /* fBreakOnDisabled */, RT_ELEMENTS(aItems), aItems, NULL /* *pfDisabledFound */);
    4533     Assert(Status == STATUS_SUCCESS);
     4434#ifdef DEBUG_misha
     4435    BOOLEAN fSupported = FALSE;
     4436    Status = vboxVidPnCheckTopology(hVidPnTopology, pVidPnTopologyInterface, &fSupported);
    45344437    if (!NT_SUCCESS(Status))
    45354438    {
     
    45384441    }
    45394442
     4443    Assert(fSupported);
     4444#endif
    45404445    VBOXVIDPNCOFUNCMODALITY CbContext = {0};
    45414446    CbContext.pDevExt = pDevExt;
     
    45434448    CbContext.pEnumCofuncModalityArg = pEnumCofuncModalityArg;
    45444449    CbContext.pInfos = VBoxWddmGetAllVideoModesInfos(pDevExt);
    4545     CbContext.cPathInfos = RT_ELEMENTS(aItems);
    4546     CbContext.apPathInfos = aItems;
    45474450
    45484451    Status = vboxVidPnEnumPaths(hVidPnTopology, pVidPnTopologyInterface,
    45494452                    vboxVidPnCofuncModalityPathEnum, &CbContext);
    4550     Assert(Status == STATUS_SUCCESS);
    45514453    if (!NT_SUCCESS(Status))
    45524454    {
     
    47054607}
    47064608
    4707 
    47084609NTSTATUS
    47094610APIENTRY
     
    47164617
    47174618    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
    4718     uint32_t au32OldHeightVisible[VBOX_VIDEO_MAX_SCREENS];
    47194619    NTSTATUS Status;
    47204620
    47214621    vboxVDbgBreakFv();
    4722 
    4723     /* we first store the current visible height for each target (monitor)
    4724      * and then we will zero up it for targets either for the given source
    4725      * (in case pCommitVidPnArg->AffectedVidPnSourceId != D3DDDI_ID_ALL)
    4726      * or all targets otherwize.
    4727      * In the end we will match the old and new visible height for all targets to see if
    4728      * some of them become inactivated and hide them accordingly,
    4729      * or we will restore the old height values on failure */
    4730     for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
    4731     {
    4732         PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];
    4733         au32OldHeightVisible[i] = pTarget->HeightVisible;
    4734     }
    47354622
    47364623    do {
     
    48404727        pDevExt->u.primary.hCommittedVidPn = pCommitVidPnArg->hFunctionalVidPn;
    48414728
    4842         for (int i = 1; /* <- never try to hide a primary monitor */
    4843                 i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     4729        for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
    48444730        {
    48454731            PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];
    4846             if (!pTarget->HeightVisible && !!au32OldHeightVisible[i])
    4847             {
    4848                 /* the target was previously visible */
    4849                 vboxWddmGhDisplayHideScreen(pDevExt, i);
    4850             }
    4851         }
    4852 
    4853 //#ifdef VBOX_WDDM_WIN8
    4854 //        if (g_VBoxDisplayOnly)
    4855         {
    4856             for (int i = 0; /* <- never try to hide a primary monitor */
    4857                     i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
    4858             {
    4859                 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[i];
    4860                 if (pSource->bVisible)
    4861                 {
     4732            PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[i];
     4733            uint32_t cAutoresizes = pDevExt->cContextsDispIfResize;
     4734            if (!cAutoresizes)
     4735            {
     4736                if (pSource->bVisible || !pTarget->HeightVisible)
    48624737                    vboxWddmGhDisplayCheckSetInfoFromSource(pDevExt, pSource);
    4863                 }
    4864             }
    4865         }
    4866 //#endif
     4738            }
     4739            else
     4740                pTarget->fStateSyncPening = true;
     4741        }
     4742
    48674743        LOGF(("LEAVE, SUCCESS status(0x%x), context(0x%x)", Status, hAdapter));
    48684744
     
    48714747
    48724748    AssertRelease(!NT_SUCCESS(Status));
    4873     /* failure branch restore original visible height values, see comments above */
    4874     for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
    4875     {
    4876         PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];
    4877         pTarget->HeightVisible = au32OldHeightVisible[i];
    4878     }
    48794749
    48804750    LOGF(("LEAVE, !!FAILURE!! status(0x%x), context(0x%x)", Status, hAdapter));
     
    58485718                        break;
    58495719                    }
     5720                    case VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE:
     5721                    {
     5722                        pContext->enmType = pInfo->enmType;
     5723                        ASMAtomicIncU32(&pDevExt->cContextsDispIfResize);
     5724                        break;
     5725                    }
     5726                    case VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_SEAMLESS:
     5727                    {
     5728                        pContext->enmType = pInfo->enmType;
     5729                        Status = vboxVideoCmCtxAdd(&pDevice->pAdapter->SeamlessCtxMgr, &pContext->CmContext, (HANDLE)pInfo->hUmEvent, pInfo->u64UmInfo);
     5730                        if (!NT_SUCCESS(Status))
     5731                        {
     5732                            WARN(("vboxVideoCmCtxAdd failed, Status 0x%x", Status));
     5733                        }
     5734                        break;
     5735                    }
    58505736                    default:
    58515737                    {
    5852                         Assert(0);
     5738                        WARN(("unsupported context type %d", pInfo->enmType));
    58535739                        Status = STATUS_INVALID_PARAMETER;
    58545740                        break;
     
    58915777    PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
    58925778    PVBOXMP_DEVEXT pDevExt = pContext->pDevice->pAdapter;
     5779    NTSTATUS Status = STATUS_SUCCESS;
     5780
    58935781    switch(pContext->enmType)
    58945782    {
     
    59055793            uint32_t cContexts = ASMAtomicDecU32(&pDevExt->cContexts2D);
    59065794            Assert(cContexts < UINT32_MAX/2);
     5795            break;
     5796        }
     5797        case VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE:
     5798        {
     5799            uint32_t cContexts = ASMAtomicDecU32(&pDevExt->cContextsDispIfResize);
     5800            Assert(cContexts < UINT32_MAX/2);
     5801            if (!cContexts)
     5802            {
     5803                for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     5804                {
     5805                    vboxWddmGhDisplayCheckCompletePeningScreenInfo(pDevExt, i);
     5806                }
     5807            }
     5808            break;
     5809        }
     5810        case VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_SEAMLESS:
     5811        {
     5812            Status = vboxVideoCmCtxRemove(&pContext->pDevice->pAdapter->SeamlessCtxMgr, &pContext->CmContext);
     5813            if (!NT_SUCCESS(Status))
     5814                WARN(("vboxVideoCmCtxRemove failed, Status 0x%x", Status));
     5815
     5816            Assert(pContext->CmContext.pSession == NULL);
    59075817            break;
    59085818        }
     
    59235833    vboxWddmSwapchainCtxTerm(pDevExt, pContext);
    59245834
    5925     NTSTATUS Status = vboxVideoAMgrCtxDestroy(&pContext->AllocContext);
    5926     Assert(Status == STATUS_SUCCESS);
    5927     if (Status == STATUS_SUCCESS)
     5835    Status = vboxVideoAMgrCtxDestroy(&pContext->AllocContext);
     5836    if (NT_SUCCESS(Status))
    59285837    {
    59295838        Status = vboxVideoCmCtxRemove(&pContext->pDevice->pAdapter->CmMgr, &pContext->CmContext);
    5930         Assert(Status == STATUS_SUCCESS);
    5931         if (Status == STATUS_SUCCESS)
    5932         {
     5839        if (NT_SUCCESS(Status))
    59335840            vboxWddmMemFree(pContext);
    5934         }
    5935     }
     5841        else
     5842            WARN(("vboxVideoCmCtxRemove failed, Status 0x%x", Status));
     5843    }
     5844    else
     5845        WARN(("vboxVideoAMgrCtxDestroy failed, Status 0x%x", Status));
    59365846
    59375847    LOGF(("LEAVE, hContext(0x%x)", hContext));
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.h

    r47063 r48070  
    3737//#define VBOXWDDM_DEBUG_VIDPN
    3838
     39#define VBOXWDDM_CFG_DRV_DEFAULT                        0
     40#define VBOXWDDM_CFG_DRV_SECONDARY_TARGETS_CONNECTED    1
     41
     42#define VBOXWDDM_CFG_DRVTARGET_CONNECTED                1
     43
    3944#define VBOXWDDM_CFG_LOG_UM_BACKDOOR 0x00000001
    4045#define VBOXWDDM_CFG_LOG_UM_DBGPRINT 0x00000002
    4146#define VBOXWDDM_CFG_STR_LOG_UM L"VBoxLogUm"
     47
     48#define VBOXWDDM_REG_DRV_FLAGS_NAME L"VBoxFlags"
     49#define VBOXWDDM_REG_DRV_DISPFLAGS_PREFIX L"VBoxDispFlags"
     50
     51#define VBOXWDDM_REG_DRVKEY_PREFIX L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\"
     52
     53#define VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\"
     54#define VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY_SUBKEY L"\\Video"
     55
     56
     57#define VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_VISTA L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Control\\VIDEO\\"
     58#define VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_WIN7 L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\UnitedVideo\\CONTROL\\VIDEO\\"
     59
     60#define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELX L"Attach.RelativeX"
     61#define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELY L"Attach.RelativeY"
     62#define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_DESKTOP L"Attach.ToDesktop"
     63
    4264extern DWORD g_VBoxLogUm;
    4365
     
    81103}
    82104
    83 DECLINLINE(VOID) vboxWddmAddrSetVram(PVBOXWDDM_ADDR pAddr, UINT SegmentId, VBOXVIDEOOFFSET offVram)
    84 {
     105DECLINLINE(BOOLEAN) vboxWddmAddrSetVram(PVBOXWDDM_ADDR pAddr, UINT SegmentId, VBOXVIDEOOFFSET offVram)
     106{
     107    if (pAddr->SegmentId == SegmentId && pAddr->offVram == offVram)
     108        return FALSE;
     109
    85110    pAddr->SegmentId = SegmentId;
    86111    pAddr->offVram = offVram;
     112    return TRUE;
    87113}
    88114
     
    191217    return pPrimary;
    192218}
     219
     220bool vboxWddmGhDisplayCheckSetInfoFromSource(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource);
    193221
    194222#define VBOXWDDMENTRY_2_SWAPCHAIN(_pE) ((PVBOXWDDM_SWAPCHAIN)((uint8_t*)(_pE) - RT_OFFSETOF(VBOXWDDM_SWAPCHAIN, DevExtListEntry)))
  • trunk/src/VBox/Additions/WINNT/VBoxTray/Makefile.kmk

    r42288 r48070  
    6161 VBoxTray_DEFS   += VBOX_WITH_WDDM
    6262 # VBoxTray_DEFS   += LOG_ENABLED
     63 VBoxTray_SOURCES += ../Graphics/Video/disp/wddm/VBoxDispKmt.cpp
    6364endif
    6465
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDispIf.cpp

    r46625 r48070  
    2727#endif
    2828
     29#include "VBoxDisplay.h"
     30
     31#ifndef NT_SUCCESS
     32# define NT_SUCCESS(_Status) ((_Status) >= 0)
     33#endif
     34
     35typedef struct VBOXDISPIF_OP
     36{
     37    PCVBOXDISPIF pIf;
     38    VBOXDISPKMT_ADAPTER Adapter;
     39    VBOXDISPKMT_DEVICE Device;
     40    VBOXDISPKMT_CONTEXT Context;
     41} VBOXDISPIF_OP;
     42
     43DWORD 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
     46static DWORD vboxDispIfWddmResizeDisplay(PCVBOXDISPIF const pIf, UINT Id, BOOL fEnable, DISPLAY_DEVICE * paDisplayDevices, DEVMODE *paDeviceMode, UINT devModes);
     47
     48static DWORD vboxDispIfResizePerform(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes);
     49
     50static DWORD vboxDispIfWddmEnableDisplaysTryingTopology(PCVBOXDISPIF const pIf, UINT cIds, UINT *pIds, BOOL fEnable);
     51
     52static DWORD vboxDispIfResizeStartedWDDMOp(VBOXDISPIF_OP *pOp);
     53
    2954/* APIs specific to win7 and above WDDM architecture. Not available for Vista WDDM.
    3055 * This is the reason they have not been put in the VBOXDISPIF struct in VBoxDispIf.h
     
    4267static _VBOXDISPLAYWDDMAPICONTEXT gCtx = {0};
    4368
     69typedef 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
     77static 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
     120static 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
     161static 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
     171static UINT32 g_cVBoxDispIfWddmDisplays = 0;
     172static 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
     205static 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
     218static 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
     230static 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
     236static 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
     251static 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
     270static 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
     348static 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
     356static 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
     374static 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
     387static 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
     505static 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
     533static VOID vboxDispIfOpEnd(VBOXDISPIF_OP *pOp)
     534{
     535    vboxDispKmtDestroyContext(&pOp->Context);
     536    vboxDispKmtDestroyDevice(&pOp->Device);
     537    vboxDispKmtCloseAdapter(&pOp->Adapter);
     538}
     539
    44540/* display driver interface abstraction for XPDM & WDDM
    45541 * with WDDM we can not use ExtEscape to communicate with our driver
     
    60556{
    61557#ifdef VBOX_WITH_WDDM
    62     if (pIf->enmMode == VBOXDISPIF_MODE_WDDM)
     558    if (pIf->enmMode >= VBOXDISPIF_MODE_WDDM)
    63559    {
    64560        vboxDispIfWddmTerm(pIf);
     561
     562        vboxDispKmtCallbacksTerm(&pIf->modeData.wddm.KmtCallbacks);
    65563    }
    66564#endif
     
    127625
    128626            /* 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            }
    168633        }
    169634        else
    170635        {
    171             Log((__FUNCTION__": GetModuleHandle(user32) failed, err(%d)\n", GetLastError()));
     636            WARN((__FUNCTION__": GetModuleHandle(USER32) failed, err(%d)\n", GetLastError()));
    172637            err = ERROR_NOT_SUPPORTED;
    173638        }
     
    175640    else
    176641    {
    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"));
    178643        err = ERROR_NOT_SUPPORTED;
    179644    }
     
    185650
    186651    return err;
     652}
     653
     654static DWORD vboxDispIfSwitchToWDDM_W7(PVBOXDISPIF pIf)
     655{
     656    return vboxDispIfSwitchToWDDM(pIf);
    187657}
    188658
     
    209679                {
    210680                    winEr = GetLastError();
    211                     Log(("CreateDC failed %d", winEr));
     681                    WARN(("CreateDC failed %d", winEr));
    212682                    break;
    213683                }
     
    218688        {
    219689            winEr = GetLastError();
    220             Log(("EnumDisplayDevices failed %d", winEr));
     690            WARN(("EnumDisplayDevices failed %d", winEr));
    221691            break;
    222692        }
    223693    }
    224694
    225     Log(("vboxDispIfWDDMAdpHdcCreate failure branch %d", winEr));
     695    WARN(("vboxDispIfWDDMAdpHdcCreate failure branch %d", winEr));
    226696    return winEr;
    227697}
    228698
    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;
     699static 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    }
    282709
    283710    D3DKMT_ESCAPE EscapeData = {0};
    284     EscapeData.hAdapter = hAdapter;
     711    EscapeData.hAdapter = Adapter.hAdapter;
    285712    //EscapeData.hDevice = NULL;
    286713    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);
    290718    //EscapeData.hContext = NULL;
    291719
    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;
    318723    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;
    388732}
    389733#endif
     
    398742#ifdef VBOX_WITH_WDDM
    399743        case VBOXDISPIF_MODE_WDDM:
     744        case VBOXDISPIF_MODE_WDDM_W7:
    400745            return vboxDispIfEscapeWDDM(pIf, pEscape, cbData, TRUE /* BOOL fHwAccess */);
    401746#endif
     
    415760#ifdef VBOX_WITH_WDDM
    416761        case VBOXDISPIF_MODE_WDDM:
     762        case VBOXDISPIF_MODE_WDDM_W7:
    417763            return vboxDispIfEscapeWDDM(pIf, pEscape, cbData, TRUE /* BOOL fHwAccess */);
    418764#endif
     
    422768    }
    423769}
    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_WDDM
    439         case VBOXDISPIF_MODE_WDDM:
    440             return vboxDispIfResizeWDDM(pIf, Id, Width, Height, BitsPerPixel);
    441 #endif
    442         default:
    443             Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));
    444             return ERROR_INVALID_PARAMETER;
    445     }
    446 }
    447 
    448770
    449771#ifdef VBOX_WITH_WDDM
     
    460782    UINT_PTR idTimer;
    461783    PCVBOXDISPIF pIf;
     784    UINT iChangedMode;
     785    BOOL fEnable;
     786    BOOL fExtDispSup;
    462787    DISPLAY_DEVICE *paDisplayDevices;
    463788    DEVMODE *paDeviceModes;
     
    506831}
    507832
    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);
    509834
    510835static void vboxRrRetryReschedule()
     
    512837}
    513838
    514 static void VBoxRrRetrySchedule(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes)
     839static void VBoxRrRetrySchedule(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes)
    515840{
    516841    PVBOXRR pMon = &g_VBoxRr;
     
    519844
    520845    pMon->pIf = pIf;
     846    pMon->iChangedMode = iChangedMode;
     847    pMon->fEnable = fEnable;
     848    pMon->fExtDispSup = fExtDispSup;
     849
    521850    if (cDevModes)
    522851    {
     
    549878    if (!pMon->idTimer)
    550879    {
    551         Log(("VBoxTray: SetTimer failed!, err %d\n", GetLastError()));
     880        WARN(("VBoxTray: SetTimer failed!, err %d\n", GetLastError()));
    552881        vboxRrRetryStopLocked();
    553882    }
     
    562891    if (pMon->pIf)
    563892    {
    564         DWORD dwErr = vboxDispIfWddmValidateFixResize(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);
    565894        if (ERROR_RETRY != dwErr)
    566895            VBoxRrRetryStop();
     
    634963        {
    635964            DWORD winErr = GetLastError();
    636             Log((__FUNCTION__": RegisterClass failed, winErr(%d)\n", winErr));
     965            WARN((__FUNCTION__": RegisterClass failed, winErr(%d)\n", winErr));
    637966            hr = E_FAIL;
    638967        }
     
    658987        {
    659988            DWORD winErr = GetLastError();
    660             Log((__FUNCTION__": CreateWindowEx failed, winErr(%d)\n", winErr));
     989            WARN((__FUNCTION__": CreateWindowEx failed, winErr(%d)\n", winErr));
    661990            hr = E_FAIL;
    662991        }
     
    6731002
    6741003    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));
    6761005
    6771006    return HRESULT_FROM_WIN32(winErr);
     
    7311060            DWORD winEr = GetLastError();
    7321061            hr = HRESULT_FROM_WIN32(winEr);
    733             Assert(0);
    7341062            /* just ensure we never return success in this case */
    7351063            Assert(hr != S_OK);
     
    7371065            if (hr == S_OK || hr == S_FALSE)
    7381066                hr = E_FAIL;
    739             Log(("VBoxTray: GetMessage returned -1, err %d\n", winEr));
     1067            WARN(("VBoxTray: GetMessage returned -1, err %d\n", winEr));
    7401068            VBoxRrRetryStop();
    7411069            break;
     
    7691097    {
    7701098        DWORD winErr = GetLastError();
    771         Log((__FUNCTION__": SetEvent failed, winErr = (%d)", winErr));
     1099        WARN((__FUNCTION__": SetEvent failed, winErr = (%d)", winErr));
    7721100        HRESULT tmpHr = HRESULT_FROM_WIN32(winErr);
    7731101        Assert(tmpHr != S_OK);
     
    8221150        {
    8231151            DWORD winErr = GetLastError();
    824             Log((__FUNCTION__": CreateThread failed, winErr = (%d)", winErr));
     1152            WARN((__FUNCTION__": CreateThread failed, winErr = (%d)", winErr));
    8251153            hr = HRESULT_FROM_WIN32(winErr);
    8261154            Assert(hr != S_OK);
     
    8311159    {
    8321160        DWORD winErr = GetLastError();
    833         Log((__FUNCTION__": CreateEvent failed, winErr = (%d)", winErr));
     1161        WARN((__FUNCTION__": CreateEvent failed, winErr = (%d)", winErr));
    8341162        hr = HRESULT_FROM_WIN32(winErr);
    8351163        Assert(hr != S_OK);
     
    8771205}
    8781206
    879 
    880 typedef struct VBOXDISPIF_WDDM_INTERNAL
    881 {
    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 have
    927              * 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 != 0
    954                     && RegDevMode.dmPelsHeight == 0)
    955             {
    956                 if (CurDevMode.dmBitsPerPel != RegDevMode.dmBitsPerPel
    957                         || CurDevMode.dmPelsWidth != RegDevMode.dmPelsWidth
    958                         || CurDevMode.dmPelsHeight != RegDevMode.dmPelsHeight
    959                         || CurDevMode.dmPosition.x != RegDevMode.dmPosition.x
    960                         || 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.dmBitsPerPel
    973                             || (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     else
    1045     {
    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 
    10611207static DWORD vboxDispIfWddmInit(PCVBOXDISPIF pIf)
    10621208{
    1063     memset(&g_VBoxDispIfWddm, 0, sizeof (g_VBoxDispIfWddm));
    1064     g_VBoxDispIfWddm.pIf = pIf;
    10651209    HRESULT hr = VBoxRrInit();
    10661210    if (SUCCEEDED(hr))
     
    10681212        return ERROR_SUCCESS;
    10691213    }
    1070     return ERROR_GEN_FAILURE;
     1214    WARN(("VBoxTray: VBoxRrInit failed hr 0x%x\n", hr));
     1215    return hr;
    10711216}
    10721217
     
    10741219{
    10751220    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
     1223static 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
     1250static 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
     1297static 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;
    11051316    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;
    11301327}
    11311328
     
    11371334}
    11381335
    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)
     1336static 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
     1355DWORD vboxDispIfResizeModesWDDM(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes)
    12151356{
    12161357    UINT cbVidPnInfo = VBOXWDDM_RECOMMENDVIDPN_SIZE(cDevModes);
     
    12181359    pVidPnInfo->cScreenInfos = cDevModes;
    12191360    D3DKMT_HANDLE hAdapter = NULL;
    1220     NTSTATUS Status;
    12211361    DWORD winEr = NO_ERROR;
    12221362    UINT i = 0;
     
    12251365    VBoxRrRetryStop();
    12261366
    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
    13371380        uint8_t ScreenMask[VBOXWDDM_SCREENMASK_SIZE] = {0};
    13381381        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);
    13501386
    13511387    if (winEr == ERROR_RETRY)
    13521388    {
    1353         VBoxRrRetrySchedule(pIf, paDisplayDevices, paDeviceModes, cDevModes);
     1389        VBoxRrRetrySchedule(pIf, iChangedMode, fEnable, fExtDispSup, paDisplayDevices, paDeviceModes, cDevModes);
    13541390        /* just pretend everything is fine so far */
    13551391        winEr = NO_ERROR;
    13561392    }
    13571393
     1394    vboxDispIfOpEnd(&Op);
     1395
    13581396    return winEr;
    13591397}
    13601398
    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;
     1399static 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;
    14041431                break;
    14051432            }
    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
     1529done:
     1530    vboxDispIfWddmDcTerm(&DispCfg);
     1531
     1532    return winEr;
     1533}
     1534
     1535static 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
     1552static 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;
    15031644}
    15041645
    15051646#endif /* VBOX_WITH_WDDM */
    15061647
    1507 DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes)
     1648DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes)
    15081649{
    15091650    switch (pIf->enmMode)
     
    15151656#ifdef VBOX_WITH_WDDM
    15161657        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);
    15181660#endif
    15191661        default:
    1520             Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));
     1662            WARN((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));
    15211663            return ERROR_INVALID_PARAMETER;
    15221664    }
     
    15331675#ifdef VBOX_WITH_WDDM
    15341676        case VBOXDISPIF_MODE_WDDM:
     1677        case VBOXDISPIF_MODE_WDDM_W7:
    15351678            return vboxDispIfCancelPendingResizeWDDM(pIf);
    15361679#endif
    15371680        default:
    1538             Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));
     1681            WARN((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));
    15391682            return ERROR_INVALID_PARAMETER;
    15401683    }
    15411684}
    15421685
    1543 DWORD VBoxDispIfReninitModes(PCVBOXDISPIF const pIf, uint8_t *pScreenIdMask, BOOL fReconnectDisplaysOnChange)
     1686static 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
     1712static 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
     1829static 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
     1851DWORD VBoxDispIfResizeStarted(PCVBOXDISPIF const pIf)
    15441852{
    15451853    switch (pIf->enmMode)
    15461854    {
    15471855        case VBOXDISPIF_MODE_XPDM_NT4:
    1548             return ERROR_NOT_SUPPORTED;
     1856            return NO_ERROR;
    15491857        case VBOXDISPIF_MODE_XPDM:
    1550             return ERROR_NOT_SUPPORTED;
     1858            return NO_ERROR;
    15511859#ifdef VBOX_WITH_WDDM
    15521860        case VBOXDISPIF_MODE_WDDM:
    1553             return vboxDispIfReninitModesWDDM(pIf, pScreenIdMask, fReconnectDisplaysOnChange);
     1861        case VBOXDISPIF_MODE_WDDM_W7:
     1862            return vboxDispIfResizeStartedWDDM(pIf);
    15541863#endif
    15551864        default:
    1556             Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));
     1865            WARN((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));
    15571866            return ERROR_INVALID_PARAMETER;
    15581867    }
     
    15831892            if (!bSupported)
    15841893            {
    1585                 Log((__FUNCTION__": pfnChangeDisplaySettingsEx function pointer failed to initialize\n"));
     1894                WARN((__FUNCTION__": pfnChangeDisplaySettingsEx function pointer failed to initialize\n"));
    15861895                err = ERROR_NOT_SUPPORTED;
    15871896            }
     
    15891898        else
    15901899        {
    1591             Log((__FUNCTION__": failed to get user32 handle, err (%d)\n", GetLastError()));
     1900            WARN((__FUNCTION__": failed to get USER32 handle, err (%d)\n", GetLastError()));
    15921901            err = ERROR_NOT_SUPPORTED;
    15931902        }
     
    15951904    else
    15961905    {
    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"));
    15981907        err = ERROR_NOT_SUPPORTED;
    15991908    }
     
    16131922
    16141923#ifdef VBOX_WITH_WDDM
    1615     if (pIf->enmMode == VBOXDISPIF_MODE_WDDM)
     1924    if (pIf->enmMode >= VBOXDISPIF_MODE_WDDM)
    16161925    {
    16171926        vboxDispIfWddmTerm(pIf);
     1927
     1928        vboxDispKmtCallbacksTerm(&pIf->modeData.wddm.KmtCallbacks);
    16181929    }
    16191930#endif
     
    16311942            }
    16321943            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));
    16341945            break;
    16351946        case VBOXDISPIF_MODE_XPDM:
     
    16421953            }
    16431954            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));
    16451956            break;
    16461957#ifdef VBOX_WITH_WDDM
     
    16551966            }
    16561967            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));
    16581982            break;
    16591983        }
     
    16651989    return err;
    16661990}
     1991
     1992static 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
     2018static 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
     2027static 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
     2046DWORD 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
     2067DWORD 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
     2095DWORD 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  
    1919# define D3DKMDT_SPECIAL_MULTIPLATFORM_TOOL
    2020# include <d3dkmthk.h>
     21# include "../Graphics/Video/disp/wddm/VBoxDispKmt.h"
    2122#endif
    2223
     
    3031#ifdef VBOX_WITH_WDDM
    3132    , VBOXDISPIF_MODE_WDDM
     33    , VBOXDISPIF_MODE_WDDM_W7
    3234#endif
    3335} VBOXDISPIF_MODE;
     
    5961            BOOL (WINAPI * pfnEnumDisplayDevices)(IN LPCSTR lpDevice, IN DWORD iDevNum, OUT PDISPLAY_DEVICEA lpDisplayDevice, IN DWORD dwFlags);
    6062
    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;
    7164        } wddm;
    7265#endif
     
    8477DWORD VBoxDispIfEscape(PCVBOXDISPIF const pIf, PVBOXDISPIFESCAPE pEscape, int cbData);
    8578DWORD 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);
     79DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes);
    8880DWORD 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
     82DWORD VBoxDispIfResizeStarted(PCVBOXDISPIF const pIf);
     83
     84
     85typedef 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
     102DECLINLINE(bool) VBoxDispIfSeamlesIsValid(VBOXDISPIF_SEAMLESS *pSeamless)
     103{
     104    return !!pSeamless->pIf;
     105}
     106
     107DWORD VBoxDispIfSeamlesCreate(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent);
     108DWORD VBoxDispIfSeamlesTerm(VBOXDISPIF_SEAMLESS *pSeamless);
     109DWORD VBoxDispIfSeamlesSubmit(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData);
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp

    r48030 r48070  
    9090                Log(("VBoxTray: VBoxDisplayInit: WDDM driver is installed, switching display driver if to WDDM mode\n"));
    9191                /* 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 */);
    9394                if (err == NO_ERROR)
    9495                    Log(("VBoxTray: VBoxDisplayInit: DispIf switched to WDDM mode successfully\n"));
     
    213214}
    214215
    215 static DWORD 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)
     216DWORD 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)
    217218{
    218219    DISPLAY_DEVICE displayDeviceTmp;
     
    307308    }
    308309    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
     312DWORD VBoxGetDisplayConfigCount()
    315313{
    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 
    328314    DISPLAY_DEVICE DisplayDevice;
    329     DWORD dwStatus;
    330315
    331316    ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));
    332317    DisplayDevice.cb = sizeof(DISPLAY_DEVICE);
    333 
    334     VBoxDispIfCancelPendingResize(&pCtx->pEnv->dispIf);
    335318
    336319    /* Find out how many display devices the system has */
     
    358341    }
    359342
    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
     346DWORD VBoxGetDisplayConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes)
     347{
    372348    /* Fetch information about current devices and modes. */
    373349    DWORD DevNum = 0;
    374350    DWORD DevPrimaryNum = 0;
    375351
     352    DISPLAY_DEVICE DisplayDevice;
     353
    376354    ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));
    377355    DisplayDevice.cb = sizeof(DISPLAY_DEVICE);
    378356
    379     i = 0;
     357    DWORD i = 0;
    380358    while (EnumDisplayDevices (NULL, i, &DisplayDevice, 0))
    381359    {
     
    401379            if (DevNum >= NumDevices)
    402380            {
    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;
    405383            }
    406384
     
    438416            }
    439417
    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
    486419            DevNum++;
    487420        }
     
    491424        i++;
    492425    }
     426
     427    *pNumDevices = DevNum;
     428
     429    return NO_ERROR;
     430}
     431
     432/* Returns TRUE to try again. */
     433static 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
    493502    /* Keep a record if the display with ID is already active or not. */
    494503    if (paDisplayDevices[Id].StateFlags & DISPLAY_DEVICE_ACTIVE)
     
    504513     */
    505514    if (Width == 0)
    506     {
    507515        Width = paRects[Id].right - paRects[Id].left;
    508     }
     516    else
     517        dmFields |= DM_PELSWIDTH;
    509518
    510519    if (Height == 0)
    511     {
    512520        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;
    514537
    515538    /* Check whether a mode reset or a change is requested.
     
    529552     * all rect conditions are true. Thus in this case nothing has to be done.
    530553     */
    531     if ( !fModeReset && fEnabled && fDispAlreadyEnabled && !fChangePosRequest
     554    if ( !fModeReset && (!fEnabled == !fDispAlreadyEnabled)
     555        && paRects[Id].left == dwNewPosX
     556        && paRects[Id].top == dwNewPosY
    532557        && paRects[Id].right - paRects[Id].left == Width
    533558        && paRects[Id].bottom - paRects[Id].top == Height
     
    538563    }
    539564
    540     hlpResizeRect(paRects, NumDevices, DevPrimaryNum, Id, Width, Height);
     565    hlpResizeRect(paRects, NumDevices, DevPrimaryNum, Id,
     566            fEnabled ? Width : 0, fEnabled ? Height : 0, dwNewPosX, dwNewPosY);
    541567#ifdef Log
    542568    for (i = 0; i < NumDevices; i++)
     
    561587            paDeviceModes[i].dmPelsHeight = paRects[i].bottom - paRects[i].top;
    562588
     589            if (i == Id)
     590                paDeviceModes[i].dmBitsPerPel = BitsPerPixel;
     591
     592            paDeviceModes[i].dmFields |= dmFields;
     593
    563594            /* On Vista one must specify DM_BITSPERPEL.
    564595             * Note that the current mode dmBitsPerPel is already in the DEVMODE structure.
    565596             */
    566             paDeviceModes[i].dmFields = DM_PELSHEIGHT | DM_PELSWIDTH | DM_BITSPERPEL;
    567 
    568             if (i == Id && BitsPerPixel != 0)
     597            if (!(paDeviceModes[i].dmFields & DM_BITSPERPEL))
    569598            {
    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;
    586602            }
    587603
     
    593609                  paDeviceModes[i].dmPosition.x,
    594610                  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
    644624        Log(("VBoxTray: ResizeDisplayDevice: (WDDM) RETRY requested\n"));
    645625        return TRUE;
     
    695675         Id, Width, Height, dwNewPosX, dwNewPosY, fEnabled, fExtDispSup));
    696676    dwStatus = EnableAndResizeDispDev(paDeviceModes, paDisplayDevices, DevNum, Id, Width, Height, BitsPerPixel,
    697                                       dwNewPosX, dwNewPosY, fEnabled, fExtDispSup, pCtx);
     677                                      dwNewPosX, dwNewPosY, fEnabled, fExtDispSup);
    698678    if (dwStatus == DISP_CHANGE_SUCCESSFUL || dwStatus == DISP_CHANGE_BADMODE)
    699679    {
     
    730710
    731711    PostMessage(ghwndToolWindow, WM_VBOX_GRAPHICS_SUPPORTED, 0, 0);
     712
     713    VBoxDispIfResizeStarted(&pCtx->pEnv->dispIf);
    732714
    733715    do
     
    979961            if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED)
    980962                hlpReloadCursor();
    981         } else
     963        }
     964        else
    982965        {
    983966            Log(("VBoxTray: VBoxDisplayThread: error 0 from DeviceIoControl VBOXGUEST_IOCTL_WAITEVENT\n"));
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.h

    r44528 r48070  
    2323void               VBoxDisplayDestroy (const VBOXSERVICEENV *pEnv, void *pInstance);
    2424
     25DWORD VBoxGetDisplayConfigCount();
     26DWORD VBoxGetDisplayConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes);
     27
    2528#ifndef VBOX_WITH_WDDM
    2629static bool isVBoxDisplayDriverActive (void);
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHelpers.cpp

    r35907 r48070  
    112112
    113113void 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)
    115116{
    116117    DDCLOG(("nRects %d, iPrimary %d, iResized %d, NewWidth %d, NewHeight %d\n", nRects, uPrimary, uResized, iNewWidth, iNewHeight));
     
    120121    paNewRects[uResized].right += iNewWidth - (paNewRects[uResized].right - paNewRects[uResized].left);
    121122    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;
    122127
    123128    /* Verify all pairs of originally adjacent rectangles for all 4 directions.
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHelpers.h

    r44528 r48070  
    2929extern int hlpReportStatus(VBoxGuestFacilityStatus statusCurrent);
    3030extern void hlpReloadCursor(void);
    31 extern void hlpResizeRect(RECTL *paRects, unsigned nRects, unsigned uPrimary, unsigned uResized, int iNewWidth, int iNewHeight);
     31extern void hlpResizeRect(RECTL *paRects, unsigned nRects, unsigned uPrimary, unsigned uResized, int iNewWidth, int iNewHeight, int iNewPosX, int iNewPosY);
    3232extern int hlpShowBalloonTip(HINSTANCE hInst, HWND hWnd, UINT uID, const char *pszMsg, const char *pszTitle, UINT uTimeout, DWORD dwInfoFlags);
    3333
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxSeamless.cpp

    r46593 r48070  
    116116}
    117117
    118 void VBoxSeamlessInstallHook()
     118static void VBoxSeamlessInstallHook()
    119119{
    120120    if (gCtx.pfnVBoxHookInstallWindowTracker)
    121121    {
    122122        /* Check current visible region state */
    123         VBoxSeamlessCheckWindows();
     123        VBoxSeamlessCheckWindows(true);
    124124
    125125        HMODULE hMod = (HMODULE)RTLdrGetNativeHandle(gCtx.hModHook);
     
    129129}
    130130
    131 void VBoxSeamlessRemoveHook()
     131static void VBoxSeamlessRemoveHook()
    132132{
    133133    if (gCtx.pfnVBoxHookRemoveWindowTracker)
     
    139139        gCtx.lpEscapeData = NULL;
    140140    }
     141}
     142
     143extern HANDLE ghSeamlessKmNotifyEvent;
     144
     145static VBOXDISPIF_SEAMLESS gVBoxDispIfSeamless;
     146
     147
     148void VBoxSeamlessEnable()
     149{
     150    Assert(ghSeamlessKmNotifyEvent);
     151
     152    VBoxDispIfSeamlesCreate(&gCtx.pEnv->dispIf, &gVBoxDispIfSeamless, ghSeamlessKmNotifyEvent);
     153
     154    VBoxSeamlessInstallHook();
     155}
     156
     157void VBoxSeamlessDisable()
     158{
     159    VBoxSeamlessRemoveHook();
     160
     161    VBoxDispIfSeamlesTerm(&gVBoxDispIfSeamless);
    141162}
    142163
     
    245266}
    246267
    247 void VBoxSeamlessCheckWindows()
    248 {
     268void VBoxSeamlessCheckWindows(bool fForce)
     269{
     270    if (!VBoxDispIfSeamlesIsValid(&gVBoxDispIfSeamless))
     271        return;
     272
    249273    VBOX_ENUM_PARAM param;
    250274
     
    280304#endif
    281305                    LPRGNDATA lpCtxRgnData = VBOXDISPIFESCAPE_DATA(gCtx.lpEscapeData, RGNDATA);
    282                     if (    !gCtx.lpEscapeData
     306                    if (fForce
     307                        ||  !gCtx.lpEscapeData
    283308                        ||  (lpCtxRgnData->rdh.dwSize + lpCtxRgnData->rdh.nRgnSize != cbSize)
    284309                        ||  memcmp(lpCtxRgnData, lpRgnData, cbSize))
    285310                    {
    286311                        /* send to display driver */
    287                         VBoxDispIfEscape(&gCtx.pEnv->dispIf, lpEscapeData, cbSize);
     312                        VBoxDispIfSeamlesSubmit(&gVBoxDispIfSeamless, lpEscapeData, cbSize);
    288313
    289314                        if (gCtx.lpEscapeData)
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxSeamless.h

    r45760 r48070  
    2424
    2525
    26 void VBoxSeamlessInstallHook();
    27 void VBoxSeamlessRemoveHook();
    28 void VBoxSeamlessCheckWindows();
     26void VBoxSeamlessEnable();
     27void VBoxSeamlessDisable();
     28void VBoxSeamlessCheckWindows(bool fForce);
    2929
    3030void VBoxSeamlessSetSupported(BOOL fSupported);
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp

    r47195 r48070  
    4646#include <Wtsapi32.h>
    4747
    48 #ifdef DEBUG_misha
    49 #define WARN(_m) do { \
    50             Assert(0); \
    51             Log(_m); \
    52         } while (0)
    53 #else
    54 #define WARN(_m) do { \
    55             Log(_m); \
    56         } while (0)
    57 #endif
    58 
    5948/*
    6049 * St (session [state] tracking) functionality API
     
    136125HANDLE                ghStopSem;
    137126HANDLE                ghSeamlessWtNotifyEvent = 0;
     127HANDLE                ghSeamlessKmNotifyEvent = 0;
    138128SERVICE_STATUS        gVBoxServiceStatus;
    139129SERVICE_STATUS_HANDLE gVBoxServiceStatusHandle;
     
    629619                Log(("VBoxTray: CreateEvent for Seamless failed, last error = %08X\n", dwErr));
    630620            }
     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            }
    631628        }
    632629    }
     
    640637        CloseHandle(ghSeamlessWtNotifyEvent);
    641638        ghSeamlessWtNotifyEvent = NULL;
     639    }
     640
     641    if (ghSeamlessKmNotifyEvent)
     642    {
     643        CloseHandle(ghSeamlessKmNotifyEvent);
     644        ghSeamlessKmNotifyEvent = NULL;
    642645    }
    643646}
     
    725728                 */
    726729
    727                 HANDLE hWaitEvent[3] = {0};
     730                HANDLE hWaitEvent[4] = {0};
    728731                DWORD dwEventCount = 0;
    729732
     
    734737                {
    735738                    hWaitEvent[dwEventCount++] = ghSeamlessWtNotifyEvent;
     739                }
     740
     741                if (0 != ghSeamlessKmNotifyEvent)
     742                {
     743                    hWaitEvent[dwEventCount++] = ghSeamlessKmNotifyEvent;
    736744                }
    737745
     
    768776
    769777                                    /* 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);
    771787                                    fHandled = TRUE;
    772788                                }
     
    9881004        case WM_VBOX_SEAMLESS_UPDATE:
    9891005            if (VBoxCapsEntryIsEnabled(VBOXCAPS_ENTRY_IDX_SEAMLESS))
    990                 VBoxSeamlessCheckWindows();
     1006                VBoxSeamlessCheckWindows(true);
    9911007            return 0;
    9921008
     
    12971313    if (GetVersionEx(&info))
    12981314    {
    1299         WARN(("VBoxTray: Windows version %ld.%ld\n", info.dwMajorVersion, info.dwMinorVersion));
     1315        LogRel(("VBoxTray: Windows version %ld.%ld\n", info.dwMajorVersion, info.dwMinorVersion));
    13001316        gMajorVersion = info.dwMajorVersion;
    13011317    }
     
    15071523        Assert(pCap->enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED);
    15081524        Assert(pCap->enmFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED);
    1509         VBoxSeamlessInstallHook();
     1525        VBoxSeamlessEnable();
    15101526    }
    15111527    else
     
    15131529        Log(("VBoxTray: vboxCapsOnEnableSeamles: DISABLED\n"));
    15141530        Assert(pCap->enmAcState != VBOXCAPS_ENTRY_ACSTATE_ACQUIRED || pCap->enmFuncState != VBOXCAPS_ENTRY_FUNCSTATE_STARTED);
    1515         VBoxSeamlessRemoveHook();
     1531        VBoxSeamlessDisable();
    15161532    }
    15171533}
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.h

    r47195 r48070  
    5454
    5555#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
    5667
    5768/*
  • trunk/src/VBox/Additions/WINNT/include/VBoxDisplay.h

    r46966 r48070  
    3838# define VBOXESC_ADJUSTVIDEOMODES           0xABCD9011
    3939# define VBOXESC_SETCTXHOSTID               0xABCD9012
     40# define VBOXESC_CONFIGURETARGETS           0xABCD9013
    4041#endif /* #ifdef VBOX_WITH_WDDM */
    4142
  • trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp

    r44876 r48070  
    15071507                }
    15081508
    1509                 if (   pView->u32VBVAOffset == HGSMIOFFSET_VOID
    1510                     || pView->screen.u32LineSize == 0) /* Earlier broken saved states. */
     1509                if (pView->u32VBVAOffset == HGSMIOFFSET_VOID)
    15111510                {
    15121511                    pView->pVBVA = NULL;
     
    18451844            int64_t offEnd =   (int64_t)pScreen->u32Height * pScreen->u32LineSize
    18461845                             + pScreen->u32Width + pScreen->u32StartOffset;
    1847             LogRelFlowFunc(("VBVA_INFO_SCREEN: [%d] @%d,%d %dx%d, line 0x%x, BPP %d, flags 0x%x\n",
     1846            LogRel(("VBVA_INFO_SCREEN: [%d] @%d,%d %dx%d, line 0x%x, BPP %d, flags 0x%x\n",
    18481847                            pScreen->u32ViewIndex, pScreen->i32OriginX, pScreen->i32OriginY,
    18491848                            pScreen->u32Width, pScreen->u32Height,
  • trunk/src/VBox/Devices/VMMDev/VMMDev.cpp

    r47450 r48070  
    29932993    if (!fSameResolution)
    29942994    {
    2995         LogRel(("VMMDev::SetVideoModeHint: got a video mode hint (%dx%dx%d) at %d\n", cx, cy, cBits, idxDisplay));
     2995        LogRel(("VMMDev::SetVideoModeHint: got a video mode hint (%dx%dx%d)@(%dx%d),(%d;%d) at %d\n",
     2996                cx, cy, cBits, xOrigin, yOrigin, fEnabled, fChangeOrigin, idxDisplay));
    29962997
    29972998        /* we could validate the information here but hey, the guest can do that as well! */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette