VirtualBox

Ignore:
Timestamp:
Mar 22, 2010 5:56:15 PM (15 years ago)
Author:
vboxsync
Message:

wddm: mouse pointer integration support (not tested)

Location:
trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm
Files:
2 edited

Legend:

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

    r27551 r27606  
    540540
    541541/* driver callbacks */
    542 
    543542NTSTATUS DxgkDdiAddDevice(
    544543    IN CONST PDEVICE_OBJECT PhysicalDeviceObject,
     
    563562    else
    564563    {
    565         Status  = STATUS_INSUFFICIENT_RESOURCES;
     564        Status  = STATUS_NO_MEMORY;
    566565        drprintf(("VBoxVideoWddm: ERROR, failed to create context\n"));
    567566    }
     
    11351134            pCaps->MaxAllocationListSlotId = 16;
    11361135            pCaps->ApertureSegmentCommitLimit = 0;
    1137             pCaps->MaxPointerWidth = 64;
    1138             pCaps->MaxPointerHeight = 64;
     1136            pCaps->MaxPointerWidth  = VBOXWDDM_C_POINTER_MAX_WIDTH;
     1137            pCaps->MaxPointerHeight = VBOXWDDM_C_POINTER_MAX_HEIGHT;
    11391138            pCaps->PointerCaps.Value = 3; /* Monochrome , Color*/ /* MaskedColor == Value | 4, dosable for now */
    11401139            pCaps->InterruptMessageNumber = 0;
     
    18251824}
    18261825
     1826BOOL vboxWddmPointerCopyColorData(CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape, PVIDEO_POINTER_ATTRIBUTES pPointerAttributes)
     1827{
     1828    /* Format of "hardware" pointer is:
     1829     * 1 bpp AND mask with byte aligned scanlines,
     1830     * B G R A bytes of XOR mask that starts on the next 4 byte aligned offset after AND mask.
     1831     *
     1832     * If fl & SPS_ALPHA then A bytes contain alpha channel information.
     1833     * Otherwise A bytes are undefined (but will be 0).
     1834     *
     1835     */
     1836    PBYTE pjSrcAnd = NULL;
     1837    PBYTE pjSrcXor = NULL;
     1838
     1839    ULONG cy = 0;
     1840
     1841    PBYTE pjDstAnd = pPointerAttributes->Pixels;
     1842    ULONG cjAnd = 0;
     1843    PBYTE pjDstXor = pPointerAttributes->Pixels;
     1844
     1845    ULONG cxSrc = pSetPointerShape->Width;
     1846    ULONG cySrc = pSetPointerShape->Width;
     1847
     1848    // Make sure the new pointer isn't too big to handle,
     1849    // strip the size to 64x64 if necessary
     1850    if (cxSrc > VBOXWDDM_C_POINTER_MAX_WIDTH)
     1851        cxSrc = VBOXWDDM_C_POINTER_MAX_WIDTH;
     1852
     1853    if (cySrc > VBOXWDDM_C_POINTER_MAX_HEIGHT)
     1854        cySrc = VBOXWDDM_C_POINTER_MAX_HEIGHT;
     1855
     1856    /* Size of AND mask in bytes */
     1857    cjAnd = ((cxSrc + 7) / 8) * cySrc;
     1858
     1859    /* Pointer to XOR mask is 4-bytes aligned */
     1860    pjDstXor += (cjAnd + 3) & ~3;
     1861
     1862    pPointerAttributes->Width = cxSrc;
     1863    pPointerAttributes->Height = cySrc;
     1864    pPointerAttributes->WidthInBytes = cxSrc * 4;
     1865
     1866    uint32_t cbData = ((cjAnd + 3) & ~3) + pPointerAttributes->Height*pPointerAttributes->WidthInBytes;
     1867    uint32_t cbPointerAttributes = RT_OFFSETOF(VIDEO_POINTER_ATTRIBUTES, Pixels[cbData]);
     1868    Assert(VBOXWDDM_POINTER_ATTRIBUTES_SIZE >= cbPointerAttributes);
     1869    if (VBOXWDDM_POINTER_ATTRIBUTES_SIZE < cbPointerAttributes)
     1870    {
     1871        drprintf((__FUNCTION__": VBOXWDDM_POINTER_ATTRIBUTES_SIZE(%d) < cbPointerAttributes(%d)\n", VBOXWDDM_POINTER_ATTRIBUTES_SIZE, cbPointerAttributes));
     1872        return FALSE;
     1873    }
     1874
     1875    /* Init AND mask to 1 */
     1876    RtlFillMemory (pjDstAnd, cjAnd, 0xFF);
     1877
     1878    PBYTE pjSrcAlpha = (PBYTE)pSetPointerShape->pPixels;
     1879
     1880    /*
     1881     * Emulate AND mask to provide viewable mouse pointer for
     1882     * hardware which does not support alpha channel.
     1883     */
     1884
     1885    for (cy = 0; cy < cySrc; cy++)
     1886    {
     1887        ULONG cx;
     1888
     1889        UCHAR bitmask = 0x80;
     1890
     1891        for (cx = 0; cx < cxSrc; cx++, bitmask >>= 1)
     1892        {
     1893            if (bitmask == 0)
     1894            {
     1895                bitmask = 0x80;
     1896            }
     1897
     1898            if (pjSrcAlpha[cx * 4 + 3] > 0x7f)
     1899            {
     1900               pjDstAnd[cx / 8] &= ~bitmask;
     1901            }
     1902        }
     1903
     1904        // Point to next source and dest scans
     1905        pjSrcAlpha += pSetPointerShape->Pitch;
     1906        pjDstAnd += (cxSrc + 7) / 8;
     1907    }
     1908
     1909    /*
     1910     * pso is 32 bit BGRX bitmap. Copy it to Pixels
     1911     */
     1912    pjSrcXor = (PBYTE)pSetPointerShape->pPixels;
     1913    for (cy = 0; cy < cySrc; cy++)
     1914    {
     1915        /* 32 bit bitmap is being copied */
     1916        RtlCopyMemory (pjDstXor, pjSrcXor, cxSrc * 4);
     1917
     1918        /* Point to next source and dest scans */
     1919        pjSrcXor += pSetPointerShape->Pitch;
     1920        pjDstXor += pPointerAttributes->WidthInBytes;
     1921    }
     1922
     1923    return TRUE;
     1924}
     1925
     1926BOOL vboxWddmPointerCopyMonoData(CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape, PVIDEO_POINTER_ATTRIBUTES pPointerAttributes)
     1927{
     1928    PBYTE pjSrc = NULL;
     1929
     1930    ULONG cy = 0;
     1931
     1932    PBYTE pjDstAnd = pPointerAttributes->Pixels;
     1933    ULONG cjAnd = 0;
     1934    PBYTE pjDstXor = pPointerAttributes->Pixels;
     1935
     1936    ULONG cxSrc = pSetPointerShape->Width;
     1937    ULONG cySrc = pSetPointerShape->Height / 2; /* /2 because both masks are in there */
     1938
     1939    // Make sure the new pointer isn't too big to handle,
     1940    // strip the size to 64x64 if necessary
     1941    if (cxSrc > VBOXWDDM_C_POINTER_MAX_WIDTH)
     1942        cxSrc = VBOXWDDM_C_POINTER_MAX_WIDTH;
     1943
     1944    if (cySrc > VBOXWDDM_C_POINTER_MAX_HEIGHT)
     1945        cySrc = VBOXWDDM_C_POINTER_MAX_HEIGHT;
     1946
     1947    /* Size of AND mask in bytes */
     1948    cjAnd = ((cxSrc + 7) / 8) * cySrc;
     1949
     1950    /* Pointer to XOR mask is 4-bytes aligned */
     1951    pjDstXor += (cjAnd + 3) & ~3;
     1952
     1953    pPointerAttributes->Width = cxSrc;
     1954    pPointerAttributes->Height = cySrc;
     1955    pPointerAttributes->WidthInBytes = cxSrc * 4;
     1956
     1957    /* Init AND mask to 1 */
     1958    RtlFillMemory (pjDstAnd, cjAnd, 0xFF);
     1959
     1960    /*
     1961     * Copy AND mask.
     1962     */
     1963    pjSrc = (PBYTE)pSetPointerShape->pPixels;
     1964
     1965    for (cy = 0; cy < cySrc; cy++)
     1966    {
     1967        RtlCopyMemory (pjDstAnd, pjSrc, (cxSrc + 7) / 8);
     1968
     1969        // Point to next source and dest scans
     1970        pjSrc += pSetPointerShape->Pitch;
     1971        pjDstAnd += (cxSrc + 7) / 8;
     1972    }
     1973
     1974    for (cy = 0; cy < cySrc; ++cy)
     1975    {
     1976        ULONG cx;
     1977
     1978        UCHAR bitmask = 0x80;
     1979
     1980        for (cx = 0; cx < cxSrc; cx++, bitmask >>= 1)
     1981        {
     1982            if (bitmask == 0)
     1983            {
     1984                bitmask = 0x80;
     1985            }
     1986
     1987            if (pjSrc[cx / 8] & bitmask)
     1988            {
     1989                *(ULONG *)&pjDstXor[cx * 4] = 0x00FFFFFF;
     1990            }
     1991            else
     1992            {
     1993                *(ULONG *)&pjDstXor[cx * 4] = 0;
     1994            }
     1995        }
     1996
     1997        // Point to next source and dest scans
     1998        pjSrc += pSetPointerShape->Pitch;
     1999        pjDstXor += cxSrc * 4;
     2000    }
     2001
     2002    return TRUE;
     2003}
     2004
     2005static BOOLEAN vboxVddmPointerShapeToAttributes(CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape, PVBOXWDDM_POINTER_INFO pPointerInfo)
     2006{
     2007    PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = &pPointerInfo->Attributes.data;
     2008    /* pPointerAttributes maointains the visibility state, clear all except visibility */
     2009    pPointerAttributes->Enable &= 0xffff0000 | VBOX_MOUSE_POINTER_VISIBLE;
     2010
     2011    Assert(pSetPointerShape->Flags.Value == 1 || pSetPointerShape->Flags.Value == 2);
     2012    if (pSetPointerShape->Flags.Color)
     2013    {
     2014        if (vboxWddmPointerCopyColorData(pSetPointerShape, pPointerAttributes))
     2015        {
     2016            pPointerAttributes->Flags = VIDEO_MODE_COLOR_POINTER;
     2017            pPointerAttributes->Enable |= VBOX_MOUSE_POINTER_ALPHA;
     2018        }
     2019        else
     2020        {
     2021            drprintf((__FUNCTION__": vboxWddmPointerCopyColorData failed\n"));
     2022            AssertBreakpoint();
     2023            return FALSE;
     2024        }
     2025
     2026    }
     2027    else if (pSetPointerShape->Flags.Monochrome)
     2028    {
     2029        if (vboxWddmPointerCopyMonoData(pSetPointerShape, pPointerAttributes))
     2030        {
     2031            pPointerAttributes->Flags = VIDEO_MODE_MONO_POINTER;
     2032        }
     2033        else
     2034        {
     2035            drprintf((__FUNCTION__": vboxWddmPointerCopyMonoData failed\n"));
     2036            AssertBreakpoint();
     2037            return FALSE;
     2038        }
     2039    }
     2040    else
     2041    {
     2042        drprintf((__FUNCTION__": unsupported pointer type Flags.Value(0x%x)\n", pSetPointerShape->Flags.Value));
     2043        AssertBreakpoint();
     2044        return FALSE;
     2045    }
     2046
     2047    pPointerAttributes->Enable |= VBOX_MOUSE_POINTER_SHAPE;
     2048    //
     2049    // Initialize Pointer attributes and position
     2050    //
     2051    if (pPointerAttributes->Enable & VBOX_MOUSE_POINTER_VISIBLE)
     2052    {
     2053        /* New coordinates of pointer's hot spot */
     2054        pPointerAttributes->Column = (SHORT)(pPointerInfo->xPos) - (SHORT)(pSetPointerShape->YHot);
     2055        pPointerAttributes->Row    = (SHORT)(pPointerInfo->yPos) - (SHORT)(pSetPointerShape->YHot);
     2056    }
     2057    else
     2058    {
     2059        /* Pointer should be created invisible */
     2060        pPointerAttributes->Column = -1;
     2061        pPointerAttributes->Row    = -1;
     2062    }
     2063
     2064    /* VBOX: We have to pass to miniport hot spot coordinates and alpha flag.
     2065     * They will be encoded in the pPointerAttributes::Enable field.
     2066     * High word will contain hot spot info and low word - flags.
     2067     */
     2068
     2069    pPointerAttributes->Enable |= (pSetPointerShape->YHot & 0xFF) << 24;
     2070    pPointerAttributes->Enable |= (pSetPointerShape->XHot & 0xFF) << 16;
     2071
     2072    return TRUE;
     2073}
     2074
    18272075NTSTATUS
    18282076APIENTRY
     
    18342082
    18352083    vboxVDbgBreakFv();
    1836     /* @todo: fixme: implement */
     2084
     2085    /* mouse integration is ON */
     2086    PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
     2087    PVBOXWDDM_POINTER_INFO pPointerInfo = &pDevExt->aSources[pSetPointerPosition->VidPnSourceId].PointerInfo;
     2088    PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = &pPointerInfo->Attributes.data;
     2089    if (pSetPointerPosition->Flags.Visible)
     2090        pPointerAttributes->Enable |= VBOX_MOUSE_POINTER_VISIBLE;
     2091    else
     2092        pPointerAttributes->Enable &= ~VBOX_MOUSE_POINTER_VISIBLE;
     2093
     2094    pPointerInfo->xPos = pSetPointerPosition->X;
     2095    pPointerInfo->yPos = pSetPointerPosition->Y;
    18372096
    18382097    dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
     
    18502109
    18512110    vboxVDbgBreakFv();
    1852     /* @todo: fixme: implement */
     2111
     2112    NTSTATUS Status = STATUS_NOT_SUPPORTED;
     2113
     2114    if (vboxQueryHostWantsAbsolute())
     2115    {
     2116        /* mouse integration is ON */
     2117        PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
     2118        PVBOXWDDM_POINTER_INFO pPointerInfo = &pDevExt->aSources[pSetPointerShape->VidPnSourceId].PointerInfo;
     2119        if (vboxVddmPointerShapeToAttributes(pSetPointerShape, pPointerInfo))
     2120        {
     2121            if (vboxUpdatePointerShape (pDevExt, &pPointerInfo->Attributes.data, VBOXWDDM_POINTER_ATTRIBUTES_SIZE))
     2122                Status = STATUS_SUCCESS;
     2123            else
     2124                drprintf((__FUNCTION__": vboxUpdatePointerShape failed\n"));
     2125        }
     2126    }
    18532127
    18542128//    dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
    18552129
    1856     return STATUS_NOT_SUPPORTED;
     2130    return Status;
    18572131}
    18582132
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.h

    r27383 r27606  
    2121#define VBOXWDDM_C_ALLOC_LIST_SIZE         0xc00
    2222#define VBOXWDDM_C_PATH_LOCATION_LIST_SIZE 0xc00
     23
     24#define VBOXWDDM_C_POINTER_MAX_WIDTH  64
     25#define VBOXWDDM_C_POINTER_MAX_HEIGHT 64
     26
     27#define VBOXWDDM_ROUNDBOUND(_v, _b) (((_v) + ((_b) - 1)) & ~((_b) - 1))
    2328
    2429typedef enum
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