VirtualBox

Changeset 4093 in vbox for trunk


Ignore:
Timestamp:
Aug 8, 2007 3:51:58 PM (17 years ago)
Author:
vboxsync
Message:

Fixed missing black edge for Windows Vista alpha pointers over RDP.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/ConsoleVRDPServer.cpp

    r4071 r4093  
    146146#endif /* VBOX_WITH_XPCOM */
    147147
    148 static void findTopLeftBorder (uint8_t *pu8Shape, uint32_t width, uint32_t height, uint32_t *pxSkip, uint32_t *pySkip)
     148#ifdef DEBUG_sunlover
     149#define LOGDUMPPTR Log
     150void dumpPointer (const uint8_t *pu8Shape, uint32_t width, uint32_t height, bool fXorMaskRGB32)
     151{
     152    unsigned i;
     153
     154    const uint8_t *pu8And = pu8Shape;
     155
     156    for (i = 0; i < height; i++)
     157    {
     158        unsigned j;
     159        LOGDUMPPTR(("%p: ", pu8And));
     160        for (j = 0; j < (width + 7) / 8; j++)
     161        {
     162            unsigned k;
     163            for (k = 0; k < 8; k++)
     164            {
     165                LOGDUMPPTR(("%d", ((*pu8And) & (1 << (7 - k)))? 1: 0));
     166            }
     167
     168            pu8And++;
     169        }
     170        LOGDUMPPTR(("\n"));
     171    }
     172
     173    if (fXorMaskRGB32)
     174    {
     175        uint32_t *pu32Xor = (uint32_t *)(pu8Shape + ((((width + 7) / 8) * height + 3) & ~3));
     176
     177        for (i = 0; i < height; i++)
     178        {
     179            unsigned j;
     180            LOGDUMPPTR(("%p: ", pu32Xor));
     181            for (j = 0; j < width; j++)
     182            {
     183                LOGDUMPPTR(("%08X", *pu32Xor++));
     184            }
     185            LOGDUMPPTR(("\n"));
     186        }
     187    }
     188    else
     189    {
     190        /* RDP 24 bit RGB mask. */
     191        uint8_t *pu8Xor = (uint8_t *)(pu8Shape + ((((width + 7) / 8) * height + 3) & ~3));
     192        for (i = 0; i < height; i++)
     193        {
     194            unsigned j;
     195            LOGDUMPPTR(("%p: ", pu8Xor));
     196            for (j = 0; j < width; j++)
     197            {
     198                LOGDUMPPTR(("%02X%02X%02X", pu8Xor[2], pu8Xor[1], pu8Xor[0]));
     199                pu8Xor += 3;
     200            }
     201            LOGDUMPPTR(("\n"));
     202        }
     203    }
     204}
     205#else
     206#define dumpPointer(a, b, c, d) do {} while (0)
     207#endif /* DEBUG_sunlover */
     208
     209static void findTopLeftBorder (const uint8_t *pu8AndMask, const uint8_t *pu8XorMask, uint32_t width, uint32_t height, uint32_t *pxSkip, uint32_t *pySkip)
    149210{
    150211    /*
     
    153214    uint32_t ySkipAnd = ~0;
    154215
    155     uint8_t *pu8And = pu8Shape;
     216    const uint8_t *pu8And = pu8AndMask;
    156217    const uint32_t cbAndRow = (width + 7) / 8;
    157218    const uint8_t maskLastByte = (uint8_t)( 0xFF << (cbAndRow * 8 - width) );
     
    197258    for (x = 0; x < width && xSkipAnd == ~(uint32_t)0; x++)
    198259    {
    199         pu8And = pu8Shape + x/8;       /* Currently checking byte. */
     260        pu8And = pu8AndMask + x/8;       /* Currently checking byte. */
    200261        uint8_t mask = 1 << (7 - x%8); /* Currently checking bit in the byte. */
    201262
     
    220281    uint32_t ySkipXor = ~0;
    221282
    222     uint32_t *pu32XorStart = (uint32_t *)( pu8Shape + ((cbAndRow * height + 3) & ~3) );
     283    uint32_t *pu32XorStart = (uint32_t *)pu8XorMask;
    223284
    224285    uint32_t *pu32Xor = pu32XorStart;
     
    270331}
    271332
     333/* Generate an AND mask for alpha pointers here, because
     334 * guest driver does not do that correctly for Vista pointers.
     335 * Similar fix, changing the alpha threshold, could be applied
     336 * for the guest driver, but then additions reinstall would be
     337 * necessary, which we try to avoid.
     338 */
     339static void mousePointerGenerateANDMask (uint8_t *pu8DstAndMask, int cbDstAndMask, const uint8_t *pu8SrcAlpha, int w, int h)
     340{
     341    memset (pu8DstAndMask, 0xFF, cbDstAndMask);
     342   
     343    int y;
     344    for (y = 0; y < h; y++)
     345    {
     346        uint8_t bitmask = 0x80;
     347           
     348        int x;
     349        for (x = 0; x < w; x++, bitmask >>= 1)
     350        {
     351            if (bitmask == 0)
     352            {
     353                bitmask = 0x80;
     354            }
     355           
     356            /* Whether alpha channel value is not transparent enough for the pixel to be seen. */
     357            if (pu8SrcAlpha[x * 4 + 3] > 0x7f)
     358            {
     359                pu8DstAndMask[x / 8] &= ~bitmask;
     360            }
     361        }
     362   
     363        /* Point to next source and dest scans. */
     364        pu8SrcAlpha += w * 4;
     365        pu8DstAndMask += (w + 7) / 8;
     366    }
     367}
    272368
    273369STDMETHODIMP VRDPConsoleCallback::OnMousePointerShapeChange (BOOL visible, BOOL alpha, ULONG xHot, ULONG yHot,
     
    304400             */
    305401
     402            dumpPointer (shape, width, height, true);
     403
     404            int cbDstAndMask = (((width + 7) / 8) * height + 3) & ~3;
     405
     406            uint8_t *pu8AndMask = shape;
     407            uint8_t *pu8XorMask = shape + cbDstAndMask;
     408
     409            if (alpha)
     410            {
     411                pu8AndMask = (uint8_t *)alloca (cbDstAndMask);
     412
     413                mousePointerGenerateANDMask (pu8AndMask, cbDstAndMask, pu8XorMask, width, height);
     414            }
     415
    306416            /* Windows guest alpha pointers are wider than 32 pixels.
    307417             * Try to find out the top-left border of the pointer and
     
    313423            uint32_t xSkip = 0; /* How many columns to skip at the left. */
    314424
    315             findTopLeftBorder (shape, width, height, &xSkip, &ySkip);
     425            findTopLeftBorder (pu8AndMask, pu8XorMask, width, height, &xSkip, &ySkip);
    316426
    317427            /* Must not skip the hot spot. */
     
    349459
    350460                /* Copy AND mask. */
    351                 uint8_t *src = shape + ySkip * srcmaskwidth;
     461                uint8_t *src = pu8AndMask + ySkip * srcmaskwidth;
    352462                uint8_t *dst = maskarray + (dstheight - 1) * rdpmaskwidth;
    353463
     
    380490
    381491                /* Point src to XOR mask */
    382                 src = shape + ((srcmaskwidth * height + 3) & ~3) + ySkip * srcdatawidth;
     492                src = pu8XorMask + ySkip * srcdatawidth;
    383493                dst = dataarray + (dstheight - 1) * rdpdatawidth;
    384494
     
    402512                pointer->u16MaskLen = (uint16_t)rdpmasklen;
    403513                pointer->u16DataLen = (uint16_t)rdpdatalen;
     514
     515                dumpPointer ((uint8_t *)pointer + sizeof (*pointer), dstwidth, dstheight, false);
    404516
    405517                m_server->MousePointerUpdate (pointer);
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