VirtualBox

Ignore:
Timestamp:
Mar 8, 2010 1:19:29 PM (15 years ago)
Author:
vboxsync
Message:

Windows guest additions multimonitor fixes (xTracker 4655).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp

    r26923 r27164  
    4949 * custom resolution and Windows can use it again.
    5050 */
     51#ifndef VBOX_WITH_MULTIMONITOR_FIX
    5152ULONG gCustomXRes = 0;
    5253ULONG gCustomYRes = 0;
    5354ULONG gCustomBPP  = 0;
     55#endif /* !VBOX_WITH_MULTIMONITOR_FIX */
    5456
    5557int vboxVbvaEnable (PDEVICE_EXTENSION pDevExt, ULONG ulEnable, VBVAENABLERESULT *pVbvaResult);
     
    166168 */
    167169#define MAX_VIDEO_MODES 128
     170#ifndef VBOX_WITH_MULTIMONITOR_FIX
    168171static VIDEO_MODE_INFORMATION VideoModes[MAX_VIDEO_MODES + 2] = { 0 };
     172#else
     173/*
     174 * Additional space is reserved for custom video modes for 64 guest monitors.
     175 * The custom video mode index is alternating and 2 indexes are reserved for the last custom mode.
     176 */
     177static VIDEO_MODE_INFORMATION VideoModes[MAX_VIDEO_MODES + 64 + 2] = { 0 };
     178/* On the driver startup this is initialized from registry (replaces gCustom*). */
     179static VIDEO_MODE_INFORMATION CustomVideoModes[64] = { 0 };
     180#endif /* VBOX_WITH_MULTIMONITOR_FIX */
    169181/* number of available video modes, set by VBoxBuildModesTable  */
    170182static uint32_t gNumVideoModes = 0;
     183
     184#ifdef VBOX_WITH_MULTIMONITOR_FIX
     185static void initVideoModeInformation(VIDEO_MODE_INFORMATION *pVideoMode, ULONG xres, ULONG yres, ULONG bpp, ULONG index, ULONG yoffset)
     186{
     187    /*
     188     * Build mode entry.
     189     */
     190    memset(pVideoMode, 0, sizeof(VIDEO_MODE_INFORMATION));
     191
     192    pVideoMode->Length                       = sizeof(VIDEO_MODE_INFORMATION);
     193    pVideoMode->ModeIndex                    = index;
     194    pVideoMode->VisScreenWidth               = xres;
     195    pVideoMode->VisScreenHeight              = yres - yoffset;
     196    pVideoMode->ScreenStride                 = xres * ((bpp + 7) / 8);
     197    pVideoMode->NumberOfPlanes               = 1;
     198    pVideoMode->BitsPerPlane                 = bpp;
     199    pVideoMode->Frequency                    = 60;
     200    pVideoMode->XMillimeter                  = 320;
     201    pVideoMode->YMillimeter                  = 240;
     202    switch (bpp)
     203    {
     204#ifdef VBOX_WITH_8BPP_MODES
     205        case 8:
     206            pVideoMode->NumberRedBits        = 6;
     207            pVideoMode->NumberGreenBits      = 6;
     208            pVideoMode->NumberBlueBits       = 6;
     209            pVideoMode->RedMask              = 0;
     210            pVideoMode->GreenMask            = 0;
     211            pVideoMode->BlueMask             = 0;
     212            break;
     213#endif
     214        case 16:
     215            pVideoMode->NumberRedBits        = 5;
     216            pVideoMode->NumberGreenBits      = 6;
     217            pVideoMode->NumberBlueBits       = 5;
     218            pVideoMode->RedMask              = 0xF800;
     219            pVideoMode->GreenMask            = 0x7E0;
     220            pVideoMode->BlueMask             = 0x1F;
     221            break;
     222        case 24:
     223            pVideoMode->NumberRedBits        = 8;
     224            pVideoMode->NumberGreenBits      = 8;
     225            pVideoMode->NumberBlueBits       = 8;
     226            pVideoMode->RedMask              = 0xFF0000;
     227            pVideoMode->GreenMask            = 0xFF00;
     228            pVideoMode->BlueMask             = 0xFF;
     229            break;
     230        case 32:
     231            pVideoMode->NumberRedBits        = 8;
     232            pVideoMode->NumberGreenBits      = 8;
     233            pVideoMode->NumberBlueBits       = 8;
     234            pVideoMode->RedMask              = 0xFF0000;
     235            pVideoMode->GreenMask            = 0xFF00;
     236            pVideoMode->BlueMask             = 0xFF;
     237            break;
     238    }
     239    pVideoMode->AttributeFlags               = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
     240#ifdef VBOX_WITH_8BPP_MODES
     241    if (bpp == 8)
     242        pVideoMode->AttributeFlags          |= VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
     243#endif
     244    pVideoMode->VideoMemoryBitmapWidth       = xres;
     245    pVideoMode->VideoMemoryBitmapHeight      = yres - yoffset;
     246    pVideoMode->DriverSpecificAttributeFlags = 0;
     247}
     248#endif /* VBOX_WITH_MULTIMONITOR_FIX */
     249
    171250#ifdef VBOXWDDM
    172251/* preferred mode index */
     
    750829     * registry key add it to the modes table.
    751830     */
    752     uint32_t xres = 0, yres = 0, bpp = 0;
    753     if (   (   vboxQueryDisplayRequest(&xres, &yres, &bpp)
     831
     832#ifdef VBOX_WITH_MULTIMONITOR_FIX
     833    /* Add custom resolutions for each display and then for the display change request, if exists.
     834     */
     835    BOOLEAN fDisplayChangeRequest = FALSE;
     836
     837    uint32_t xres = 0, yres = 0, bpp = 0, display = 0;
     838    if (   vboxQueryDisplayRequest(&xres, &yres, &bpp, &display)
     839        && (xres || yres || bpp))
     840    {
     841        /* There is a pending display change request. */
     842        fDisplayChangeRequest = TRUE;
     843    }
     844    if (display > RT_ELEMENTS(CustomVideoModes))
     845    {
     846       display = RT_ELEMENTS(CustomVideoModes) - 1;
     847    }
     848
     849    dprintf(("VBoxVideo: fDisplayChangeRequest = %d\n", fDisplayChangeRequest));
     850
     851    /*
     852     * Reinsert custom video modes for all displays.
     853     */
     854    int iCustomMode;
     855    for (iCustomMode = 0; iCustomMode < DeviceExtension->pPrimary->u.primary.cDisplays; iCustomMode++)
     856    {
     857        if (fDisplayChangeRequest && iCustomMode == display)
     858        {
     859            /* Do not keep info for this display to make sure that
     860             * the new mode will be taken from the alternating index entries actually.
     861             */
     862            memcpy(&VideoModes[gNumVideoModes], &VideoModes[3], sizeof(VIDEO_MODE_INFORMATION));
     863            VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
     864        }
     865        else
     866        {
     867            VideoModes[gNumVideoModes] = CustomVideoModes[iCustomMode];
     868            VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
     869        }
     870#ifdef LOG_ENABLED
     871        dprintf(("Custom mode for %2d: %4d x %4d @ %2d\n",
     872                iCustomMode, CustomVideoModes[iCustomMode].VisScreenWidth,
     873                CustomVideoModes[iCustomMode].VisScreenHeight, CustomVideoModes[iCustomMode].BitsPerPlane));
     874#endif
     875        gNumVideoModes++;
     876    }
     877#endif /* VBOX_WITH_MULTIMONITOR_FIX */
     878
     879   
     880#ifndef VBOX_WITH_MULTIMONITOR_FIX
     881    uint32_t xres = 0, yres = 0, bpp = 0, display = 0;
     882    if (   (   vboxQueryDisplayRequest(&xres, &yres, &bpp, &display)
    754883            && (xres || yres || bpp))
    755884        || (gCustomXRes || gCustomYRes || gCustomBPP))
     885#else
     886    if (fDisplayChangeRequest || DeviceExtension->CurrentMode == 0)
     887#endif /* VBOX_WITH_MULTIMONITOR_FIX */
    756888    {
    757889#ifndef VBOXWDDM
     
    766898             * The custom mode might be not valid anymore and would block any hints from host.
    767899             */
     900#ifndef VBOX_WITH_MULTIMONITOR_FIX
    768901            if (!xres)
    769902                xres = gCustomXRes;
     
    772905            if (!bpp)
    773906                bpp  = gCustomBPP;
     907#else
     908            if (!xres)
     909                xres = CustomVideoModes[display].VisScreenWidth;
     910            if (!yres)
     911                yres = CustomVideoModes[display].VisScreenHeight;
     912            if (!bpp)
     913                bpp  = CustomVideoModes[display].BitsPerPlane;
     914#endif /* VBOX_WITH_MULTIMONITOR_FIX */
    774915            dprintf(("VBoxVideo: using stored custom resolution %dx%dx%d\n", xres, yres, bpp));
    775916        }
     
    821962            {
    822963                /* we need an alternating index */
     964#ifdef VBOX_WITH_MULTIMONITOR_FIX
     965                /* Only alternate index if the new custom mode differs from the last one
     966                 * (only resolution and bpp changes are important, a display change does not matter).
     967                 * Always add 2 last entries to the mode array, so number of video modes
     968                 * do not change.
     969                 */
     970                BOOLEAN fNewInvocation = FALSE;
     971                static sPrev_xres    = 0;
     972                static sPrev_yres    = 0;
     973                static sPrev_bpp     = 0;
     974                if (   sPrev_xres != xres
     975                    || sPrev_yres != yres
     976                    || sPrev_bpp != bpp)
     977                {
     978                    sPrev_xres = xres;
     979                    sPrev_yres = yres;
     980                    sPrev_bpp = bpp;
     981                    fNewInvocation = TRUE;
     982                }
     983                BOOLEAN fAlternatedIndex = FALSE;
     984#endif /* VBOX_WITH_MULTIMONITOR_FIX */
    823985#ifndef VBOXWDDM
    824986                if (DeviceExtension->CurrentMode != 0)
     
    826988                if (DeviceExtension->cSources && DeviceExtension->aSources[0].pAllocation)
    827989#endif
     990#ifndef VBOX_WITH_MULTIMONITOR_FIX
    828991                {
    829992                    if (gInvocationCounter % 2)
     
    831994                    gInvocationCounter++;
    832995                }
    833 
    834                 dprintf(("VBoxVideo: setting special mode to xres = %d, yres = %d, bpp = %d\n", xres, yres, bpp));
     996#else
     997                {
     998                    if (fNewInvocation)
     999                        gInvocationCounter++;
     1000                    if (gInvocationCounter % 2)
     1001                    {
     1002                        fAlternatedIndex = TRUE;
     1003
     1004                        memcpy(&VideoModes[gNumVideoModes], &VideoModes[3], sizeof(VIDEO_MODE_INFORMATION));
     1005                        VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
     1006                        gNumVideoModes++;
     1007                    }
     1008                }
     1009                else
     1010                {
     1011                    fNewInvocation = FALSE;
     1012                }
     1013#endif /* VBOX_WITH_MULTIMONITOR_FIX */
     1014
     1015                dprintf(("VBoxVideo: setting special mode to xres = %d, yres = %d, bpp = %d, display = %d\n", xres, yres, bpp, display));
     1016#ifdef VBOX_WITH_MULTIMONITOR_FIX
     1017                dprintf(("VBoxVideo: fNewInvocation = %d, fAlternatedIndex = %d\n", fNewInvocation, fAlternatedIndex));
     1018#endif /* VBOX_WITH_MULTIMONITOR_FIX */
    8351019#ifdef VBOXWDDM
    8361020                /* assign host-supplied as the most preferable */
     
    8981082                VideoModes[gNumVideoModes].VideoMemoryBitmapHeight      = yres;
    8991083                VideoModes[gNumVideoModes].DriverSpecificAttributeFlags = 0;
     1084#ifdef VBOX_WITH_MULTIMONITOR_FIX
     1085                /* Save the mode in the list of custom modes for this display. */
     1086                CustomVideoModes[display] = VideoModes[gNumVideoModes];
     1087#endif /* VBOX_WITH_MULTIMONITOR_FIX */
    9001088                ++gNumVideoModes;
    9011089
     
    9121100                    gNumVideoModes++;
    9131101                }
    914 
     1102#ifdef VBOX_WITH_MULTIMONITOR_FIX
     1103                else if (!fAlternatedIndex)
     1104                {
     1105                    dprintf(("VBoxVideo: making a copy of the custom mode as #%d\n", gNumVideoModes + 1));
     1106                    memcpy(&VideoModes[gNumVideoModes], &VideoModes[3], sizeof(VIDEO_MODE_INFORMATION));
     1107                    VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
     1108                    gNumVideoModes++;
     1109                }
     1110#endif /* VBOX_WITH_MULTIMONITOR_FIX */
     1111
     1112#ifndef VBOX_WITH_MULTIMONITOR_FIX
    9151113                /* store this video mode as the last custom video mode */
    9161114                status = VBoxVideoCmnRegSetDword(Reg, L"CustomXRes", xres);
     
    9231121                if (status != NO_ERROR)
    9241122                    dprintf(("VBoxVideo: error %d writing CustomBPP\n", status));
     1123#else
     1124                /* Save the custom mode for this display. */
     1125                if (display == 0)
     1126                {
     1127                    /* Name without a suffix */
     1128                    status = VBoxVideoCmnRegSetDword(Reg, L"CustomXRes", xres);
     1129                    if (status != NO_ERROR)
     1130                        dprintf(("VBoxVideo: error %d writing CustomXRes\n", status));
     1131                    status = VBoxVideoCmnRegSetDword(Reg, L"CustomYRes", yres);
     1132                    if (status != NO_ERROR)
     1133                        dprintf(("VBoxVideo: error %d writing CustomYRes\n", status));
     1134                    status = VBoxVideoCmnRegSetDword(Reg, L"CustomBPP", bpp);
     1135                    if (status != NO_ERROR)
     1136                        dprintf(("VBoxVideo: error %d writing CustomBPP\n", status));
     1137                }
     1138                else
     1139                {
     1140                    wchar_t keyname[32];
     1141                    swprintf(keyname, L"CustomXRes%d", display);
     1142                    status = VBoxVideoCmnRegSetDword(Reg, keyname, xres);
     1143                    if (status != NO_ERROR)
     1144                        dprintf(("VBoxVideo: error %d writing CustomXRes%d\n", status, display));
     1145                    swprintf(keyname, L"CustomYRes%d", display);
     1146                    status = VBoxVideoCmnRegSetDword(Reg, keyname, yres);
     1147                    if (status != NO_ERROR)
     1148                        dprintf(("VBoxVideo: error %d writing CustomYRes%d\n", status, display));
     1149                    swprintf(keyname, L"CustomBPP%d", display);
     1150                    status = VBoxVideoCmnRegSetDword(Reg, keyname, bpp);
     1151                    if (status != NO_ERROR)
     1152                        dprintf(("VBoxVideo: error %d writing CustomBPP%d\n", status, display));
     1153                }
     1154#endif /* VBOX_WITH_MULTIMONITOR_FIX */
    9251155            }
    9261156            else
     
    9551185                || VideoModes[i].BitsPerPlane)
    9561186            {
    957                 dprintf((" %2d: %4d x %4d @ %2d\n",
    958                         i, VideoModes[i].VisScreenWidth,
     1187                dprintf((" %2d: #%d %4d x %4d @ %2d\n",
     1188                        i, VideoModes[i].ModeIndex, VideoModes[i].VisScreenWidth,
    9591189                        VideoModes[i].VisScreenHeight, VideoModes[i].BitsPerPlane));
    9601190            }
     
    15981828    pDevExt->u.primary.pvReqFlush = NULL;
    15991829
     1830#ifndef VBOX_WITH_MULTIMONITOR_FIX
    16001831    /*
    16011832     * Get the last custom resolution
     
    16241855
    16251856   dprintf(("VBoxVideo: got stored custom resolution %dx%dx%d\n", gCustomXRes, gCustomYRes, gCustomBPP));
     1857#else
     1858    /* Initialize all custom modes to the 800x600x32. */
     1859    initVideoModeInformation(&CustomVideoModes[0], 800, 600, 32, 0, 0);
     1860
     1861    int iCustomMode;
     1862    for (iCustomMode = 1; iCustomMode < RT_ELEMENTS(CustomVideoModes); iCustomMode++)
     1863    {
     1864        CustomVideoModes[iCustomMode] = CustomVideoModes[0];
     1865    }
     1866
     1867    /* Load stored custom resolution from the registry. */
     1868    PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)HwDeviceExtension;
     1869    for (iCustomMode = 0; iCustomMode < DeviceExtension->pPrimary->u.primary.cDisplays; iCustomMode++)
     1870    {
     1871        /*
     1872         * Get the last custom resolution
     1873         */
     1874        ULONG CustomXRes = 0, CustomYRes = 0, CustomBPP = 0;
     1875
     1876        if (iCustomMode == 0)
     1877        {
     1878            /* Name without a suffix */
     1879            status = VideoPortGetRegistryParameters(HwDeviceExtension,
     1880                                                    L"CustomXRes",
     1881                                                    FALSE,
     1882                                                    VBoxRegistryCallback,
     1883                                                    &CustomXRes);
     1884            if (status != NO_ERROR)
     1885                CustomXRes = 0;
     1886            status = VideoPortGetRegistryParameters(HwDeviceExtension,
     1887                                                    L"CustomYRes",
     1888                                                    FALSE,
     1889                                                    VBoxRegistryCallback,
     1890                                                    &CustomYRes);
     1891            if (status != NO_ERROR)
     1892                CustomYRes = 0;
     1893            status = VideoPortGetRegistryParameters(HwDeviceExtension,
     1894                                                    L"CustomBPP",
     1895                                                    FALSE,
     1896                                                    VBoxRegistryCallback,
     1897                                                    &CustomBPP);
     1898            if (status != NO_ERROR)
     1899                CustomBPP = 0;
     1900        }
     1901        else
     1902        {
     1903            wchar_t keyname[32];
     1904            swprintf(keyname, L"CustomXRes%d", iCustomMode);
     1905            status = VideoPortGetRegistryParameters(HwDeviceExtension,
     1906                                                    keyname,
     1907                                                    FALSE,
     1908                                                    VBoxRegistryCallback,
     1909                                                    &CustomXRes);
     1910            if (status != NO_ERROR)
     1911                CustomXRes = 0;
     1912            swprintf(keyname, L"CustomYRes%d", iCustomMode);
     1913            status = VideoPortGetRegistryParameters(HwDeviceExtension,
     1914                                                    keyname,
     1915                                                    FALSE,
     1916                                                    VBoxRegistryCallback,
     1917                                                    &CustomYRes);
     1918            if (status != NO_ERROR)
     1919                CustomYRes = 0;
     1920            swprintf(keyname, L"CustomBPP%d", iCustomMode);
     1921            status = VideoPortGetRegistryParameters(HwDeviceExtension,
     1922                                                    keyname,
     1923                                                    FALSE,
     1924                                                    VBoxRegistryCallback,
     1925                                                    &CustomBPP);
     1926            if (status != NO_ERROR)
     1927                CustomBPP = 0;
     1928        }
     1929
     1930        dprintf(("VBoxVideo: got stored custom resolution[%d] %dx%dx%d\n", iCustomMode, CustomXRes, CustomYRes, CustomBPP));
     1931
     1932        if (CustomXRes || CustomYRes || CustomBPP)
     1933        {
     1934            if (CustomXRes == 0)
     1935            {
     1936                CustomXRes = CustomVideoModes[iCustomMode].VisScreenWidth;
     1937            }
     1938            if (CustomYRes == 0)
     1939            {
     1940                CustomYRes = CustomVideoModes[iCustomMode].VisScreenHeight;
     1941            }
     1942            if (CustomBPP == 0)
     1943            {
     1944                CustomBPP = CustomVideoModes[iCustomMode].BitsPerPlane;
     1945            }
     1946
     1947            initVideoModeInformation(&CustomVideoModes[iCustomMode], CustomXRes, CustomYRes, CustomBPP, 0, 0);
     1948        }
     1949    }
     1950#endif /* VBOX_WITH_MULTIMONITOR_FIX */
     1951
    16261952   return TRUE;
    16271953}
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