VirtualBox

Changeset 84452 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 22, 2020 11:34:53 AM (5 years ago)
Author:
vboxsync
Message:

VBoxTray: changed multiple screens resizing code to follow MSDN docs and deal with complex topologies.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDispIf.cpp

    r84382 r84452  
    302302        {
    303303            return (int)iter;
     304        }
     305    }
     306    return -1;
     307}
     308
     309static int vboxDispIfWddmDcSearchActiveSourcePath(VBOXDISPIF_WDDM_DISPCFG *pCfg, UINT srcId)
     310{
     311    for (UINT i = 0; i < pCfg->cPathInfoArray; ++i)
     312    {
     313        if (   pCfg->pPathInfoArray[i].sourceInfo.id == srcId
     314            && RT_BOOL(pCfg->pPathInfoArray[i].flags & DISPLAYCONFIG_PATH_ACTIVE))
     315        {
     316            return (int)i;
    304317        }
    305318    }
     
    18031816        pDispDef = &paDispDef[i];
    18041817
    1805         DISPLAYCONFIG_PATH_INFO *pPathInfo;
    1806         int iPath = vboxDispIfWddmDcSearchPath(&DispCfg, pDispDef->idDisplay, pDispDef->idDisplay);
     1818        /* Modify the path which the same source and target ids. */
     1819        int const iPath = vboxDispIfWddmDcSearchPath(&DispCfg, pDispDef->idDisplay, pDispDef->idDisplay);
    18071820        if (iPath < 0)
    18081821        {
     
    18111824        }
    18121825
     1826        /* If the source is used by another active path, then deactivate the path. */
     1827        int const iActiveSrcPath = vboxDispIfWddmDcSearchActiveSourcePath(&DispCfg, pDispDef->idDisplay);
     1828        if (iActiveSrcPath >= 0 && iActiveSrcPath != iPath)
     1829            DispCfg.pPathInfoArray[iActiveSrcPath].flags &= ~DISPLAYCONFIG_PATH_ACTIVE;
     1830
     1831        DISPLAYCONFIG_PATH_INFO *pPathInfo = &DispCfg.pPathInfoArray[iPath];
     1832
    18131833        if (!(pDispDef->fDisplayFlags & VMMDEV_DISPLAY_DISABLED))
    18141834        {
     
    18161836            DISPLAYCONFIG_TARGET_MODE *pTgtMode;
    18171837
    1818             pPathInfo = &DispCfg.pPathInfoArray[iPath];
    1819 
    18201838            if (pPathInfo->flags & DISPLAYCONFIG_PATH_ACTIVE)
    18211839            {
    1822                 UINT iSrcMode, iTgtMode;
    1823 
    1824                 iSrcMode = pPathInfo->sourceInfo.modeInfoIdx;
    1825                 iTgtMode = pPathInfo->targetInfo.modeInfoIdx;
     1840                UINT iSrcMode = pPathInfo->sourceInfo.modeInfoIdx;
     1841                UINT iTgtMode = pPathInfo->targetInfo.modeInfoIdx;
    18261842
    18271843                if (iSrcMode >= DispCfg.cModeInfoArray || iTgtMode >= DispCfg.cModeInfoArray)
     
    18371853                {
    18381854                    pSrcMode->width =
    1839                         pTgtMode->targetVideoSignalInfo.activeSize.cx =
    1840                         pTgtMode->targetVideoSignalInfo.totalSize.cx = pDispDef->cx;
     1855                    pTgtMode->targetVideoSignalInfo.activeSize.cx =
     1856                    pTgtMode->targetVideoSignalInfo.totalSize.cx = pDispDef->cx;
    18411857                }
    18421858
     
    18441860                {
    18451861                    pSrcMode->height =
    1846                         pTgtMode->targetVideoSignalInfo.activeSize.cy =
    1847                         pTgtMode->targetVideoSignalInfo.totalSize.cy = pDispDef->cy;
     1862                    pTgtMode->targetVideoSignalInfo.activeSize.cy =
     1863                    pTgtMode->targetVideoSignalInfo.totalSize.cy = pDispDef->cy;
    18481864                }
    18491865
     
    18711887                        break;
    18721888                    default:
    1873                         LogRel(("VBoxTray: (WDDM) invalid bpp %d, using 32bpp instead\n", pDispDef->cBitsPerPixel));
     1889                        WARN(("VBoxTray: (WDDM) invalid bpp %d, using 32bpp instead\n", pDispDef->cBitsPerPixel));
    18741890                        pSrcMode->pixelFormat = DISPLAYCONFIG_PIXELFORMAT_32BPP;
    18751891                        break;
     
    18791895            else
    18801896            {
    1881                 DISPLAYCONFIG_MODE_INFO *pModeInfo, *pModeInfoNew;
    1882 
    1883                 pModeInfo = (DISPLAYCONFIG_MODE_INFO *)realloc(DispCfg.pModeInfoArray, (DispCfg.cModeInfoArray + 2) * sizeof(DISPLAYCONFIG_MODE_INFO));
    1884 
    1885                 if (!pModeInfo)
     1897                /* "The source and target modes for each source and target identifiers can only appear
     1898                 * in the modeInfoArray array once."
     1899                 * Try to find the source mode.
     1900                 */
     1901                DISPLAYCONFIG_MODE_INFO *pSrcModeInfo = NULL;
     1902                int iSrcModeInfo = -1;
     1903                for (UINT j = 0; j < DispCfg.cModeInfoArray; ++j)
    18861904                {
    1887                     WARN(("VBoxTray:(WDDM) Unable to re-allocate DispCfg.pModeInfoArray\n"));
    1888                     continue;
     1905                    if (   DispCfg.pModeInfoArray[j].infoType == DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE
     1906                        && DispCfg.pModeInfoArray[j].id == pDispDef->idDisplay)
     1907                    {
     1908                        pSrcModeInfo = &DispCfg.pModeInfoArray[j];
     1909                        iSrcModeInfo = (int)j;
     1910                        break;
     1911                    }
    18891912                }
    18901913
    1891                 DispCfg.pModeInfoArray = pModeInfo;
    1892 
    1893                 *pPathInfo = DispCfg.pPathInfoArray[0];
    1894                 pPathInfo->sourceInfo.id = pDispDef->idDisplay;
    1895                 pPathInfo->targetInfo.id = pDispDef->idDisplay;
    1896 
    1897                 pModeInfoNew = &pModeInfo[DispCfg.cModeInfoArray];
    1898                 pModeInfoNew->infoType = DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE;
    1899                 pModeInfoNew->id = pDispDef->idDisplay;
    1900                 pModeInfoNew->adapterId = pModeInfo[0].adapterId;
    1901                 pSrcMode = &pModeInfoNew->sourceMode;
    1902                 pSrcMode->width  = pDispDef->cx;
    1903                 pSrcMode->height = pDispDef->cy;
    1904                 pSrcMode->pixelFormat = DISPLAYCONFIG_PIXELFORMAT_32BPP;
    1905                 pSrcMode->position.x = pDispDef->xOrigin;
    1906                 pSrcMode->position.y = pDispDef->yOrigin;
    1907                 pPathInfo->sourceInfo.modeInfoIdx = DispCfg.cModeInfoArray;
    1908 
    1909                 pModeInfoNew++;
    1910                 pModeInfoNew->infoType = DISPLAYCONFIG_MODE_INFO_TYPE_TARGET;
    1911                 pModeInfoNew->id = pDispDef->idDisplay;
    1912                 pModeInfoNew->adapterId = pModeInfo[0].adapterId;
    1913                 pModeInfoNew->targetMode = pModeInfo[0].targetMode;
    1914                 pTgtMode = &pModeInfoNew->targetMode;
    1915                 pTgtMode->targetVideoSignalInfo.activeSize.cx =
    1916                     pTgtMode->targetVideoSignalInfo.totalSize.cx = pDispDef->cx;
    1917                 pTgtMode->targetVideoSignalInfo.activeSize.cy =
    1918                     pTgtMode->targetVideoSignalInfo.totalSize.cy  = pDispDef->cy;
    1919                 pPathInfo->targetInfo.modeInfoIdx = DispCfg.cModeInfoArray + 1;
    1920 
    1921                 DispCfg.cModeInfoArray += 2;
    1922             }
     1914                if (pSrcModeInfo == NULL)
     1915                {
     1916                    /* No mode yet. Add the new mode to the ModeInfo array. */
     1917                    DISPLAYCONFIG_MODE_INFO *paModeInfo = (DISPLAYCONFIG_MODE_INFO *)realloc(DispCfg.pModeInfoArray, (DispCfg.cModeInfoArray + 1) * sizeof(DISPLAYCONFIG_MODE_INFO));
     1918                    if (!paModeInfo)
     1919                    {
     1920                        WARN(("VBoxTray:(WDDM) Unable to re-allocate DispCfg.pModeInfoArray\n"));
     1921                        continue;
     1922                    }
     1923
     1924                    DispCfg.pModeInfoArray = paModeInfo;
     1925                    DispCfg.cModeInfoArray += 1;
     1926
     1927                    iSrcModeInfo = DispCfg.cModeInfoArray - 1;
     1928                    pSrcModeInfo = &DispCfg.pModeInfoArray[iSrcModeInfo];
     1929                    RT_ZERO(*pSrcModeInfo);
     1930
     1931                    pSrcModeInfo->infoType  = DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE;
     1932                    pSrcModeInfo->id        = pDispDef->idDisplay;
     1933                    pSrcModeInfo->adapterId = DispCfg.pModeInfoArray[0].adapterId;
     1934                }
     1935
     1936                /* Update the source mode information. */
     1937                if (pDispDef->fDisplayFlags & VMMDEV_DISPLAY_CX)
     1938                {
     1939                    pSrcModeInfo->sourceMode.width = pDispDef->cx;
     1940                }
     1941
     1942                if (pDispDef->fDisplayFlags & VMMDEV_DISPLAY_CY)
     1943                {
     1944                    pSrcModeInfo->sourceMode.height = pDispDef->cy;
     1945                }
     1946
     1947                if (pDispDef->fDisplayFlags & VMMDEV_DISPLAY_BPP)
     1948                {
     1949                    switch (pDispDef->cBitsPerPixel)
     1950                    {
     1951                        case 32:
     1952                            pSrcModeInfo->sourceMode.pixelFormat = DISPLAYCONFIG_PIXELFORMAT_32BPP;
     1953                            break;
     1954                        case 24:
     1955                            pSrcModeInfo->sourceMode.pixelFormat = DISPLAYCONFIG_PIXELFORMAT_24BPP;
     1956                            break;
     1957                        case 16:
     1958                            pSrcModeInfo->sourceMode.pixelFormat = DISPLAYCONFIG_PIXELFORMAT_16BPP;
     1959                            break;
     1960                        case 8:
     1961                            pSrcModeInfo->sourceMode.pixelFormat = DISPLAYCONFIG_PIXELFORMAT_8BPP;
     1962                            break;
     1963                        default:
     1964                            WARN(("VBoxTray: (WDDM) invalid bpp %d, using 32bpp instead\n", pDispDef->cBitsPerPixel));
     1965                            pSrcModeInfo->sourceMode.pixelFormat = DISPLAYCONFIG_PIXELFORMAT_32BPP;
     1966                            break;
     1967                    }
     1968                }
     1969
     1970                if (pDispDef->fDisplayFlags & VMMDEV_DISPLAY_ORIGIN)
     1971                {
     1972                    pSrcModeInfo->sourceMode.position.x = pDispDef->xOrigin;
     1973                    pSrcModeInfo->sourceMode.position.y = pDispDef->yOrigin;
     1974                }
     1975
     1976                /* Configure the path information. */
     1977                Assert(pPathInfo->sourceInfo.id == pDispDef->idDisplay);
     1978                pPathInfo->sourceInfo.modeInfoIdx = iSrcModeInfo;
     1979
     1980                Assert(pPathInfo->targetInfo.id == pDispDef->idDisplay);
     1981                /* "If the index value is DISPLAYCONFIG_PATH_MODE_IDX_INVALID ..., this indicates
     1982                 * the mode information is not being specified. It is valid for the path plus source mode ...
     1983                 * information to be specified for a given path."
     1984                 */
     1985                pPathInfo->targetInfo.modeInfoIdx      = DISPLAYCONFIG_PATH_MODE_IDX_INVALID;
     1986                pPathInfo->targetInfo.outputTechnology = DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15;
     1987                pPathInfo->targetInfo.rotation         = DISPLAYCONFIG_ROTATION_IDENTITY;
     1988                pPathInfo->targetInfo.scaling          = DISPLAYCONFIG_SCALING_PREFERRED;
     1989                /* "A refresh rate with both the numerator and denominator set to zero indicates that
     1990                 * the caller does not specify a refresh rate and the operating system should use
     1991                 * the most optimal refresh rate available. For this case, in a call to the SetDisplayConfig
     1992                 * function, the caller must set the scanLineOrdering member to the
     1993                 * DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED value; otherwise, SetDisplayConfig fails."
     1994                 *
     1995                 * If a refresh rate is set to a value, then the resize will fail if miniport driver
     1996                 * does not support VSync, i.e. with display-only driver on Win8+ (@bugref{8440}).
     1997                 */
     1998                pPathInfo->targetInfo.refreshRate.Numerator   = 0;
     1999                pPathInfo->targetInfo.refreshRate.Denominator = 0;
     2000                pPathInfo->targetInfo.scanLineOrdering        = DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED;
     2001                /* Make sure that "The output can be forced on this target even if a monitor is not detected." */
     2002                pPathInfo->targetInfo.targetAvailable         = TRUE;
     2003                pPathInfo->targetInfo.statusFlags             = DISPLAYCONFIG_TARGET_FORCIBLE;
     2004            }
     2005
     2006            pPathInfo->flags |= DISPLAYCONFIG_PATH_ACTIVE;
    19232007        }
    19242008        else
    19252009        {
    1926                 DispCfg.pPathInfoArray[iPath].flags &= ~DISPLAYCONFIG_PATH_ACTIVE;
     2010            pPathInfo->flags &= ~DISPLAYCONFIG_PATH_ACTIVE;
    19272011        }
    19282012    }
Note: See TracChangeset for help on using the changeset viewer.

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