VirtualBox

Changeset 98379 in vbox


Ignore:
Timestamp:
Feb 1, 2023 12:38:42 PM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
155623
Message:

Merging r155205 and r155228 from gui4 branch: FE/Qt: Runtime UI: Move mouse stuff from UISession to UIMachine; Quite a heavy and dangerous rework.

Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk

    • Property svn:mergeinfo
      •  

        old new  
        1919/branches/dsen/gui2:79224,79228,79233,79235,79258,79262-79263,79273,79341,79345,79354,79357,79387-79388,79559-79569,79572-79573,79578,79581-79582,79590-79591,79598-79599,79602-79603,79605-79606,79632,79635,79637,79644
        2020/branches/dsen/gui3:79645-79692
        21 /branches/dsen/gui4:155183-155185,155187,155198,155200-155201
         21/branches/dsen/gui4:155183-155185,155187,155198,155200-155201,155205,155228
        2222/trunk/src:92342,154921
  • trunk/src/VBox

    • Property svn:mergeinfo
      •  

        old new  
        1919/branches/dsen/gui2/src/VBox:79224,79228,79233,79235,79258,79262-79263,79273,79341,79345,79354,79357,79387-79388,79559-79569,79572-79573,79578,79581-79582,79590-79591,79598-79599,79602-79603,79605-79606,79632,79635,79637,79644
        2020/branches/dsen/gui3/src/VBox:79645-79692
        21 /branches/dsen/gui4/src/VBox:155183-155185,155187,155198,155200-155201
         21/branches/dsen/gui4/src/VBox:155183-155185,155187,155198,155200-155201,155205,155228
  • trunk/src/VBox/Frontends

    • Property svn:mergeinfo
      •  

        old new  
        1616/branches/dsen/gui2/src/VBox/Frontends:79224,79228,79233,79235,79258,79262-79263,79273,79341,79345,79354,79357,79387-79388,79559-79569,79572-79573,79578,79581-79582,79590-79591,79598-79599,79602-79603,79605-79606,79632,79635,79637,79644
        1717/branches/dsen/gui3/src/VBox/Frontends:79645-79692
        18 /branches/dsen/gui4/src/VBox/Frontends:155183-155185,155187,155198,155200-155201
         18/branches/dsen/gui4/src/VBox/Frontends:155183-155185,155187,155198,155200-155201,155205,155228
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp

    r98103 r98379  
    3737#include "UIFrameBuffer.h"
    3838#include "UISession.h"
     39#include "UIMachine.h"
    3940#include "UIMachineLogic.h"
    4041#include "UIMachineWindow.h"
     
    19441945     * framebuffer cursor if mouse integration is supported and enabled. */
    19451946    if (   m_pMachineView
    1946         && !m_pMachineView->uisession()->isHidingHostPointer()
    1947         && m_pMachineView->uisession()->isValidPointerShapePresent()
    1948         && m_pMachineView->uisession()->isValidCursorPositionPresent()
    1949         && (   !m_pMachineView->uisession()->isMouseIntegrated()
    1950             || !m_pMachineView->uisession()->isMouseSupportsAbsolute()))
     1947        && !m_pMachineView->uimachine()->isHidingHostPointer()
     1948        && m_pMachineView->uimachine()->isValidPointerShapePresent()
     1949        && m_pMachineView->uimachine()->isValidCursorPositionPresent()
     1950        && (   !m_pMachineView->uimachine()->isMouseIntegrated()
     1951            || !m_pMachineView->uimachine()->isMouseSupportsAbsolute()))
    19511952    {
    19521953        /* Acquire cursor hotspot: */
    1953         QPoint cursorHotspot = m_pMachineView->uisession()->cursorHotspot();
     1954        QPoint cursorHotspot = m_pMachineView->uimachine()->cursorHotspot();
    19541955        /* Apply the scale-factor if necessary: */
    19551956        cursorHotspot /= scaleFactor();
     
    19591960
    19601961        /* Acquire cursor position and size: */
    1961         QPoint cursorPosition = m_pMachineView->uisession()->cursorPosition() - cursorHotspot;
    1962         QSize cursorSize = m_pMachineView->uisession()->cursorSize();
     1962        QPoint cursorPosition = m_pMachineView->uimachine()->cursorPosition() - cursorHotspot;
     1963        QSize cursorSize = m_pMachineView->uimachine()->cursorSize();
    19631964        /* Apply the scale-factor if necessary: */
    19641965        cursorPosition *= scaleFactor();
     
    20042005
    20052006    /* Attach GUI connections: */
    2006     connect(m_pMachineView->uisession(), &UISession::sigMousePointerShapeChange,
     2007    connect(m_pMachineView->uimachine(), &UIMachine::sigMousePointerShapeChange,
    20072008            this, &UIFrameBufferPrivate::sltMousePointerShapeOrPositionChange);
    2008     connect(m_pMachineView->uisession(), &UISession::sigCursorPositionChange,
     2009    connect(m_pMachineView->uimachine(), &UIMachine::sigCursorPositionChange,
    20092010            this, &UIFrameBufferPrivate::sltMousePointerShapeOrPositionChange);
    20102011}
     
    20212022
    20222023    /* Detach GUI connections: */
    2023     disconnect(m_pMachineView->uisession(), &UISession::sigMousePointerShapeChange,
     2024    disconnect(m_pMachineView->uimachine(), &UIMachine::sigMousePointerShapeChange,
    20242025               this, &UIFrameBufferPrivate::sltMousePointerShapeOrPositionChange);
    2025     disconnect(m_pMachineView->uisession(), &UISession::sigCursorPositionChange,
     2026    disconnect(m_pMachineView->uimachine(), &UIMachine::sigCursorPositionChange,
    20262027               this, &UIFrameBufferPrivate::sltMousePointerShapeOrPositionChange);
    20272028}
     
    21432144     * framebuffer cursor if mouse integration is supported and enabled. */
    21442145    if (   !m_cursorRectangle.isNull()
    2145         && !m_pMachineView->uisession()->isHidingHostPointer()
    2146         && m_pMachineView->uisession()->isValidPointerShapePresent()
    2147         && m_pMachineView->uisession()->isValidCursorPositionPresent()
    2148         && (   !m_pMachineView->uisession()->isMouseIntegrated()
    2149             || !m_pMachineView->uisession()->isMouseSupportsAbsolute()))
     2146        && !m_pMachineView->uimachine()->isHidingHostPointer()
     2147        && m_pMachineView->uimachine()->isValidPointerShapePresent()
     2148        && m_pMachineView->uimachine()->isValidCursorPositionPresent()
     2149        && (   !m_pMachineView->uimachine()->isMouseIntegrated()
     2150            || !m_pMachineView->uimachine()->isMouseSupportsAbsolute()))
    21502151    {
    21512152        /* Acquire session cursor shape pixmap: */
    2152         QPixmap cursorPixmap = m_pMachineView->uisession()->cursorShapePixmap();
     2153        QPixmap cursorPixmap = m_pMachineView->uimachine()->cursorShapePixmap();
    21532154
    21542155        /* Take the device-pixel-ratio into account: */
     
    22532254     * framebuffer cursor if mouse integration is supported and enabled. */
    22542255    if (   !m_cursorRectangle.isNull()
    2255         && !m_pMachineView->uisession()->isHidingHostPointer()
    2256         && m_pMachineView->uisession()->isValidPointerShapePresent()
    2257         && m_pMachineView->uisession()->isValidCursorPositionPresent()
    2258         && (   !m_pMachineView->uisession()->isMouseIntegrated()
    2259             || !m_pMachineView->uisession()->isMouseSupportsAbsolute()))
     2256        && !m_pMachineView->uimachine()->isHidingHostPointer()
     2257        && m_pMachineView->uimachine()->isValidPointerShapePresent()
     2258        && m_pMachineView->uimachine()->isValidCursorPositionPresent()
     2259        && (   !m_pMachineView->uimachine()->isMouseIntegrated()
     2260            || !m_pMachineView->uimachine()->isMouseSupportsAbsolute()))
    22602261    {
    22612262        /* Acquire session cursor shape pixmap: */
    2262         QPixmap cursorPixmap = m_pMachineView->uisession()->cursorShapePixmap();
     2263        QPixmap cursorPixmap = m_pMachineView->uimachine()->cursorShapePixmap();
    22632264
    22642265        /* Take the device-pixel-ratio into account: */
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIIndicatorsPool.cpp

    r98375 r98379  
    11811181        setStateIcon(4, UIIconPool::iconSet(":/mouse_can_seamless_uncaptured_16px.png"));
    11821182        /* Configure connection: */
    1183         connect(pSession, &UISession::sigMouseStateChange,
     1183        connect(m_pMachine, &UIMachine::sigMouseStateChange,
    11841184                this, static_cast<void(UIIndicatorMouse::*)(int)>(&UIIndicatorMouse::setState));
    1185         setState(pSession->mouseState());
     1185        setState(m_pMachine->mouseState());
    11861186        /* Translate finally: */
    11871187        retranslateUi();
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp

    r98378 r98379  
    14301430        {
    14311431            releaseKeyboard();
    1432             if (!uisession()->isMouseSupportsAbsolute() || !uisession()->isMouseIntegrated())
     1432            if (!uimachine()->isMouseSupportsAbsolute() || !uimachine()->isMouseIntegrated())
    14331433                machineLogic()->mouseHandler()->releaseMouse();
    14341434        }
     
    15631563                {
    15641564                    /* Determine whether the mouse can be captured: */
    1565                     bool fCaptureMouse =    !uisession()->isMouseSupportsAbsolute()
    1566                                          || !uisession()->isMouseIntegrated();
     1565                    bool fCaptureMouse =    !uimachine()->isMouseSupportsAbsolute()
     1566                                         || !uimachine()->isMouseIntegrated();
    15671567
    15681568                    if (m_fIsKeyboardCaptured)
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp

    r98378 r98379  
    2626 */
    2727
     28/* Qt includes: */
     29#ifdef VBOX_WS_WIN
     30# include <QBitmap>
     31#endif
     32
    2833/* GUI includes: */
    2934#include "UICommon.h"
     
    214219}
    215220
     221void UIMachine::sltMousePointerShapeChange(const UIMousePointerShapeData &shapeData)
     222{
     223    LogRelFlow(("GUI: UIMachine::sltMousePointerShapeChange: "
     224                "Is visible: %s, Has alpha: %s, "
     225                "Hot spot: %dx%d, Shape size: %dx%d, "
     226                "Shape data: %s\n",
     227                shapeData.isVisible() ? "TRUE" : "FALSE",
     228                shapeData.hasAlpha() ? "TRUE" : "FALSE",
     229                shapeData.hotSpot().x(), shapeData.hotSpot().y(),
     230                shapeData.shapeSize().width(), shapeData.shapeSize().height(),
     231                shapeData.shape().isEmpty() ? "EMPTY" : "PRESENT"));
     232
     233    /* In case if shape itself is present: */
     234    if (shapeData.shape().size() > 0)
     235    {
     236        /* We are ignoring visibility flag: */
     237        m_fIsHidingHostPointer = false;
     238
     239        /* And updating current shape data: */
     240        m_shapeData = shapeData;
     241        updateMousePointerShape();
     242    }
     243    /* In case if shape itself is NOT present: */
     244    else
     245    {
     246        /* Remember if we should hide the cursor: */
     247        m_fIsHidingHostPointer = !shapeData.isVisible();
     248    }
     249
     250    /* Notify listeners: */
     251    emit sigMousePointerShapeChange();
     252}
     253
     254void UIMachine::sltMouseCapabilityChange(bool fSupportsAbsolute, bool fSupportsRelative,
     255                                         bool fSupportsTouchScreen, bool fSupportsTouchPad,
     256                                         bool fNeedsHostCursor)
     257{
     258    LogRelFlow(("GUI: UIMachine::sltMouseCapabilityChange: "
     259                "Supports absolute: %s, Supports relative: %s, "
     260                "Supports touchscreen: %s, Supports touchpad: %s, "
     261                "Needs host cursor: %s\n",
     262                fSupportsAbsolute ? "TRUE" : "FALSE", fSupportsRelative ? "TRUE" : "FALSE",
     263                fSupportsTouchScreen ? "TRUE" : "FALSE", fSupportsTouchPad ? "TRUE" : "FALSE",
     264                fNeedsHostCursor ? "TRUE" : "FALSE"));
     265
     266    /* Check if something had changed: */
     267    if (   m_fIsMouseSupportsAbsolute != fSupportsAbsolute
     268        || m_fIsMouseSupportsRelative != fSupportsRelative
     269        || m_fIsMouseSupportsTouchScreen != fSupportsTouchScreen
     270        || m_fIsMouseSupportsTouchPad != fSupportsTouchPad
     271        || m_fIsMouseHostCursorNeeded != fNeedsHostCursor)
     272    {
     273        /* Store new data: */
     274        m_fIsMouseSupportsAbsolute = fSupportsAbsolute;
     275        m_fIsMouseSupportsRelative = fSupportsRelative;
     276        m_fIsMouseSupportsTouchScreen = fSupportsTouchScreen;
     277        m_fIsMouseSupportsTouchPad = fSupportsTouchPad;
     278        m_fIsMouseHostCursorNeeded = fNeedsHostCursor;
     279
     280        /* Notify listeners: */
     281        emit sigMouseCapabilityChange();
     282    }
     283}
     284
     285void UIMachine::sltCursorPositionChange(bool fContainsData, unsigned long uX, unsigned long uY)
     286{
     287    LogRelFlow(("GUI: UIMachine::sltCursorPositionChange: "
     288                "Cursor position valid: %d, Cursor position: %dx%d\n",
     289                fContainsData ? "TRUE" : "FALSE", uX, uY));
     290
     291    /* Check if something had changed: */
     292    if (   m_fIsValidCursorPositionPresent != fContainsData
     293        || m_cursorPosition.x() != (int)uX
     294        || m_cursorPosition.y() != (int)uY)
     295    {
     296        /* Store new data: */
     297        m_fIsValidCursorPositionPresent = fContainsData;
     298        m_cursorPosition = QPoint(uX, uY);
     299
     300        /* Notify listeners: */
     301        emit sigCursorPositionChange();
     302    }
     303}
     304
    216305UIMachine::UIMachine()
    217306    : QObject(0)
     
    223312    , m_pMachineLogic(0)
    224313    , m_pMachineWindowIcon(0)
     314    , m_fIsHidingHostPointer(true)
     315    , m_fIsValidPointerShapePresent(false)
     316    , m_fIsValidCursorPositionPresent(false)
     317    , m_fIsMouseSupportsAbsolute(false)
     318    , m_fIsMouseSupportsRelative(false)
     319    , m_fIsMouseSupportsTouchScreen(false)
     320    , m_fIsMouseSupportsTouchPad(false)
     321    , m_fIsMouseHostCursorNeeded(false)
     322    , m_fIsMouseCaptured(false)
     323    , m_fIsMouseIntegrated(true)
     324    , m_iMouseState(0)
    225325{
    226326    m_spInstance = this;
     
    246346
    247347    /* Prepare stuff: */
     348    prepareSessionConnections();
    248349    prepareMachineWindowIcon();
    249350    prepareMachineLogic();
     
    256357        return false;
    257358
     359    /* Update stuff: */
     360    updateMouseState();
     361
    258362    /* True by default: */
    259363    return true;
     364}
     365
     366void UIMachine::prepareSessionConnections()
     367{
     368    connect(uisession(), &UISession::sigMousePointerShapeChange,
     369            this, &UIMachine::sltMousePointerShapeChange);
     370    connect(uisession(), &UISession::sigMouseCapabilityChange,
     371            this, &UIMachine::sltMouseCapabilityChange);
     372    connect(uisession(), &UISession::sigCursorPositionChange,
     373            this, &UIMachine::sltCursorPositionChange);
    260374}
    261375
     
    362476    sltChangeVisualState(m_initialVisualState);
    363477}
     478
     479void UIMachine::updateMousePointerShape()
     480{
     481    /* Fetch incoming shape data: */
     482    const bool fHasAlpha = m_shapeData.hasAlpha();
     483    const uint uWidth = m_shapeData.shapeSize().width();
     484    const uint uHeight = m_shapeData.shapeSize().height();
     485    const uchar *pShapeData = m_shapeData.shape().constData();
     486    AssertMsgReturnVoid(pShapeData, ("Shape data must not be NULL!\n"));
     487
     488    /* Invalidate mouse pointer shape initially: */
     489    m_fIsValidPointerShapePresent = false;
     490    m_cursorShapePixmap = QPixmap();
     491    m_cursorMaskPixmap = QPixmap();
     492
     493    /* Parse incoming shape data: */
     494    const uchar *pSrcAndMaskPtr = pShapeData;
     495    const uint uAndMaskSize = (uWidth + 7) / 8 * uHeight;
     496    const uchar *pSrcShapePtr = pShapeData + ((uAndMaskSize + 3) & ~3);
     497
     498#if defined (VBOX_WS_WIN)
     499
     500    /* Create an ARGB image out of the shape data: */
     501
     502    // WORKAROUND:
     503    // Qt5 QCursor recommends 32 x 32 cursor, therefore the original data is copied to
     504    // a larger QImage if necessary. Cursors like 10x16 did not work correctly (Solaris 10 guest).
     505    // Align the cursor dimensions to 32 bit pixels, because for example a 56x56 monochrome cursor
     506    // did not work correctly on Windows host.
     507    const uint uCursorWidth = RT_ALIGN_32(uWidth, 32);
     508    const uint uCursorHeight = RT_ALIGN_32(uHeight, 32);
     509
     510    if (fHasAlpha)
     511    {
     512        QImage image(uCursorWidth, uCursorHeight, QImage::Format_ARGB32);
     513        memset(image.bits(), 0, image.byteCount());
     514
     515        const uint32_t *pu32SrcShapeScanline = (uint32_t *)pSrcShapePtr;
     516        for (uint y = 0; y < uHeight; ++y, pu32SrcShapeScanline += uWidth)
     517            memcpy(image.scanLine(y), pu32SrcShapeScanline, uWidth * sizeof(uint32_t));
     518
     519        m_cursorShapePixmap = QPixmap::fromImage(image);
     520    }
     521    else
     522    {
     523        if (isPointer1bpp(pSrcShapePtr, uWidth, uHeight))
     524        {
     525            // Incoming data consist of 32 bit BGR XOR mask and 1 bit AND mask.
     526            // XOR pixels contain either 0x00000000 or 0x00FFFFFF.
     527            //
     528            // Originally intended result (F denotes 0x00FFFFFF):
     529            // XOR AND
     530            //   0   0 black
     531            //   F   0 white
     532            //   0   1 transparent
     533            //   F   1 xor'd
     534            //
     535            // Actual Qt5 result for color table 0:0xFF000000, 1:0xFFFFFFFF
     536            // (tested on Windows 7 and 10 64 bit hosts):
     537            // Bitmap Mask
     538            //  0   0 black
     539            //  1   0 white
     540            //  0   1 xor
     541            //  1   1 transparent
     542
     543            QVector<QRgb> colors(2);
     544            colors[0] = UINT32_C(0xFF000000);
     545            colors[1] = UINT32_C(0xFFFFFFFF);
     546
     547            QImage bitmap(uCursorWidth, uCursorHeight, QImage::Format_Mono);
     548            bitmap.setColorTable(colors);
     549            memset(bitmap.bits(), 0xFF, bitmap.byteCount());
     550
     551            QImage mask(uCursorWidth, uCursorHeight, QImage::Format_Mono);
     552            mask.setColorTable(colors);
     553            memset(mask.bits(), 0xFF, mask.byteCount());
     554
     555            const uint8_t *pu8SrcAndScanline = pSrcAndMaskPtr;
     556            const uint32_t *pu32SrcShapeScanline = (uint32_t *)pSrcShapePtr;
     557            for (uint y = 0; y < uHeight; ++y)
     558            {
     559                for (uint x = 0; x < uWidth; ++x)
     560                {
     561                    const uint8_t u8Bit = (uint8_t)(1 << (7 - x % 8));
     562
     563                    const uint8_t u8SrcMaskByte = pu8SrcAndScanline[x / 8];
     564                    const uint8_t u8SrcMaskBit = u8SrcMaskByte & u8Bit;
     565                    const uint32_t u32SrcPixel = pu32SrcShapeScanline[x] & UINT32_C(0xFFFFFF);
     566
     567                    uint8_t *pu8DstMaskByte = &mask.scanLine(y)[x / 8];
     568                    uint8_t *pu8DstBitmapByte = &bitmap.scanLine(y)[x / 8];
     569
     570                    if (u8SrcMaskBit == 0)
     571                    {
     572                        if (u32SrcPixel == 0)
     573                        {
     574                            /* Black: Qt Bitmap = 0, Mask = 0 */
     575                            *pu8DstMaskByte &= ~u8Bit;
     576                            *pu8DstBitmapByte &= ~u8Bit;
     577                        }
     578                        else
     579                        {
     580                            /* White: Qt Bitmap = 1, Mask = 0 */
     581                            *pu8DstMaskByte &= ~u8Bit;
     582                            *pu8DstBitmapByte |= u8Bit;
     583                        }
     584                    }
     585                    else
     586                    {
     587                        if (u32SrcPixel == 0)
     588                        {
     589                            /* Transparent: Qt Bitmap = 1, Mask = 1 */
     590                            *pu8DstMaskByte |= u8Bit;
     591                            *pu8DstBitmapByte |= u8Bit;
     592                        }
     593                        else
     594                        {
     595                            /* Xor'ed: Qt Bitmap = 0, Mask = 1 */
     596                            *pu8DstMaskByte |= u8Bit;
     597                            *pu8DstBitmapByte &= ~u8Bit;
     598                        }
     599                    }
     600                }
     601
     602                pu8SrcAndScanline += (uWidth + 7) / 8;
     603                pu32SrcShapeScanline += uWidth;
     604            }
     605
     606            m_cursorShapePixmap = QBitmap::fromImage(bitmap);
     607            m_cursorMaskPixmap = QBitmap::fromImage(mask);
     608        }
     609        else
     610        {
     611            /* Assign alpha channel values according to the AND mask: 1 -> 0x00, 0 -> 0xFF: */
     612            QImage image(uCursorWidth, uCursorHeight, QImage::Format_ARGB32);
     613            memset(image.bits(), 0, image.byteCount());
     614
     615            const uint8_t *pu8SrcAndScanline = pSrcAndMaskPtr;
     616            const uint32_t *pu32SrcShapeScanline = (uint32_t *)pSrcShapePtr;
     617
     618            for (uint y = 0; y < uHeight; ++y)
     619            {
     620                uint32_t *pu32DstPixel = (uint32_t *)image.scanLine(y);
     621
     622                for (uint x = 0; x < uWidth; ++x)
     623                {
     624                    const uint8_t u8Bit = (uint8_t)(1 << (7 - x % 8));
     625                    const uint8_t u8SrcMaskByte = pu8SrcAndScanline[x / 8];
     626
     627                    if (u8SrcMaskByte & u8Bit)
     628                        *pu32DstPixel++ = pu32SrcShapeScanline[x] & UINT32_C(0x00FFFFFF);
     629                    else
     630                        *pu32DstPixel++ = pu32SrcShapeScanline[x] | UINT32_C(0xFF000000);
     631                }
     632
     633                pu32SrcShapeScanline += uWidth;
     634                pu8SrcAndScanline += (uWidth + 7) / 8;
     635            }
     636
     637            m_cursorShapePixmap = QPixmap::fromImage(image);
     638        }
     639    }
     640
     641    /* Mark mouse pointer shape valid: */
     642    m_fIsValidPointerShapePresent = true;
     643
     644#elif defined(VBOX_WS_X11) || defined(VBOX_WS_MAC)
     645
     646    /* Create an ARGB image out of the shape data: */
     647    QImage image(uWidth, uHeight, QImage::Format_ARGB32);
     648
     649    if (fHasAlpha)
     650    {
     651        memcpy(image.bits(), pSrcShapePtr, uHeight * uWidth * 4);
     652    }
     653    else
     654    {
     655        renderCursorPixels((uint32_t *)pSrcShapePtr, pSrcAndMaskPtr,
     656                           uWidth, uHeight,
     657                           (uint32_t *)image.bits(), uHeight * uWidth * 4);
     658    }
     659
     660    /* Create cursor-pixmap from the image: */
     661    m_cursorShapePixmap = QPixmap::fromImage(image);
     662
     663    /* Mark mouse pointer shape valid: */
     664    m_fIsValidPointerShapePresent = true;
     665
     666#else
     667
     668# warning "port me"
     669
     670#endif
     671
     672    /* Cache cursor pixmap size and hotspot: */
     673    m_cursorSize = m_cursorShapePixmap.size();
     674    m_cursorHotspot = m_shapeData.hotSpot();
     675}
     676
     677void UIMachine::updateMouseState()
     678{
     679    m_fIsMouseSupportsAbsolute = uisession()->mouse().GetAbsoluteSupported();
     680    m_fIsMouseSupportsRelative = uisession()->mouse().GetRelativeSupported();
     681    m_fIsMouseSupportsTouchScreen = uisession()->mouse().GetTouchScreenSupported();
     682    m_fIsMouseSupportsTouchPad = uisession()->mouse().GetTouchPadSupported();
     683    m_fIsMouseHostCursorNeeded = uisession()->mouse().GetNeedsHostCursor();
     684}
     685
     686#if defined(VBOX_WS_X11) || defined(VBOX_WS_MAC)
     687/* static */
     688void UIMachine::renderCursorPixels(const uint32_t *pu32XOR, const uint8_t *pu8AND,
     689                                   uint32_t u32Width, uint32_t u32Height,
     690                                   uint32_t *pu32Pixels, uint32_t cbPixels)
     691{
     692    /* Output pixels set to 0 which allow to not write transparent pixels anymore. */
     693    memset(pu32Pixels, 0, cbPixels);
     694
     695    const uint32_t *pu32XORSrc = pu32XOR;  /* Iterator for source XOR pixels. */
     696    const uint8_t *pu8ANDSrcLine = pu8AND; /* The current AND mask scanline. */
     697    uint32_t *pu32Dst = pu32Pixels;        /* Iterator for all destination BGRA pixels. */
     698
     699    /* Some useful constants. */
     700    const int cbANDLine = ((int)u32Width + 7) / 8;
     701
     702    int y;
     703    for (y = 0; y < (int)u32Height; ++y)
     704    {
     705        int x;
     706        for (x = 0; x < (int)u32Width; ++x)
     707        {
     708            const uint32_t u32Pixel = *pu32XORSrc; /* Current pixel at (x,y) */
     709            const uint8_t *pu8ANDSrc = pu8ANDSrcLine + x / 8; /* Byte which containt current AND bit. */
     710
     711            if ((*pu8ANDSrc << (x % 8)) & 0x80)
     712            {
     713                if (u32Pixel)
     714                {
     715                    const uint32_t u32PixelInverted = ~u32Pixel;
     716
     717                    /* Scan neighbor pixels and assign them if they are transparent. */
     718                    int dy;
     719                    for (dy = -1; dy <= 1; ++dy)
     720                    {
     721                        const int yn = y + dy;
     722                        if (yn < 0 || yn >= (int)u32Height)
     723                            continue; /* Do not cross the bounds. */
     724
     725                        int dx;
     726                        for (dx = -1; dx <= 1; ++dx)
     727                        {
     728                            const int xn = x + dx;
     729                            if (xn < 0 || xn >= (int)u32Width)
     730                                continue;  /* Do not cross the bounds. */
     731
     732                            if (dx != 0 || dy != 0)
     733                            {
     734                                /* Check if the neighbor pixel is transparent. */
     735                                const uint32_t *pu32XORNeighborSrc = &pu32XORSrc[dy * (int)u32Width + dx];
     736                                const uint8_t *pu8ANDNeighborSrc = pu8ANDSrcLine + dy * cbANDLine + xn / 8;
     737                                if (   *pu32XORNeighborSrc == 0
     738                                    && ((*pu8ANDNeighborSrc << (xn % 8)) & 0x80) != 0)
     739                                {
     740                                    /* Transparent neighbor pixels are replaced with the source pixel value. */
     741                                    uint32_t *pu32PixelNeighborDst = &pu32Dst[dy * (int)u32Width + dx];
     742                                    *pu32PixelNeighborDst = u32Pixel | 0xFF000000;
     743                                }
     744                            }
     745                            else
     746                            {
     747                                /* The pixel itself is replaced with inverted value. */
     748                                *pu32Dst = u32PixelInverted | 0xFF000000;
     749                            }
     750                        }
     751                    }
     752                }
     753                else
     754                {
     755                    /* The pixel does not affect the screen.
     756                     * Do nothing. Do not touch destination which can already contain generated pixels.
     757                     */
     758                }
     759            }
     760            else
     761            {
     762                /* AND bit is 0, the pixel will be just drawn. */
     763                *pu32Dst = u32Pixel | 0xFF000000;
     764            }
     765
     766            ++pu32XORSrc; /* Next source pixel. */
     767            ++pu32Dst;    /* Next destination pixel. */
     768        }
     769
     770        /* Next AND scanline. */
     771        pu8ANDSrcLine += cbANDLine;
     772    }
     773}
     774#endif /* VBOX_WS_X11 || VBOX_WS_MAC */
     775
     776#ifdef VBOX_WS_WIN
     777/* static */
     778bool UIMachine::isPointer1bpp(const uint8_t *pu8XorMask,
     779                              uint uWidth,
     780                              uint uHeight)
     781{
     782    /* Check if the pointer has only 0 and 0xFFFFFF pixels, ignoring the alpha channel. */
     783    const uint32_t *pu32Src = (uint32_t *)pu8XorMask;
     784
     785    uint y;
     786    for (y = 0; y < uHeight ; ++y)
     787    {
     788        uint x;
     789        for (x = 0; x < uWidth; ++x)
     790        {
     791            const uint32_t u32Pixel = pu32Src[x] & UINT32_C(0xFFFFFF);
     792            if (u32Pixel != 0 && u32Pixel != UINT32_C(0xFFFFFF))
     793                return false;
     794        }
     795
     796        pu32Src += uWidth;
     797    }
     798
     799    return true;
     800}
     801#endif /* VBOX_WS_WIN */
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.h

    r98378 r98379  
    3434/* Qt includes: */
    3535#include <QObject>
     36#include <QPixmap>
    3637
    3738/* GUI includes: */
    3839#include "UIExtraDataDefs.h"
    3940#include "UIMachineDefs.h"
     41#include "UIMousePointerShapeData.h"
    4042
    4143/* COM includes: */
     
    5759    /** Requests async visual-state change. */
    5860    void sigRequestAsyncVisualStateChange(UIVisualStateType visualStateType);
     61
     62    /** @name Mouse cursor stuff.
     63     ** @{ */
     64        /** Notifies listeners about mouse pointer shape change. */
     65        void sigMousePointerShapeChange();
     66        /** Notifies listeners about mouse capability change. */
     67        void sigMouseCapabilityChange();
     68        /** Notifies listeners about cursor position change. */
     69        void sigCursorPositionChange();
     70
     71        /** Notifies listeners about mouse state-change. */
     72        void sigMouseStateChange(int iState);
     73    /** @} */
    5974
    6075public:
     
    98113    /** @} */
    99114
     115    /** @name Mouse cursor stuff.
     116     ** @{ */
     117        /** Returns whether we should hide host mouse pointer. */
     118        bool isHidingHostPointer() const { return m_fIsHidingHostPointer; }
     119        /** Returns whether there is valid mouse pointer shape present. */
     120        bool isValidPointerShapePresent() const { return m_fIsValidPointerShapePresent; }
     121        /** Returns whether the @a cursorPosition() is valid and could be used by the GUI now. */
     122        bool isValidCursorPositionPresent() const { return m_fIsValidCursorPositionPresent; }
     123
     124        /** Returns whether mouse supports absolute coordinates. */
     125        bool isMouseSupportsAbsolute() const { return m_fIsMouseSupportsAbsolute; }
     126        /** Returns whether mouse supports relative coordinates. */
     127        bool isMouseSupportsRelative() const { return m_fIsMouseSupportsRelative; }
     128        /** Returns whether touch screen is supported. */
     129        bool isMouseSupportsTouchScreen() const { return m_fIsMouseSupportsTouchScreen; }
     130        /** Returns whether touch pad is supported. */
     131        bool isMouseSupportsTouchPad() const { return m_fIsMouseSupportsTouchPad; }
     132        /** Returns whether guest requires host cursor to be shown. */
     133        bool isMouseHostCursorNeeded() const { return m_fIsMouseHostCursorNeeded; }
     134
     135        /** Returns whether mouse is captured. */
     136        bool isMouseCaptured() const { return m_fIsMouseCaptured; }
     137        /** Returns whether mouse is integrated. */
     138        bool isMouseIntegrated() const { return m_fIsMouseIntegrated; }
     139        /** Defines whether mouse is @a fCaptured. */
     140        void setMouseCaptured(bool fCaptured) { m_fIsMouseCaptured = fCaptured; }
     141        /** Defines whether mouse is @a fIntegrated. */
     142        void setMouseIntegrated(bool fIntegrated) { m_fIsMouseIntegrated = fIntegrated; }
     143
     144        /** Returns currently cached mouse cursor shape pixmap. */
     145        QPixmap cursorShapePixmap() const { return m_cursorShapePixmap; }
     146        /** Returns currently cached mouse cursor mask pixmap. */
     147        QPixmap cursorMaskPixmap() const { return m_cursorMaskPixmap; }
     148        /** Returns currently cached mouse cursor size. */
     149        QSize cursorSize() const { return m_cursorSize; }
     150        /** Returns currently cached mouse cursor hotspot. */
     151        QPoint cursorHotspot() const { return m_cursorHotspot; }
     152        /** Returns currently cached mouse cursor position. */
     153        QPoint cursorPosition() const { return m_cursorPosition; }
     154
     155        /** Returns mouse-state. */
     156        int mouseState() const { return m_iMouseState; }
     157    /** @} */
     158
    100159public slots:
     160
     161    /** @name Mouse cursor stuff.
     162     ** @{ */
     163        /** Defines @a iMouseState. */
     164        void setMouseState(int iMouseState) { m_iMouseState = iMouseState; emit sigMouseStateChange(m_iMouseState); }
     165    /** @} */
    101166
    102167    /** Closes Runtime UI. */
     
    107172    /** Visual state-change handler. */
    108173    void sltChangeVisualState(UIVisualStateType visualStateType);
     174
     175    /** @name Mouse cursor stuff.
     176     ** @{ */
     177        /** Handles signal about mouse pointer shape data change.
     178          * @param  shapeData  Brings complex struct describing mouse pointer shape aspects. */
     179        void sltMousePointerShapeChange(const UIMousePointerShapeData &shapeData);
     180        /** Handles signal about mouse capability change.
     181          * @param  fSupportsAbsolute     Brings whether mouse supports absolute coordinates.
     182          * @param  fSupportsRelative     Brings whether mouse supports relative coordinates.
     183          * @param  fSupportsTouchScreen  Brings whether touch screen is supported.
     184          * @param  fSupportsTouchPad     Brings whether touch pad is supported.
     185          * @param  fNeedsHostCursor      Brings whether guest requires host cursor to be shown. */
     186        void sltMouseCapabilityChange(bool fSupportsAbsolute, bool fSupportsRelative,
     187                                      bool fSupportsTouchScreen, bool fSupportsTouchPad,
     188                                      bool fNeedsHostCursor);
     189        /** Handles signal about guest request to change the cursor position to @a uX * @a uY.
     190          * @param  fContainsData  Brings whether the @a uX and @a uY values are valid and could be used by the GUI now.
     191          * @param  uX             Brings cursor position X origin.
     192          * @param  uY             Brings cursor position Y origin. */
     193        void sltCursorPositionChange(bool fContainsData,
     194                                     unsigned long uX,
     195                                     unsigned long uY);
     196    /** @} */
    109197
    110198private:
     
    117205    /** Prepare routine. */
    118206    bool prepare();
     207    /** Prepare routine: Session connection stuff. */
     208    void prepareSessionConnections();
    119209    /** Prepare routine: Machine-window icon. */
    120210    void prepareMachineWindowIcon();
     
    136226    /** Moves VM to initial state. */
    137227    void enterInitialVisualState();
     228
     229    /** @name Mouse cursor stuff.
     230     ** @{ */
     231        /** Updates mouse pointer shape. */
     232        void updateMousePointerShape();
     233
     234        /** Updates mouse states. */
     235        void updateMouseState();
     236
     237#if defined(VBOX_WS_X11) || defined(VBOX_WS_MAC)
     238        /** Generate a BGRA bitmap which approximates a XOR/AND mouse pointer.
     239          *
     240          * Pixels which has 1 in the AND mask and not 0 in the XOR mask are replaced by
     241          * the inverted pixel and 8 surrounding pixels with the original color.
     242          * Fort example a white pixel (W) is replaced with a black (B) pixel:
     243          *         WWW
     244          *  W   -> WBW
     245          *         WWW
     246          * The surrounding pixels are written only if the corresponding source pixel
     247          * does not affect the screen, i.e. AND bit is 1 and XOR value is 0. */
     248        static void renderCursorPixels(const uint32_t *pu32XOR, const uint8_t *pu8AND,
     249                                       uint32_t u32Width, uint32_t u32Height,
     250                                       uint32_t *pu32Pixels, uint32_t cbPixels);
     251#endif /* VBOX_WS_X11 || VBOX_WS_MAC */
     252
     253#ifdef VBOX_WS_WIN
     254        static bool isPointer1bpp(const uint8_t *pu8XorMask,
     255                                  uint uWidth,
     256                                  uint uHeight);
     257#endif /* VBOX_WS_WIN */
     258    /** @} */
    138259
    139260    /** Static instance. */
     
    164285#endif
    165286    /** @} */
     287
     288    /** @name Mouse cursor stuff.
     289     ** @{ */
     290        /** Holds whether we should hide host mouse pointer. */
     291        bool  m_fIsHidingHostPointer;
     292        /** Holds whether there is valid mouse pointer shape present. */
     293        bool  m_fIsValidPointerShapePresent;
     294        /** Holds whether the @a m_cursorPosition is valid and could be used by the GUI now. */
     295        bool  m_fIsValidCursorPositionPresent;
     296
     297        /** Holds whether mouse supports absolute coordinates. */
     298        bool  m_fIsMouseSupportsAbsolute;
     299        /** Holds whether mouse supports relative coordinates. */
     300        bool  m_fIsMouseSupportsRelative;
     301        /** Holds whether touch screen is supported. */
     302        bool  m_fIsMouseSupportsTouchScreen;
     303        /** Holds whether touch pad is supported. */
     304        bool  m_fIsMouseSupportsTouchPad;
     305        /** Holds whether guest requires host cursor to be shown. */
     306        bool  m_fIsMouseHostCursorNeeded;
     307
     308        /** Holds whether mouse is captured. */
     309        bool  m_fIsMouseCaptured;
     310        /** Holds whether mouse is integrated. */
     311        bool  m_fIsMouseIntegrated;
     312
     313        /** Holds the mouse pointer shape data. */
     314        UIMousePointerShapeData  m_shapeData;
     315
     316        /** Holds cached mouse cursor shape pixmap. */
     317        QPixmap  m_cursorShapePixmap;
     318        /** Holds cached mouse cursor mask pixmap. */
     319        QPixmap  m_cursorMaskPixmap;
     320        /** Holds cached mouse cursor size. */
     321        QSize    m_cursorSize;
     322        /** Holds cached mouse cursor hotspot. */
     323        QPoint   m_cursorHotspot;
     324        /** Holds cached mouse cursor position. */
     325        QPoint   m_cursorPosition;
     326
     327        /** Holds the mouse-state. */
     328        int  m_iMouseState;
     329    /** @} */
    166330};
    167331
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp

    r98376 r98379  
    592592{
    593593    /* Variable falgs: */
    594     bool fIsMouseSupportsAbsolute = uisession()->isMouseSupportsAbsolute();
    595     bool fIsMouseSupportsRelative = uisession()->isMouseSupportsRelative();
    596     bool fIsMouseSupportsTouchScreen = uisession()->isMouseSupportsTouchScreen();
    597     bool fIsMouseSupportsTouchPad = uisession()->isMouseSupportsTouchPad();
    598     bool fIsMouseHostCursorNeeded = uisession()->isMouseHostCursorNeeded();
     594    bool fIsMouseSupportsAbsolute = uimachine()->isMouseSupportsAbsolute();
     595    bool fIsMouseSupportsRelative = uimachine()->isMouseSupportsRelative();
     596    bool fIsMouseSupportsTouchScreen = uimachine()->isMouseSupportsTouchScreen();
     597    bool fIsMouseSupportsTouchPad = uimachine()->isMouseSupportsTouchPad();
     598    bool fIsMouseHostCursorNeeded = uimachine()->isMouseHostCursorNeeded();
    599599
    600600    /* For now MT stuff is not important for MI action: */
     
    822822    /* Connect to session: */
    823823    connect(m_pMouseHandler, &UIMouseHandler::sigStateChange,
    824             uisession(), &UISession::setMouseState);
     824            uimachine(), &UIMachine::setMouseState);
    825825}
    826826
     
    888888    connect(uisession(), &UISession::sigMachineStateChange, this, &UIMachineLogic::sltMachineStateChanged);
    889889    connect(uisession(), &UISession::sigAdditionsStateActualChange, this, &UIMachineLogic::sltAdditionsStateChanged);
    890     connect(uisession(), &UISession::sigMouseCapabilityChange, this, &UIMachineLogic::sltMouseCapabilityChanged);
     890    connect(uimachine(), &UIMachine::sigMouseCapabilityChange, this, &UIMachineLogic::sltMouseCapabilityChanged);
    891891    connect(uisession(), &UISession::sigKeyboardLedsChange, this, &UIMachineLogic::sltKeyboardLedsChanged);
    892892    connect(uisession(), &UISession::sigUSBDeviceStateChange, this, &UIMachineLogic::sltUSBDeviceStateChange);
     
    11491149    /* Update UI session values with current: */
    11501150    uisession()->setKeyboardState(keyboardHandler()->state());
    1151     uisession()->setMouseState(mouseHandler()->state());
     1151    uimachine()->setMouseState(mouseHandler()->state());
    11521152}
    11531153
     
    14381438    disconnect(uisession(), &UISession::sigMachineStateChange, this, &UIMachineLogic::sltMachineStateChanged);
    14391439    disconnect(uisession(), &UISession::sigAdditionsStateActualChange, this, &UIMachineLogic::sltAdditionsStateChanged);
    1440     disconnect(uisession(), &UISession::sigMouseCapabilityChange, this, &UIMachineLogic::sltMouseCapabilityChanged);
     1440    disconnect(uimachine(), &UIMachine::sigMouseCapabilityChange, this, &UIMachineLogic::sltMouseCapabilityChanged);
    14411441    disconnect(uisession(), &UISession::sigKeyboardLedsChange, this, &UIMachineLogic::sltKeyboardLedsChanged);
    14421442    disconnect(uisession(), &UISession::sigUSBDeviceStateChange, this, &UIMachineLogic::sltUSBDeviceStateChange);
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp

    r98378 r98379  
    11181118{
    11191119    /* Fetch the shape and the mask: */
    1120     QPixmap pixmapShape = uisession()->cursorShapePixmap();
    1121     QPixmap pixmapMask = uisession()->cursorMaskPixmap();
    1122     const QPoint hotspot = uisession()->cursorHotspot();
     1120    QPixmap pixmapShape = uimachine()->cursorShapePixmap();
     1121    QPixmap pixmapMask = uimachine()->cursorMaskPixmap();
     1122    const QPoint hotspot = uimachine()->cursorHotspot();
    11231123    uint uXHot = hotspot.x();
    11241124    uint uYHot = hotspot.y();
     
    13871387    connect(uisession(), &UISession::sigMachineStateChange, this, &UIMachineView::sltMachineStateChanged);
    13881388    /* Mouse pointer shape updater: */
    1389     connect(uisession(), &UISession::sigMousePointerShapeChange, this, &UIMachineView::sltMousePointerShapeChange);
     1389    connect(uimachine(), &UIMachine::sigMousePointerShapeChange, this, &UIMachineView::sltMousePointerShapeChange);
    13901390}
    13911391
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.cpp

    r98378 r98379  
    162162{
    163163    /* Do not try to capture mouse if its captured already: */
    164     if (uisession()->isMouseCaptured())
     164    if (uimachine()->isMouseCaptured())
    165165        return;
    166166
     
    169169    {
    170170        /* Store mouse-capturing state value: */
    171         uisession()->setMouseCaptured(true);
     171        uimachine()->setMouseCaptured(true);
    172172
    173173        /* Memorize the index of machine-view-viewport captured mouse: */
     
    212212{
    213213    /* Do not try to release mouse if its released already: */
    214     if (!uisession()->isMouseCaptured())
     214    if (!uimachine()->isMouseCaptured())
    215215        return;
    216216
     
    219219    {
    220220        /* Store mouse-capturing state value: */
    221         uisession()->setMouseCaptured(false);
     221        uimachine()->setMouseCaptured(false);
    222222
    223223        /* Return the cursor to where it was when we captured it: */
     
    245245{
    246246    /* Do not do anything if its already done: */
    247     if (uisession()->isMouseIntegrated() == fEnabled)
     247    if (uimachine()->isMouseIntegrated() == fEnabled)
    248248        return;
    249249
    250250    /* Store mouse-integration state value: */
    251     uisession()->setMouseIntegrated(fEnabled);
     251    uimachine()->setMouseIntegrated(fEnabled);
    252252
    253253    /* Reuse sltMouseCapabilityChanged() to update mouse state: */
     
    258258int UIMouseHandler::state() const
    259259{
    260     return (uisession()->isMouseCaptured() ? UIMouseStateType_MouseCaptured : 0) |
    261            (uisession()->isMouseSupportsAbsolute() ? UIMouseStateType_MouseAbsolute : 0) |
    262            (uisession()->isMouseIntegrated() ? 0 : UIMouseStateType_MouseAbsoluteDisabled);
     260    return (uimachine()->isMouseCaptured() ? UIMouseStateType_MouseCaptured : 0) |
     261           (uimachine()->isMouseSupportsAbsolute() ? UIMouseStateType_MouseAbsolute : 0) |
     262           (uimachine()->isMouseIntegrated() ? 0 : UIMouseStateType_MouseAbsoluteDisabled);
    263263}
    264264
     
    327327        {
    328328            /* Do nothing if mouse is actively grabbed: */
    329             if (uisession()->isMouseCaptured())
     329            if (uimachine()->isMouseCaptured())
    330330                break;
    331331
     
    404404{
    405405    /* If mouse supports absolute pointing and mouse-integration activated: */
    406     if (uisession()->isMouseSupportsAbsolute() && uisession()->isMouseIntegrated())
     406    if (uimachine()->isMouseSupportsAbsolute() && uimachine()->isMouseIntegrated())
    407407    {
    408408        /* Release the mouse: */
     
    448448        /* Do not annoy user while restoring VM: */
    449449        if (uisession()->machineState() != KMachineState_Restoring)
    450             UINotificationMessage::remindAboutMouseIntegration(uisession()->isMouseSupportsAbsolute());
     450            UINotificationMessage::remindAboutMouseIntegration(uimachine()->isMouseSupportsAbsolute());
    451451    }
    452452
     
    462462     * 1. mouse is 'captured' or
    463463     * 2. machine is NOT 'paused' and mouse is NOT 'captured' and 'integrated' and 'absolute' but host pointer is 'hidden' by the guest. */
    464     if (uisession()->isMouseCaptured() ||
     464    if (uimachine()->isMouseCaptured() ||
    465465        (!uisession()->isPaused() &&
    466          uisession()->isMouseIntegrated() &&
    467          uisession()->isMouseSupportsAbsolute() &&
    468          uisession()->isHidingHostPointer()))
     466         uimachine()->isMouseIntegrated() &&
     467         uimachine()->isMouseSupportsAbsolute() &&
     468         uimachine()->isHidingHostPointer()))
    469469    {
    470470        QList<ulong> screenIds = m_viewports.keys();
     
    478478     * machine is NOT 'paused', mouse is 'integrated' and 'absolute' and valid pointer shape is present. */
    479479    if (!uisession()->isPaused() &&
    480         uisession()->isMouseIntegrated() &&
    481         uisession()->isMouseSupportsAbsolute() &&
    482         uisession()->isValidPointerShapePresent())
     480        uimachine()->isMouseIntegrated() &&
     481        uimachine()->isMouseSupportsAbsolute() &&
     482        uimachine()->isValidPointerShapePresent())
    483483    {
    484484        QList<ulong> screenIds = m_viewports.keys();
     
    530530
    531531    /* Mouse capability state-change updater: */
    532     connect(uisession(), &UISession::sigMouseCapabilityChange, this, &UIMouseHandler::sltMouseCapabilityChanged);
     532    connect(uimachine(), &UIMachine::sigMouseCapabilityChange, this, &UIMouseHandler::sltMouseCapabilityChanged);
     533    /* Mouse cursor position state-change updater: */
     534    connect(uimachine(), &UIMachine::sigCursorPositionChange, this, &UIMouseHandler::sltMousePointerShapeChanged);
    533535
    534536    /* Mouse pointer shape state-change updater: */
    535537    connect(this, &UIMouseHandler::sigStateChange, this, &UIMouseHandler::sltMousePointerShapeChanged);
    536 
    537     /* Mouse cursor position state-change updater: */
    538     connect(uisession(), &UISession::sigCursorPositionChange, this, &UIMouseHandler::sltMousePointerShapeChanged);
    539538
    540539    /* Initialize: */
     
    709708                    /* Check if we should activate window under cursor: */
    710709                    if (gEDataManager->activateHoveredMachineWindow() &&
    711                         !uisession()->isMouseCaptured() &&
     710                        !uimachine()->isMouseCaptured() &&
    712711                        QApplication::activeWindow() &&
    713712                        m_windows.values().contains(QApplication::activeWindow()) &&
     
    758757                case QEvent::TouchEnd:
    759758                {
    760                     if (uisession()->isMouseSupportsTouchScreen() || uisession()->isMouseSupportsTouchPad())
     759                    if (uimachine()->isMouseSupportsTouchScreen() || uimachine()->isMouseSupportsTouchPad())
    761760                        return multiTouchEvent(static_cast<QTouchEvent*>(pEvent), uScreenId);
    762761                    break;
     
    923922{
    924923    /* Ignore fake mouse events. */
    925     if (   (uisession()->isMouseSupportsTouchScreen() || uisession()->isMouseSupportsTouchPad())
     924    if (   (uimachine()->isMouseSupportsTouchScreen() || uimachine()->isMouseSupportsTouchPad())
    926925        && mouseIsTouchSource(iEventType, mouseButtons))
    927926        return true;
     
    967966        iWheelHorizontal = wheelDelta / 120;
    968967
    969     if (uisession()->isMouseCaptured())
     968    if (uimachine()->isMouseCaptured())
    970969    {
    971970#ifdef VBOX_WS_WIN
     
    10661065        return true; /* stop further event handling */
    10671066    }
    1068     else /* !uisession()->isMouseCaptured() */
    1069     {
    1070         if (uisession()->isMouseSupportsAbsolute() && uisession()->isMouseIntegrated())
     1067    else /* !uimachine()->isMouseCaptured() */
     1068    {
     1069        if (uimachine()->isMouseSupportsAbsolute() && uimachine()->isMouseIntegrated())
    10711070        {
    10721071            int iCw = m_views[uScreenId]->contentsWidth(), iCh = m_views[uScreenId]->contentsHeight();
     
    12191218    /* Compatibility with previous behavior. If there is no touchpad configured
    12201219     * then treat all multitouch events as touchscreen ones: */
    1221     fTouchScreen |= !uisession()->isMouseSupportsTouchPad();
     1220    fTouchScreen |= !uimachine()->isMouseSupportsTouchPad();
    12221221
    12231222    if (fTouchScreen)
     
    12981297        return;
    12991298
    1300     if (uisession()->isMouseCaptured())
     1299    if (uimachine()->isMouseCaptured())
    13011300    {
    13021301        /* Get full-viewport-rectangle in global coordinates: */
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp

    r98377 r98379  
    2828/* Qt includes: */
    2929#include <QApplication>
    30 #include <QBitmap>
    3130#include <QMenuBar>
    3231#include <QWidget>
     
    218217    if (uiCommon().isSeparateProcess())
    219218    {
    220         m_fIsMouseSupportsAbsolute = mouse().GetAbsoluteSupported();
    221         m_fIsMouseSupportsRelative = mouse().GetRelativeSupported();
    222         m_fIsMouseSupportsTouchScreen = mouse().GetTouchScreenSupported();
    223         m_fIsMouseSupportsTouchPad = mouse().GetTouchPadSupported();
    224         m_fIsMouseHostCursorNeeded = mouse().GetNeedsHostCursor();
    225219        sltAdditionsChange();
    226220    }
     
    500494}
    501495#endif /* RT_OS_DARWIN */
    502 
    503 void UISession::sltMousePointerShapeChange(const UIMousePointerShapeData &shapeData)
    504 {
    505     /* In case if shape itself is present: */
    506     if (shapeData.shape().size() > 0)
    507     {
    508         /* We are ignoring visibility flag: */
    509         m_fIsHidingHostPointer = false;
    510 
    511         /* And updating current shape data: */
    512         m_shapeData = shapeData;
    513         updateMousePointerShape();
    514     }
    515     /* In case if shape itself is NOT present: */
    516     else
    517     {
    518         /* Remember if we should hide the cursor: */
    519         m_fIsHidingHostPointer = !shapeData.isVisible();
    520     }
    521 
    522     /* Notify listeners about mouse capability changed: */
    523     emit sigMousePointerShapeChange();
    524 }
    525 
    526 void UISession::sltMouseCapabilityChange(bool fSupportsAbsolute, bool fSupportsRelative,
    527                                          bool fSupportsTouchScreen, bool fSupportsTouchPad,
    528                                          bool fNeedsHostCursor)
    529 {
    530     LogRelFlow(("GUI: UISession::sltMouseCapabilityChange: "
    531                 "Supports absolute: %s, Supports relative: %s, "
    532                 "Supports touchscreen: %s, Supports touchpad: %s, "
    533                 "Needs host cursor: %s\n",
    534                 fSupportsAbsolute ? "TRUE" : "FALSE", fSupportsRelative ? "TRUE" : "FALSE",
    535                 fSupportsTouchScreen ? "TRUE" : "FALSE", fSupportsTouchPad ? "TRUE" : "FALSE",
    536                 fNeedsHostCursor ? "TRUE" : "FALSE"));
    537 
    538     /* Check if something had changed: */
    539     if (   m_fIsMouseSupportsAbsolute != fSupportsAbsolute
    540         || m_fIsMouseSupportsRelative != fSupportsRelative
    541         || m_fIsMouseSupportsTouchScreen != fSupportsTouchScreen
    542         || m_fIsMouseSupportsTouchPad != fSupportsTouchPad
    543         || m_fIsMouseHostCursorNeeded != fNeedsHostCursor)
    544     {
    545         /* Store new data: */
    546         m_fIsMouseSupportsAbsolute = fSupportsAbsolute;
    547         m_fIsMouseSupportsRelative = fSupportsRelative;
    548         m_fIsMouseSupportsTouchScreen = fSupportsTouchScreen;
    549         m_fIsMouseSupportsTouchPad = fSupportsTouchPad;
    550         m_fIsMouseHostCursorNeeded = fNeedsHostCursor;
    551 
    552         /* Notify listeners about mouse capability changed: */
    553         emit sigMouseCapabilityChange();
    554     }
    555 }
    556 
    557 void UISession::sltCursorPositionChange(bool fContainsData, unsigned long uX, unsigned long uY)
    558 {
    559     LogRelFlow(("GUI: UISession::sltCursorPositionChange: "
    560                 "Cursor position valid: %d, Cursor position: %dx%d\n",
    561                 fContainsData ? "TRUE" : "FALSE", uX, uY));
    562 
    563     /* Check if something had changed: */
    564     if (   m_fIsValidCursorPositionPresent != fContainsData
    565         || m_cursorPosition.x() != (int)uX
    566         || m_cursorPosition.y() != (int)uY)
    567     {
    568         /* Store new data: */
    569         m_fIsValidCursorPositionPresent = fContainsData;
    570         m_cursorPosition = QPoint(uX, uY);
    571 
    572         /* Notify listeners about cursor position changed: */
    573         emit sigCursorPositionChange();
    574     }
    575 }
    576496
    577497void UISession::sltKeyboardLedsChangeEvent(bool fNumLock, bool fCapsLock, bool fScrollLock)
     
    913833    , m_uNumLockAdaptionCnt(2)
    914834    , m_uCapsLockAdaptionCnt(2)
    915     /* Mouse flags: */
    916     , m_fIsMouseSupportsAbsolute(false)
    917     , m_fIsMouseSupportsRelative(false)
    918     , m_fIsMouseSupportsTouchScreen(false)
    919     , m_fIsMouseSupportsTouchPad(false)
    920     , m_fIsMouseHostCursorNeeded(false)
    921     , m_fIsMouseCaptured(false)
    922     , m_fIsMouseIntegrated(true)
    923     , m_fIsValidPointerShapePresent(false)
    924     , m_fIsHidingHostPointer(true)
    925     , m_fIsValidCursorPositionPresent(false)
     835    /* CPU hardware virtualization features for VM: */
    926836    , m_enmVMExecutionEngine(KVMExecutionEngine_NotSet)
    927     /* CPU hardware virtualization features for VM: */
    928837    , m_fIsHWVirtExNestedPagingEnabled(false)
    929838    , m_fIsHWVirtExUXEnabled(false)
     
    1026935    /* Add console event connections: */
    1027936    connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigMousePointerShapeChange,
    1028             this, &UISession::sltMousePointerShapeChange);
     937            this, &UISession::sigMousePointerShapeChange);
    1029938    connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigMouseCapabilityChange,
    1030             this, &UISession::sltMouseCapabilityChange);
     939            this, &UISession::sigMouseCapabilityChange);
    1031940    connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigCursorPositionChange,
    1032             this, &UISession::sltCursorPositionChange);
     941            this, &UISession::sigCursorPositionChange);
    1033942    connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigKeyboardLedsChangeEvent,
    1034943            this, &UISession::sltKeyboardLedsChangeEvent);
     
    12591168
    12601169        /* Input options: */
    1261         actionPool()->action(UIActionIndexRT_M_Input_M_Mouse_T_Integration)->setChecked(isMouseIntegrated());
     1170        actionPool()->action(UIActionIndexRT_M_Input_M_Mouse_T_Integration)->setChecked(uimachine()->isMouseIntegrated());
    12621171
    12631172        /* Devices options: */
     
    14041313}
    14051314#endif /* VBOX_WS_MAC */
    1406 
    1407 /** Generate a BGRA bitmap which approximates a XOR/AND mouse pointer.
    1408  *
    1409  * Pixels which has 1 in the AND mask and not 0 in the XOR mask are replaced by
    1410  * the inverted pixel and 8 surrounding pixels with the original color.
    1411  * Fort example a white pixel (W) is replaced with a black (B) pixel:
    1412  *         WWW
    1413  *  W   -> WBW
    1414  *         WWW
    1415  * The surrounding pixels are written only if the corresponding source pixel
    1416  * does not affect the screen, i.e. AND bit is 1 and XOR value is 0.
    1417  */
    1418 static void renderCursorPixels(const uint32_t *pu32XOR, const uint8_t *pu8AND,
    1419                                uint32_t u32Width, uint32_t u32Height,
    1420                                uint32_t *pu32Pixels, uint32_t cbPixels)
    1421 {
    1422     /* Output pixels set to 0 which allow to not write transparent pixels anymore. */
    1423     memset(pu32Pixels, 0, cbPixels);
    1424 
    1425     const uint32_t *pu32XORSrc = pu32XOR;  /* Iterator for source XOR pixels. */
    1426     const uint8_t *pu8ANDSrcLine = pu8AND; /* The current AND mask scanline. */
    1427     uint32_t *pu32Dst = pu32Pixels;        /* Iterator for all destination BGRA pixels. */
    1428 
    1429     /* Some useful constants. */
    1430     const int cbANDLine = ((int)u32Width + 7) / 8;
    1431 
    1432     int y;
    1433     for (y = 0; y < (int)u32Height; ++y)
    1434     {
    1435         int x;
    1436         for (x = 0; x < (int)u32Width; ++x)
    1437         {
    1438             const uint32_t u32Pixel = *pu32XORSrc; /* Current pixel at (x,y) */
    1439             const uint8_t *pu8ANDSrc = pu8ANDSrcLine + x / 8; /* Byte which containt current AND bit. */
    1440 
    1441             if ((*pu8ANDSrc << (x % 8)) & 0x80)
    1442             {
    1443                 if (u32Pixel)
    1444                 {
    1445                     const uint32_t u32PixelInverted = ~u32Pixel;
    1446 
    1447                     /* Scan neighbor pixels and assign them if they are transparent. */
    1448                     int dy;
    1449                     for (dy = -1; dy <= 1; ++dy)
    1450                     {
    1451                         const int yn = y + dy;
    1452                         if (yn < 0 || yn >= (int)u32Height)
    1453                             continue; /* Do not cross the bounds. */
    1454 
    1455                         int dx;
    1456                         for (dx = -1; dx <= 1; ++dx)
    1457                         {
    1458                             const int xn = x + dx;
    1459                             if (xn < 0 || xn >= (int)u32Width)
    1460                                 continue;  /* Do not cross the bounds. */
    1461 
    1462                             if (dx != 0 || dy != 0)
    1463                             {
    1464                                 /* Check if the neighbor pixel is transparent. */
    1465                                 const uint32_t *pu32XORNeighborSrc = &pu32XORSrc[dy * (int)u32Width + dx];
    1466                                 const uint8_t *pu8ANDNeighborSrc = pu8ANDSrcLine + dy * cbANDLine + xn / 8;
    1467                                 if (   *pu32XORNeighborSrc == 0
    1468                                     && ((*pu8ANDNeighborSrc << (xn % 8)) & 0x80) != 0)
    1469                                 {
    1470                                     /* Transparent neighbor pixels are replaced with the source pixel value. */
    1471                                     uint32_t *pu32PixelNeighborDst = &pu32Dst[dy * (int)u32Width + dx];
    1472                                     *pu32PixelNeighborDst = u32Pixel | 0xFF000000;
    1473                                 }
    1474                             }
    1475                             else
    1476                             {
    1477                                 /* The pixel itself is replaced with inverted value. */
    1478                                 *pu32Dst = u32PixelInverted | 0xFF000000;
    1479                             }
    1480                         }
    1481                     }
    1482                 }
    1483                 else
    1484                 {
    1485                     /* The pixel does not affect the screen.
    1486                      * Do nothing. Do not touch destination which can already contain generated pixels.
    1487                      */
    1488                 }
    1489             }
    1490             else
    1491             {
    1492                 /* AND bit is 0, the pixel will be just drawn. */
    1493                 *pu32Dst = u32Pixel | 0xFF000000;
    1494             }
    1495 
    1496             ++pu32XORSrc; /* Next source pixel. */
    1497             ++pu32Dst;    /* Next destination pixel. */
    1498         }
    1499 
    1500         /* Next AND scanline. */
    1501         pu8ANDSrcLine += cbANDLine;
    1502     }
    1503 }
    1504 
    1505 #ifdef VBOX_WS_WIN
    1506 static bool isPointer1bpp(const uint8_t *pu8XorMask,
    1507                           uint uWidth,
    1508                           uint uHeight)
    1509 {
    1510     /* Check if the pointer has only 0 and 0xFFFFFF pixels, ignoring the alpha channel. */
    1511     const uint32_t *pu32Src = (uint32_t *)pu8XorMask;
    1512 
    1513     uint y;
    1514     for (y = 0; y < uHeight ; ++y)
    1515     {
    1516         uint x;
    1517         for (x = 0; x < uWidth; ++x)
    1518         {
    1519             const uint32_t u32Pixel = pu32Src[x] & UINT32_C(0xFFFFFF);
    1520             if (u32Pixel != 0 && u32Pixel != UINT32_C(0xFFFFFF))
    1521                 return false;
    1522         }
    1523 
    1524         pu32Src += uWidth;
    1525     }
    1526 
    1527     return true;
    1528 }
    1529 #endif /* VBOX_WS_WIN */
    1530 
    1531 void UISession::updateMousePointerShape()
    1532 {
    1533     /* Fetch incoming shape data: */
    1534     const bool fHasAlpha = m_shapeData.hasAlpha();
    1535     const uint uWidth = m_shapeData.shapeSize().width();
    1536     const uint uHeight = m_shapeData.shapeSize().height();
    1537     const uchar *pShapeData = m_shapeData.shape().constData();
    1538     AssertMsgReturnVoid(pShapeData, ("Shape data must not be NULL!\n"));
    1539 
    1540     /* Invalidate mouse pointer shape initially: */
    1541     m_fIsValidPointerShapePresent = false;
    1542     m_cursorShapePixmap = QPixmap();
    1543     m_cursorMaskPixmap = QPixmap();
    1544 
    1545     /* Parse incoming shape data: */
    1546     const uchar *pSrcAndMaskPtr = pShapeData;
    1547     const uint uAndMaskSize = (uWidth + 7) / 8 * uHeight;
    1548     const uchar *pSrcShapePtr = pShapeData + ((uAndMaskSize + 3) & ~3);
    1549 
    1550 #if defined (VBOX_WS_WIN)
    1551 
    1552     /* Create an ARGB image out of the shape data: */
    1553 
    1554     // WORKAROUND:
    1555     // Qt5 QCursor recommends 32 x 32 cursor, therefore the original data is copied to
    1556     // a larger QImage if necessary. Cursors like 10x16 did not work correctly (Solaris 10 guest).
    1557     // Align the cursor dimensions to 32 bit pixels, because for example a 56x56 monochrome cursor
    1558     // did not work correctly on Windows host.
    1559     const uint uCursorWidth = RT_ALIGN_32(uWidth, 32);
    1560     const uint uCursorHeight = RT_ALIGN_32(uHeight, 32);
    1561 
    1562     if (fHasAlpha)
    1563     {
    1564         QImage image(uCursorWidth, uCursorHeight, QImage::Format_ARGB32);
    1565         memset(image.bits(), 0, image.byteCount());
    1566 
    1567         const uint32_t *pu32SrcShapeScanline = (uint32_t *)pSrcShapePtr;
    1568         for (uint y = 0; y < uHeight; ++y, pu32SrcShapeScanline += uWidth)
    1569             memcpy(image.scanLine(y), pu32SrcShapeScanline, uWidth * sizeof(uint32_t));
    1570 
    1571         m_cursorShapePixmap = QPixmap::fromImage(image);
    1572     }
    1573     else
    1574     {
    1575         if (isPointer1bpp(pSrcShapePtr, uWidth, uHeight))
    1576         {
    1577             /* Incoming data consist of 32 bit BGR XOR mask and 1 bit AND mask.
    1578              * XOR pixels contain either 0x00000000 or 0x00FFFFFF.
    1579              *
    1580              * Originally intended result (F denotes 0x00FFFFFF):
    1581              * XOR AND
    1582              *   0   0 black
    1583              *   F   0 white
    1584              *   0   1 transparent
    1585              *   F   1 xor'd
    1586              *
    1587              * Actual Qt5 result for color table 0:0xFF000000, 1:0xFFFFFFFF
    1588              * (tested on Windows 7 and 10 64 bit hosts):
    1589              * Bitmap Mask
    1590              *  0   0 black
    1591              *  1   0 white
    1592              *  0   1 xor
    1593              *  1   1 transparent
    1594              *
    1595              */
    1596 
    1597             QVector<QRgb> colors(2);
    1598             colors[0] = UINT32_C(0xFF000000);
    1599             colors[1] = UINT32_C(0xFFFFFFFF);
    1600 
    1601             QImage bitmap(uCursorWidth, uCursorHeight, QImage::Format_Mono);
    1602             bitmap.setColorTable(colors);
    1603             memset(bitmap.bits(), 0xFF, bitmap.byteCount());
    1604 
    1605             QImage mask(uCursorWidth, uCursorHeight, QImage::Format_Mono);
    1606             mask.setColorTable(colors);
    1607             memset(mask.bits(), 0xFF, mask.byteCount());
    1608 
    1609             const uint8_t *pu8SrcAndScanline = pSrcAndMaskPtr;
    1610             const uint32_t *pu32SrcShapeScanline = (uint32_t *)pSrcShapePtr;
    1611             for (uint y = 0; y < uHeight; ++y)
    1612             {
    1613                 for (uint x = 0; x < uWidth; ++x)
    1614                 {
    1615                     const uint8_t u8Bit = (uint8_t)(1 << (7 - x % 8));
    1616 
    1617                     const uint8_t u8SrcMaskByte = pu8SrcAndScanline[x / 8];
    1618                     const uint8_t u8SrcMaskBit = u8SrcMaskByte & u8Bit;
    1619                     const uint32_t u32SrcPixel = pu32SrcShapeScanline[x] & UINT32_C(0xFFFFFF);
    1620 
    1621                     uint8_t *pu8DstMaskByte = &mask.scanLine(y)[x / 8];
    1622                     uint8_t *pu8DstBitmapByte = &bitmap.scanLine(y)[x / 8];
    1623 
    1624                     if (u8SrcMaskBit == 0)
    1625                     {
    1626                         if (u32SrcPixel == 0)
    1627                         {
    1628                             /* Black: Qt Bitmap = 0, Mask = 0 */
    1629                             *pu8DstMaskByte &= ~u8Bit;
    1630                             *pu8DstBitmapByte &= ~u8Bit;
    1631                         }
    1632                         else
    1633                         {
    1634                             /* White: Qt Bitmap = 1, Mask = 0 */
    1635                             *pu8DstMaskByte &= ~u8Bit;
    1636                             *pu8DstBitmapByte |= u8Bit;
    1637                         }
    1638                     }
    1639                     else
    1640                     {
    1641                         if (u32SrcPixel == 0)
    1642                         {
    1643                             /* Transparent: Qt Bitmap = 1, Mask = 1 */
    1644                             *pu8DstMaskByte |= u8Bit;
    1645                             *pu8DstBitmapByte |= u8Bit;
    1646                         }
    1647                         else
    1648                         {
    1649                             /* Xor'ed: Qt Bitmap = 0, Mask = 1 */
    1650                             *pu8DstMaskByte |= u8Bit;
    1651                             *pu8DstBitmapByte &= ~u8Bit;
    1652                         }
    1653                     }
    1654                 }
    1655 
    1656                 pu8SrcAndScanline += (uWidth + 7) / 8;
    1657                 pu32SrcShapeScanline += uWidth;
    1658             }
    1659 
    1660             m_cursorShapePixmap = QBitmap::fromImage(bitmap);
    1661             m_cursorMaskPixmap = QBitmap::fromImage(mask);
    1662         }
    1663         else
    1664         {
    1665             /* Assign alpha channel values according to the AND mask: 1 -> 0x00, 0 -> 0xFF: */
    1666             QImage image(uCursorWidth, uCursorHeight, QImage::Format_ARGB32);
    1667             memset(image.bits(), 0, image.byteCount());
    1668 
    1669             const uint8_t *pu8SrcAndScanline = pSrcAndMaskPtr;
    1670             const uint32_t *pu32SrcShapeScanline = (uint32_t *)pSrcShapePtr;
    1671 
    1672             for (uint y = 0; y < uHeight; ++y)
    1673             {
    1674                 uint32_t *pu32DstPixel = (uint32_t *)image.scanLine(y);
    1675 
    1676                 for (uint x = 0; x < uWidth; ++x)
    1677                 {
    1678                     const uint8_t u8Bit = (uint8_t)(1 << (7 - x % 8));
    1679                     const uint8_t u8SrcMaskByte = pu8SrcAndScanline[x / 8];
    1680 
    1681                     if (u8SrcMaskByte & u8Bit)
    1682                         *pu32DstPixel++ = pu32SrcShapeScanline[x] & UINT32_C(0x00FFFFFF);
    1683                     else
    1684                         *pu32DstPixel++ = pu32SrcShapeScanline[x] | UINT32_C(0xFF000000);
    1685                 }
    1686 
    1687                 pu32SrcShapeScanline += uWidth;
    1688                 pu8SrcAndScanline += (uWidth + 7) / 8;
    1689             }
    1690 
    1691             m_cursorShapePixmap = QPixmap::fromImage(image);
    1692         }
    1693     }
    1694 
    1695     /* Mark mouse pointer shape valid: */
    1696     m_fIsValidPointerShapePresent = true;
    1697 
    1698 #elif defined(VBOX_WS_X11) || defined(VBOX_WS_MAC)
    1699 
    1700     /* Create an ARGB image out of the shape data: */
    1701     QImage image(uWidth, uHeight, QImage::Format_ARGB32);
    1702 
    1703     if (fHasAlpha)
    1704     {
    1705         memcpy(image.bits(), pSrcShapePtr, uHeight * uWidth * 4);
    1706     }
    1707     else
    1708     {
    1709         renderCursorPixels((uint32_t *)pSrcShapePtr, pSrcAndMaskPtr,
    1710                            uWidth, uHeight,
    1711                            (uint32_t *)image.bits(), uHeight * uWidth * 4);
    1712     }
    1713 
    1714     /* Create cursor-pixmap from the image: */
    1715     m_cursorShapePixmap = QPixmap::fromImage(image);
    1716 
    1717     /* Mark mouse pointer shape valid: */
    1718     m_fIsValidPointerShapePresent = true;
    1719 
    1720 #else
    1721 
    1722 # warning "port me"
    1723 
    1724 #endif
    1725 
    1726     /* Cache cursor pixmap size and hotspot: */
    1727     m_cursorSize = m_cursorShapePixmap.size();
    1728     m_cursorHotspot = m_shapeData.hotSpot();
    1729 }
    17301315
    17311316bool UISession::preprocessInitialization()
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h

    r98377 r98379  
    3737#include <QEvent>
    3838#include <QMap>
    39 #include <QPixmap>
    4039
    4140/* GUI includes: */
     
    8584    /** Notifies listeners about keyboard state-change. */
    8685    void sigKeyboardStateChange(int iState);
    87     /** Notifies listeners about mouse state-change. */
    88     void sigMouseStateChange(int iState);
    8986    /** Notifies listeners about mouse pointer shape change. */
    90     void sigMousePointerShapeChange();
     87    void sigMousePointerShapeChange(const UIMousePointerShapeData &shapeData);
    9188    /** Notifies listeners about mouse capability change. */
    92     void sigMouseCapabilityChange();
     89    void sigMouseCapabilityChange(bool fSupportsAbsolute, bool fSupportsRelative,
     90                                  bool fSupportsTouchScreen, bool fSupportsTouchPad,
     91                                  bool fNeedsHostCursor);
    9392    /** Notifies listeners about cursor position change. */
    94     void sigCursorPositionChange();
     93    void sigCursorPositionChange(bool fContainsData, unsigned long uX, unsigned long uY);
    9594    void sigKeyboardLedsChange();
    9695    void sigMachineStateChange();
     
    174173    UIMachineWindow *activeMachineWindow() const;
    175174
    176     /** Returns currently cached mouse cursor shape pixmap. */
    177     QPixmap cursorShapePixmap() const { return m_cursorShapePixmap; }
    178     /** Returns currently cached mouse cursor mask pixmap. */
    179     QPixmap cursorMaskPixmap() const { return m_cursorMaskPixmap; }
    180     /** Returns currently cached mouse cursor size. */
    181     QSize cursorSize() const { return m_cursorSize; }
    182     /** Returns currently cached mouse cursor hotspot. */
    183     QPoint cursorHotspot() const { return m_cursorHotspot; }
    184     /** Returns currently cached mouse cursor position. */
    185     QPoint cursorPosition() const { return m_cursorPosition; }
    186 
    187175    /** @name Host-screen configuration variables.
    188176     ** @{ */
     
    254242    uint capsLockAdaptionCnt() const { return m_uCapsLockAdaptionCnt; }
    255243
    256     /* Mouse getters: */
    257     /** Returns mouse-state. */
    258     int mouseState() const { return m_iMouseState; }
    259     bool isMouseSupportsAbsolute() const { return m_fIsMouseSupportsAbsolute; }
    260     bool isMouseSupportsRelative() const { return m_fIsMouseSupportsRelative; }
    261     bool isMouseSupportsTouchScreen() const { return m_fIsMouseSupportsTouchScreen; }
    262     bool isMouseSupportsTouchPad() const { return m_fIsMouseSupportsTouchPad; }
    263     bool isMouseHostCursorNeeded() const { return m_fIsMouseHostCursorNeeded; }
    264     bool isMouseCaptured() const { return m_fIsMouseCaptured; }
    265     bool isMouseIntegrated() const { return m_fIsMouseIntegrated; }
    266     bool isValidPointerShapePresent() const { return m_fIsValidPointerShapePresent; }
    267     bool isHidingHostPointer() const { return m_fIsHidingHostPointer; }
    268     /** Returns whether the @a cursorPosition() is valid and could be used by the GUI now. */
    269     bool isValidCursorPositionPresent() const { return m_fIsValidCursorPositionPresent; }
    270 
    271244    /* Common setters: */
    272245    bool pause() { return setPause(true); }
     
    280253    void setNumLockAdaptionCnt(uint uNumLockAdaptionCnt) { m_uNumLockAdaptionCnt = uNumLockAdaptionCnt; }
    281254    void setCapsLockAdaptionCnt(uint uCapsLockAdaptionCnt) { m_uCapsLockAdaptionCnt = uCapsLockAdaptionCnt; }
    282 
    283     /* Mouse setters: */
    284     void setMouseCaptured(bool fIsMouseCaptured) { m_fIsMouseCaptured = fIsMouseCaptured; }
    285     void setMouseIntegrated(bool fIsMouseIntegrated) { m_fIsMouseIntegrated = fIsMouseIntegrated; }
    286255
    287256    /* Screen visibility status for host-desires: */
     
    351320    void setKeyboardState(int iKeyboardState) { m_iKeyboardState = iKeyboardState; emit sigKeyboardStateChange(m_iKeyboardState); }
    352321
    353     /** Defines @a iMouseState. */
    354     void setMouseState(int iMouseState) { m_iMouseState = iMouseState; emit sigMouseStateChange(m_iMouseState); }
    355 
    356322    /** Closes Runtime UI. */
    357323    void closeRuntimeUI();
     
    368334
    369335    /* Console events slots */
    370     /** Handles signal about mouse pointer @a shapeData change. */
    371     void sltMousePointerShapeChange(const UIMousePointerShapeData &shapeData);
    372     /** Handles signal about mouse capability change to @a fSupportsAbsolute, @a fSupportsRelative,
    373       * @a fSupportsTouchScreen, @a fSupportsTouchPad and @a fNeedsHostCursor. */
    374     void sltMouseCapabilityChange(bool fSupportsAbsolute, bool fSupportsRelative,
    375                                   bool fSupportsTouchScreen, bool fSupportsTouchPad,
    376                                   bool fNeedsHostCursor);
    377     /** Handles signal about guest request to change the cursor position to @a uX * @a uY.
    378       * @param  fContainsData  Brings whether the @a uX and @a uY values are valid and could be used by the GUI now. */
    379     void sltCursorPositionChange(bool fContainsData, unsigned long uX, unsigned long uY);
    380336    void sltKeyboardLedsChangeEvent(bool fNumLock, bool fCapsLock, bool fScrollLock);
    381337    void sltStateChange(KMachineState state);
     
    456412    void updateMenu();
    457413#endif /* VBOX_WS_MAC */
    458 
    459     /** Updates mouse pointer shape. */
    460     void updateMousePointerShape();
    461414
    462415    /* Common helpers: */
     
    527480    KMachineState m_machineState;
    528481
    529     /** Holds cached mouse cursor shape pixmap. */
    530     QPixmap  m_cursorShapePixmap;
    531     /** Holds cached mouse cursor mask pixmap. */
    532     QPixmap  m_cursorMaskPixmap;
    533     /** Holds cached mouse cursor size. */
    534     QSize    m_cursorSize;
    535     /** Holds cached mouse cursor hotspot. */
    536     QPoint   m_cursorHotspot;
    537     /** Holds cached mouse cursor position. */
    538     QPoint   m_cursorPosition;
    539 
    540482    /** @name Host-screen configuration variables.
    541483     * @{ */
     
    581523    uint m_uCapsLockAdaptionCnt;
    582524
    583     /* Mouse flags: */
    584     /** Holds the mouse-state. */
    585     int m_iMouseState;
    586     bool m_fIsMouseSupportsAbsolute : 1;
    587     bool m_fIsMouseSupportsRelative : 1;
    588     bool m_fIsMouseSupportsTouchScreen: 1;
    589     bool m_fIsMouseSupportsTouchPad: 1;
    590     bool m_fIsMouseHostCursorNeeded : 1;
    591     bool m_fIsMouseCaptured : 1;
    592     bool m_fIsMouseIntegrated : 1;
    593     bool m_fIsValidPointerShapePresent : 1;
    594     bool m_fIsHidingHostPointer : 1;
    595     /** Holds whether the @a m_cursorPosition is valid and could be used by the GUI now. */
    596     bool m_fIsValidCursorPositionPresent : 1;
    597     /** Holds the mouse pointer shape data. */
    598     UIMousePointerShapeData  m_shapeData;
    599 
    600525    /** Copy of IMachineDebugger::ExecutionEngine */
    601526    KVMExecutionEngine m_enmVMExecutionEngine;
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