VirtualBox

Changeset 52923 in vbox


Ignore:
Timestamp:
Oct 2, 2014 7:04:02 AM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
96358
Message:

ConsoleVRDPServer: update the mouse pointer when the VRDP server is started.

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/ConsoleVRDPServer.h

    r52442 r52923  
    157157
    158158    Console *getConsole(void) { return mConsole; }
     159
     160    void onMousePointerShapeChange(BOOL visible, BOOL alpha, ULONG xHot, ULONG yHot,
     161                                   ULONG width, ULONG height, ComSafeArrayIn(BYTE,shape));
    159162
    160163private:
     
    193196    static DECLCALLBACK(void) VRDPCallbackVideoModeHint     (void *pvCallback, unsigned cWidth, unsigned cHeight,  unsigned cBitsPerPixel, unsigned uScreenId);
    194197    static DECLCALLBACK(void) VRDECallbackAudioIn           (void *pvCallback, void *pvCtx, uint32_t u32ClientId, uint32_t u32Event, const void *pvData, uint32_t cbData);
     198
     199    void fetchCurrentState(void);
    195200
    196201    bool m_fGuestWantsAbsolute;
  • trunk/src/VBox/Main/src-client/ConsoleVRDPServer.cpp

    r52442 r52923  
    8888                mpscev->COMGETTER(Shape)(ComSafeArrayAsOutParam(shape));
    8989
    90                 OnMousePointerShapeChange(visible, alpha, xHot, yHot, width, height, ComSafeArrayAsInParam(shape));
     90                m_server->onMousePointerShapeChange(visible, alpha, xHot, yHot, width, height, ComSafeArrayAsInParam(shape));
    9191                break;
    9292            }
     
    127127
    128128private:
    129     STDMETHOD(OnMousePointerShapeChange)(BOOL visible, BOOL alpha, ULONG xHot, ULONG yHot,
    130                                          ULONG width, ULONG height, ComSafeArrayIn(BYTE,shape));
    131129    ConsoleVRDPServer *m_server;
    132130};
     
    358356}
    359357
    360 STDMETHODIMP VRDPConsoleListener::OnMousePointerShapeChange(BOOL visible,
    361                                                             BOOL alpha,
    362                                                             ULONG xHot,
    363                                                             ULONG yHot,
    364                                                             ULONG width,
    365                                                             ULONG height,
    366                                                             ComSafeArrayIn(BYTE,inShape))
     358void ConsoleVRDPServer::onMousePointerShapeChange(BOOL visible,
     359                                                  BOOL alpha,
     360                                                  ULONG xHot,
     361                                                  ULONG yHot,
     362                                                  ULONG width,
     363                                                  ULONG height,
     364                                                  ComSafeArrayIn(BYTE,inShape))
    367365{
    368366    LogSunlover(("VRDPConsoleListener::OnMousePointerShapeChange: %d, %d, %lux%lu, @%lu,%lu\n",
    369367                 visible, alpha, width, height, xHot, yHot));
    370368
    371     if (m_server)
    372     {
    373         com::SafeArray <BYTE> aShape(ComSafeArrayInArg(inShape));
    374         if (aShape.size() == 0)
    375         {
    376             if (!visible)
    377             {
    378                 m_server->MousePointerHide();
    379             }
    380         }
    381         else if (width != 0 && height != 0)
    382         {
    383             uint8_t* shape = aShape.raw();
    384 
    385             dumpPointer(shape, width, height, true);
    386 
    387             if (m_server->MousePointer(alpha, xHot, yHot, width, height, shape) == VINF_SUCCESS)
    388             {
    389                 return S_OK;
    390             }
    391 
    392             /* Pointer consists of 1 bpp AND and 24 BPP XOR masks.
    393              * 'shape' AND mask followed by XOR mask.
    394              * XOR mask contains 32 bit (lsb)BGR0(msb) values.
    395              *
    396              * We convert this to RDP color format which consist of
    397              * one bpp AND mask and 24 BPP (BGR) color XOR image.
    398              *
    399              * RDP clients expect 8 aligned width and height of
    400              * pointer (preferably 32x32).
    401              *
    402              * They even contain bugs which do not appear for
    403              * 32x32 pointers but would appear for a 41x32 one.
    404              *
    405              * So set pointer size to 32x32. This can be done safely
    406              * because most pointers are 32x32.
    407              */
    408 
    409             int cbDstAndMask = (((width + 7) / 8) * height + 3) & ~3;
    410 
    411             uint8_t *pu8AndMask = shape;
    412             uint8_t *pu8XorMask = shape + cbDstAndMask;
    413 
    414             if (alpha)
    415             {
    416                 pu8AndMask = (uint8_t*)alloca(cbDstAndMask);
    417 
    418                 mousePointerGenerateANDMask(pu8AndMask, cbDstAndMask, pu8XorMask, width, height);
    419             }
    420 
    421             /* Windows guest alpha pointers are wider than 32 pixels.
    422              * Try to find out the top-left border of the pointer and
    423              * then copy only meaningful bits. All complete top rows
    424              * and all complete left columns where (AND == 1 && XOR == 0)
    425              * are skipped. Hot spot is adjusted.
    426              */
    427             uint32_t ySkip = 0; /* How many rows to skip at the top. */
    428             uint32_t xSkip = 0; /* How many columns to skip at the left. */
    429 
    430             findTopLeftBorder(pu8AndMask, pu8XorMask, width, height, &xSkip, &ySkip);
    431 
    432             /* Must not skip the hot spot. */
    433             xSkip = RT_MIN(xSkip, xHot);
    434             ySkip = RT_MIN(ySkip, yHot);
    435 
    436             /*
    437              * Compute size and allocate memory for the pointer.
    438              */
    439             const uint32_t dstwidth = 32;
    440             const uint32_t dstheight = 32;
    441 
    442             VRDECOLORPOINTER *pointer = NULL;
    443 
    444             uint32_t dstmaskwidth = (dstwidth + 7) / 8;
    445 
    446             uint32_t rdpmaskwidth = dstmaskwidth;
    447             uint32_t rdpmasklen = dstheight * rdpmaskwidth;
    448 
    449             uint32_t rdpdatawidth = dstwidth * 3;
    450             uint32_t rdpdatalen = dstheight * rdpdatawidth;
    451 
    452             pointer = (VRDECOLORPOINTER *)RTMemTmpAlloc(sizeof(VRDECOLORPOINTER) + rdpmasklen + rdpdatalen);
    453 
    454             if (pointer)
    455             {
    456                 uint8_t *maskarray = (uint8_t*)pointer + sizeof(VRDECOLORPOINTER);
    457                 uint8_t *dataarray = maskarray + rdpmasklen;
    458 
    459                 memset(maskarray, 0xFF, rdpmasklen);
    460                 memset(dataarray, 0x00, rdpdatalen);
    461 
    462                 uint32_t srcmaskwidth = (width + 7) / 8;
    463                 uint32_t srcdatawidth = width * 4;
    464 
    465                 /* Copy AND mask. */
    466                 uint8_t *src = pu8AndMask + ySkip * srcmaskwidth;
    467                 uint8_t *dst = maskarray + (dstheight - 1) * rdpmaskwidth;
    468 
    469                 uint32_t minheight = RT_MIN(height - ySkip, dstheight);
    470                 uint32_t minwidth = RT_MIN(width - xSkip, dstwidth);
    471 
    472                 unsigned x, y;
    473 
    474                 for (y = 0; y < minheight; y++)
     369    com::SafeArray <BYTE> aShape(ComSafeArrayInArg(inShape));
     370    if (aShape.size() == 0)
     371    {
     372        if (!visible)
     373        {
     374            MousePointerHide();
     375        }
     376    }
     377    else if (width != 0 && height != 0)
     378    {
     379        uint8_t* shape = aShape.raw();
     380
     381        dumpPointer(shape, width, height, true);
     382
     383        /* Try the new interface. */
     384        if (MousePointer(alpha, xHot, yHot, width, height, shape) == VINF_SUCCESS)
     385        {
     386            return;
     387        }
     388
     389        /* Continue with the old interface. */
     390
     391        /* Pointer consists of 1 bpp AND and 24 BPP XOR masks.
     392         * 'shape' AND mask followed by XOR mask.
     393         * XOR mask contains 32 bit (lsb)BGR0(msb) values.
     394         *
     395         * We convert this to RDP color format which consist of
     396         * one bpp AND mask and 24 BPP (BGR) color XOR image.
     397         *
     398         * RDP clients expect 8 aligned width and height of
     399         * pointer (preferably 32x32).
     400         *
     401         * They even contain bugs which do not appear for
     402         * 32x32 pointers but would appear for a 41x32 one.
     403         *
     404         * So set pointer size to 32x32. This can be done safely
     405         * because most pointers are 32x32.
     406         */
     407
     408        int cbDstAndMask = (((width + 7) / 8) * height + 3) & ~3;
     409
     410        uint8_t *pu8AndMask = shape;
     411        uint8_t *pu8XorMask = shape + cbDstAndMask;
     412
     413        if (alpha)
     414        {
     415            pu8AndMask = (uint8_t*)alloca(cbDstAndMask);
     416
     417            mousePointerGenerateANDMask(pu8AndMask, cbDstAndMask, pu8XorMask, width, height);
     418        }
     419
     420        /* Windows guest alpha pointers are wider than 32 pixels.
     421         * Try to find out the top-left border of the pointer and
     422         * then copy only meaningful bits. All complete top rows
     423         * and all complete left columns where (AND == 1 && XOR == 0)
     424         * are skipped. Hot spot is adjusted.
     425         */
     426        uint32_t ySkip = 0; /* How many rows to skip at the top. */
     427        uint32_t xSkip = 0; /* How many columns to skip at the left. */
     428
     429        findTopLeftBorder(pu8AndMask, pu8XorMask, width, height, &xSkip, &ySkip);
     430
     431        /* Must not skip the hot spot. */
     432        xSkip = RT_MIN(xSkip, xHot);
     433        ySkip = RT_MIN(ySkip, yHot);
     434
     435        /*
     436         * Compute size and allocate memory for the pointer.
     437         */
     438        const uint32_t dstwidth = 32;
     439        const uint32_t dstheight = 32;
     440
     441        VRDECOLORPOINTER *pointer = NULL;
     442
     443        uint32_t dstmaskwidth = (dstwidth + 7) / 8;
     444
     445        uint32_t rdpmaskwidth = dstmaskwidth;
     446        uint32_t rdpmasklen = dstheight * rdpmaskwidth;
     447
     448        uint32_t rdpdatawidth = dstwidth * 3;
     449        uint32_t rdpdatalen = dstheight * rdpdatawidth;
     450
     451        pointer = (VRDECOLORPOINTER *)RTMemTmpAlloc(sizeof(VRDECOLORPOINTER) + rdpmasklen + rdpdatalen);
     452
     453        if (pointer)
     454        {
     455            uint8_t *maskarray = (uint8_t*)pointer + sizeof(VRDECOLORPOINTER);
     456            uint8_t *dataarray = maskarray + rdpmasklen;
     457
     458            memset(maskarray, 0xFF, rdpmasklen);
     459            memset(dataarray, 0x00, rdpdatalen);
     460
     461            uint32_t srcmaskwidth = (width + 7) / 8;
     462            uint32_t srcdatawidth = width * 4;
     463
     464            /* Copy AND mask. */
     465            uint8_t *src = pu8AndMask + ySkip * srcmaskwidth;
     466            uint8_t *dst = maskarray + (dstheight - 1) * rdpmaskwidth;
     467
     468            uint32_t minheight = RT_MIN(height - ySkip, dstheight);
     469            uint32_t minwidth = RT_MIN(width - xSkip, dstwidth);
     470
     471            unsigned x, y;
     472
     473            for (y = 0; y < minheight; y++)
     474            {
     475                for (x = 0; x < minwidth; x++)
    475476                {
    476                     for (x = 0; x < minwidth; x++)
     477                    uint32_t byteIndex = (x + xSkip) / 8;
     478                    uint32_t bitIndex = (x + xSkip) % 8;
     479
     480                    bool bit = (src[byteIndex] & (1 << (7 - bitIndex))) != 0;
     481
     482                    if (!bit)
    477483                    {
    478                         uint32_t byteIndex = (x + xSkip) / 8;
    479                         uint32_t bitIndex = (x + xSkip) % 8;
    480 
    481                         bool bit = (src[byteIndex] & (1 << (7 - bitIndex))) != 0;
    482 
    483                         if (!bit)
    484                         {
    485                             byteIndex = x / 8;
    486                             bitIndex = x % 8;
    487 
    488                             dst[byteIndex] &= ~(1 << (7 - bitIndex));
    489                         }
     484                        byteIndex = x / 8;
     485                        bitIndex = x % 8;
     486
     487                        dst[byteIndex] &= ~(1 << (7 - bitIndex));
    490488                    }
    491 
    492                     src += srcmaskwidth;
    493                     dst -= rdpmaskwidth;
    494489                }
    495490
    496                 /* Point src to XOR mask */
    497                 src = pu8XorMask + ySkip * srcdatawidth;
    498                 dst = dataarray + (dstheight - 1) * rdpdatawidth;
    499 
    500                 for (y = 0; y < minheight ; y++)
     491                src += srcmaskwidth;
     492                dst -= rdpmaskwidth;
     493            }
     494
     495            /* Point src to XOR mask */
     496            src = pu8XorMask + ySkip * srcdatawidth;
     497            dst = dataarray + (dstheight - 1) * rdpdatawidth;
     498
     499            for (y = 0; y < minheight ; y++)
     500            {
     501                for (x = 0; x < minwidth; x++)
    501502                {
    502                     for (x = 0; x < minwidth; x++)
    503                     {
    504                         memcpy(dst + x * 3, &src[4 * (x + xSkip)], 3);
    505                     }
    506 
    507                     src += srcdatawidth;
    508                     dst -= rdpdatawidth;
     503                    memcpy(dst + x * 3, &src[4 * (x + xSkip)], 3);
    509504                }
    510505
    511                 pointer->u16HotX = (uint16_t)(xHot - xSkip);
    512                 pointer->u16HotY = (uint16_t)(yHot - ySkip);
    513 
    514                 pointer->u16Width = (uint16_t)dstwidth;
    515                 pointer->u16Height = (uint16_t)dstheight;
    516 
    517                 pointer->u16MaskLen = (uint16_t)rdpmasklen;
    518                 pointer->u16DataLen = (uint16_t)rdpdatalen;
    519 
    520                 dumpPointer((uint8_t*)pointer + sizeof(*pointer), dstwidth, dstheight, false);
    521 
    522                 m_server->MousePointerUpdate(pointer);
    523 
    524                 RTMemTmpFree(pointer);
    525             }
    526         }
    527     }
    528 
    529     return S_OK;
     506                src += srcdatawidth;
     507                dst -= rdpdatawidth;
     508            }
     509
     510            pointer->u16HotX = (uint16_t)(xHot - xSkip);
     511            pointer->u16HotY = (uint16_t)(yHot - ySkip);
     512
     513            pointer->u16Width = (uint16_t)dstwidth;
     514            pointer->u16Height = (uint16_t)dstheight;
     515
     516            pointer->u16MaskLen = (uint16_t)rdpmasklen;
     517            pointer->u16DataLen = (uint16_t)rdpdatalen;
     518
     519            dumpPointer((uint8_t*)pointer + sizeof(*pointer), dstwidth, dstheight, false);
     520
     521            MousePointerUpdate(pointer);
     522
     523            RTMemTmpFree(pointer);
     524        }
     525    }
    530526}
    531527
     
    17761772                remoteUSBThreadStart();
    17771773#endif
     1774
     1775                /*
     1776                 * Re-init the server current state, which is usually obtained from events.
     1777                 */
     1778                fetchCurrentState();
    17781779            }
    17791780            else
     
    17881789
    17891790    return vrc;
     1791}
     1792
     1793void ConsoleVRDPServer::fetchCurrentState(void)
     1794{
     1795    ComPtr<IMousePointerShape> mps;
     1796    mConsole->i_getMouse()->COMGETTER(PointerShape)(mps.asOutParam());
     1797    if (!mps.isNull())
     1798    {
     1799        BOOL  visible, alpha;
     1800        ULONG hotX, hotY, width, height;
     1801        com::SafeArray <BYTE> shape;
     1802
     1803        mps->COMGETTER(Visible)(&visible);
     1804        mps->COMGETTER(Alpha)(&alpha);
     1805        mps->COMGETTER(HotX)(&hotX);
     1806        mps->COMGETTER(HotY)(&hotY);
     1807        mps->COMGETTER(Width)(&width);
     1808        mps->COMGETTER(Height)(&height);
     1809        mps->COMGETTER(Shape)(ComSafeArrayAsOutParam(shape));
     1810
     1811        onMousePointerShapeChange(visible, alpha, hotX, hotY, width, height, ComSafeArrayAsInParam(shape));
     1812    }
    17901813}
    17911814
Note: See TracChangeset for help on using the changeset viewer.

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