VirtualBox

Changeset 62588 in vbox for trunk/src


Ignore:
Timestamp:
Jul 27, 2016 12:34:50 PM (8 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:8438: UISession::setPointerShape Qt5 fixes for Windows host.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp

    r62493 r62588  
    17531753# else /* QT_VERSION >= 0x050000 */
    17541754    /* Create a ARGB image out of the shape data: */
    1755     QImage image(uWidth, uHeight, QImage::Format_ARGB32);
    1756     memcpy(image.bits(), srcShapePtr, uHeight * uWidth * 4);
     1755
     1756    /*
     1757     * Qt5 QCursor recommends 32 x 32 cursor, therefore the original data is copied to
     1758     * a larger QImage if necessary. Cursors like 10x16 did not work correctly (Solaris 10 guest).
     1759     */
     1760    uint uCursorWidth = uWidth >= 32? uWidth: 32;
     1761    uint uCursorHeight = uHeight >= 32? uHeight: 32;
     1762    uint x, y;
    17571763
    17581764    if (fHasAlpha)
     1765    {
     1766        QImage image(uCursorWidth, uCursorHeight, QImage::Format_ARGB32);
     1767        memset(image.bits(), 0, image.byteCount());
     1768
     1769        const uint32_t *pu32SrcShapeScanline = (uint32_t *)srcShapePtr;
     1770        for (y = 0; y < uHeight; ++y, pu32SrcShapeScanline += uWidth)
     1771            memcpy(image.scanLine(y), pu32SrcShapeScanline, uWidth * sizeof(uint32_t));
     1772
    17591773        m_cursor = QCursor(QPixmap::fromImage(image), uXHot, uYHot);
     1774    }
    17601775    else
    17611776    {
     
    17641779            /* Incoming data consist of 32 bit BGR XOR mask and 1 bit AND mask.
    17651780             * XOR pixels contain either 0x00000000 or 0x00FFFFFF.
    1766              * image.convertToFormat(QImage::Format_Mono) converts them:
    1767              * 0x00000000 -> 1, 0x00FFFFFF -> 0.
    17681781             *
    1769              * XOR AND originally intended result (F denotes 0x00FFFFFF):
     1782             * Originally intended result (F denotes 0x00FFFFFF):
     1783             * XOR AND
    17701784             *   0   0 black
    17711785             *   F   0 white
     
    17731787             *   F   1 xor'd
    17741788             *
    1775              * XOR AND converted bitmap intended result:
    1776              *   1   0 black
    1777              *   0   0 white
    1778              *   1   1 transparent
    1779              *   0   1 xor'd
     1789             * Actual Qt5 result for color table 0:0xFF000000, 1:0xFFFFFFFF
     1790             * (tested on Windows 7 and 10 64 bit hosts):
     1791             * Bitmap Mask
     1792             *  0   0 black
     1793             *  1   0 white
     1794             *  0   1 xor
     1795             *  1   1 transparent
    17801796             *
    1781              * Bitmap Mask actual Qt5 result (tested on Windows 7 64 bit host):
    1782              *   1   0 black
    1783              *   0   0 white
    1784              *   0   1 transparent
    1785              *   1   1 xor'd
    1786              *
    1787              * Converted bitmap to the Qt5 mask and bitmap:
    1788              * Mask = AND;
    1789              * Bitmap = ConvBitmap ^ Mask;
    17901797             */
    1791             QImage bitmap = image.convertToFormat(QImage::Format_Mono);
    1792             QImage mask(uWidth, uHeight, QImage::Format_Mono);
    1793             memcpy(mask.bits(), srcAndMaskPtr, uHeight * ((uWidth + 7) / 8));
    1794 
    1795             const uint8_t *pu8Mask = mask.bits();
    1796             uint8_t *pu8Bitmap = bitmap.bits();
    1797             uint i;
    1798             for (i = 0; i < uHeight * ((uWidth + 7) / 8); ++i)
    1799                 pu8Bitmap[i] ^= pu8Mask[i];
    1800 
    1801             m_cursor = QCursor(QBitmap::fromImage(bitmap), QBitmap::fromImage(mask), uXHot, uYHot);
    1802         }
    1803         else
    1804         {
    1805             /* Assign alpha channel values according to the AND mask: 1 -> 0x00, 0 -> 0xFF: */
    1806             const uint8_t *pu8And = srcAndMaskPtr;
    1807             uint32_t *pu32Pixel = (uint32_t *)image.bits();
    1808             uint y;
     1798
     1799            QVector<QRgb> colors(2);
     1800            colors[0] = UINT32_C(0xFF000000);
     1801            colors[1] = UINT32_C(0xFFFFFFFF);
     1802
     1803            QImage bitmap(uCursorWidth, uCursorHeight, QImage::Format_Mono);
     1804            bitmap.setColorTable(colors);
     1805            memset(bitmap.bits(), 0xFF, bitmap.byteCount());
     1806
     1807            QImage mask(uCursorWidth, uCursorHeight, QImage::Format_Mono);
     1808            mask.setColorTable(colors);
     1809            memset(mask.bits(), 0xFF, mask.byteCount());
     1810
     1811            const uint8_t *pu8SrcAndScanline = srcAndMaskPtr;
     1812            const uint32_t *pu32SrcShapeScanline = (uint32_t *)srcShapePtr;
    18091813            for (y = 0; y < uHeight; ++y)
    18101814            {
    1811                 uint x;
    1812                 for (x = 0; x < (uWidth + 7) / 8; ++x)
     1815                for (x = 0; x < uWidth; ++x)
    18131816                {
    1814                     const uint8_t b = *pu8And;
    1815                     uint k;
    1816                     for (k = 0; k < 8; ++k)
     1817                    const uint8_t u8Bit = (uint8_t)(1 << (7 - x % 8));
     1818
     1819                    const uint8_t u8SrcMaskByte = pu8SrcAndScanline[x / 8];
     1820                    const uint8_t u8SrcMaskBit = u8SrcMaskByte & u8Bit;
     1821                    const uint32_t u32SrcPixel = pu32SrcShapeScanline[x] & UINT32_C(0xFFFFFF);
     1822
     1823                    uint8_t *pu8DstMaskByte = &mask.scanLine(y)[x / 8];
     1824                    uint8_t *pu8DstBitmapByte = &bitmap.scanLine(y)[x / 8];
     1825
     1826                    if (u8SrcMaskBit == 0)
    18171827                    {
    1818                         if (b & (1 << (7 - k)))
    1819                             *pu32Pixel &= UINT32_C(0x00FFFFFF);
     1828                        if (u32SrcPixel == 0)
     1829                        {
     1830                            /* Black: Qt Bitmap = 0, Mask = 0 */
     1831                            *pu8DstMaskByte &= ~u8Bit;
     1832                            *pu8DstBitmapByte &= ~u8Bit;
     1833                        }
    18201834                        else
    1821                             *pu32Pixel |= UINT32_C(0xFF000000);
    1822                         ++pu32Pixel;
     1835                        {
     1836                            /* White: Qt Bitmap = 1, Mask = 0 */
     1837                            *pu8DstMaskByte &= ~u8Bit;
     1838                            *pu8DstBitmapByte |= u8Bit;
     1839                        }
    18231840                    }
    1824 
    1825                     ++pu8And;
     1841                    else
     1842                    {
     1843                        if (u32SrcPixel == 0)
     1844                        {
     1845                            /* Transparent: Qt Bitmap = 1, Mask = 1 */
     1846                            *pu8DstMaskByte |= u8Bit;
     1847                            *pu8DstBitmapByte |= u8Bit;
     1848                        }
     1849                        else
     1850                        {
     1851                            /* Xor'ed: Qt Bitmap = 0, Mask = 1 */
     1852                            *pu8DstMaskByte |= u8Bit;
     1853                            *pu8DstBitmapByte &= ~u8Bit;
     1854                        }
     1855                    }
    18261856                }
     1857
     1858                pu8SrcAndScanline += (uWidth + 7) / 8;
     1859                pu32SrcShapeScanline += uWidth;
     1860            }
     1861
     1862            m_cursor = QCursor(QBitmap::fromImage(bitmap), QBitmap::fromImage(mask), uXHot, uYHot);
     1863        }
     1864        else
     1865        {
     1866            /* Assign alpha channel values according to the AND mask: 1 -> 0x00, 0 -> 0xFF: */
     1867            QImage image(uCursorWidth, uCursorHeight, QImage::Format_ARGB32);
     1868            memset(image.bits(), 0, image.byteCount());
     1869
     1870            const uint8_t *pu8SrcAndScanline = srcAndMaskPtr;
     1871            const uint32_t *pu32SrcShapeScanline = (uint32_t *)srcShapePtr;
     1872
     1873            for (y = 0; y < uHeight; ++y)
     1874            {
     1875                uint32_t *pu32DstPixel = (uint32_t *)image.scanLine(y);
     1876
     1877                for (x = 0; x < uWidth; ++x)
     1878                {
     1879                    const uint8_t u8Bit = (uint8_t)(1 << (7 - x % 8));
     1880                    const uint8_t u8SrcMaskByte = pu8SrcAndScanline[x / 8];
     1881
     1882                    if (u8SrcMaskByte & u8Bit)
     1883                        *pu32DstPixel++ = pu32SrcShapeScanline[x] & UINT32_C(0x00FFFFFF);
     1884                    else
     1885                        *pu32DstPixel++ = pu32SrcShapeScanline[x] | UINT32_C(0xFF000000);
     1886                }
     1887
     1888                pu32SrcShapeScanline += uWidth;
     1889                pu8SrcAndScanline += (uWidth + 7) / 8;
    18271890            }
    18281891
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