Ticket #29: mouse-integration.diff

File mouse-integration.diff, 15.7 KB (added by Valery V. Sedletski, 8 years ago)

Mouse integration patch

  • src/VBox/Frontends/VirtualBox/src/runtime/UISession.h

     
    447447#if defined(Q_WS_WIN)
    448448    HCURSOR m_alphaCursor;
    449449#endif
     450#if defined(Q_WS_PM)
     451    HPOINTER m_alphaCursor;
     452#endif
    450453
    451454    /** @name Host-screen configuration variables.
    452455     * @{ */
  • src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp

     
    2626# ifdef Q_WS_MAC
    2727#  include <QTimer>
    2828# endif /* Q_WS_MAC */
     29# ifdef Q_WS_PM
     30#  define INCL_GPIBITMAPS
     31#  define INCL_WINPOINTERS
     32#  define INCL_WINSYS
     33#  include <os2.h>
     34# endif
    2935
    3036/* GUI includes: */
    3137# include "VBoxGlobal.h"
     
    923929#ifdef Q_WS_WIN
    924930    , m_alphaCursor(0)
    925931#endif /* Q_WS_WIN */
     932#ifdef Q_WS_PM
     933    , m_alphaCursor(0)
     934#endif /* Q_WS_PM */
    926935#ifdef Q_WS_MAC
    927936    , m_pWatchdogDisplayChange(0)
    928937#endif /* Q_WS_MAC */
     
    14061415    if (m_alphaCursor)
    14071416        DestroyIcon(m_alphaCursor);
    14081417#endif /* Q_WS_WIN */
     1418#ifdef Q_WS_PM
     1419    if (m_alphaCursor)
     1420        WinDestroyPointer(m_alphaCursor);
     1421#endif /* Q_WS_PM */
    14091422
    14101423    /* Save settings: */
    14111424    saveSessionSettings();
     
    16371650        XcursorImageDestroy(img);
    16381651    }
    16391652
     1653#elif defined(Q_WS_PM)
     1654
     1655    uint uAlpha = fHasAlpha;
     1656    uint uHotX  = uXHot;
     1657    uint uHotY  = uYHot;
     1658
     1659    uint uX  = uWidth;
     1660    uint uY  = uHeight;
     1661
     1662    uint mxX = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER);
     1663    uint mxY = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER);
     1664
     1665    if (uX <= mxX)
     1666        mxX = uX;
     1667
     1668    if (uY <= mxY)
     1669        mxY = uY;
     1670
     1671    /* Width in bytes of the original AND mask scan line. */
     1672    uint32_t cbAndMaskScan     = (uX  + 7) / 8;
     1673    uint32_t cbAndMaskScanMx   = (mxX + 7) / 8;
     1674
     1675    //printf("mxX=%u, mxY=%u\n", mxX, mxY);
     1676    //printf("cbAndMaskScan: %u\n", cbAndMaskScan);
     1677
     1678    BITMAPINFOHEADER2 bmih2;
     1679    PBITMAPINFO2      pbi2         = NULL;
     1680    HBITMAP           hBitmap      = NULLHANDLE;
     1681    HBITMAP           hMonoBitmap  = NULLHANDLE;
     1682    void              *lpBits      = NULL;
     1683
     1684    memset(&bmih2, 0, sizeof(BITMAPINFOHEADER2));
     1685    bmih2.cbFix        = sizeof(BITMAPINFOHEADER2);
     1686    bmih2.cx           = mxX;
     1687    bmih2.cy           = mxY;
     1688    bmih2.cPlanes      = 1;
     1689    bmih2.cBitCount    = 32;
     1690
     1691    HPS hps = WinGetPS(HWND_DESKTOP);
     1692
     1693    pbi2 = (PBITMAPINFO2)RTMemAllocZ(sizeof(BITMAPINFOHEADER2) + mxX * mxY * 4);
     1694
     1695    if (pbi2)
     1696    {
     1697        memcpy((void *)pbi2, (void *)&bmih2, sizeof(BITMAPINFOHEADER2));
     1698        lpBits = (char *)pbi2 + sizeof(BITMAPINFOHEADER2);
     1699
     1700        ULONG *srcshp = (ULONG *) srcShapePtr;
     1701        ULONG *dstshp = (ULONG *) lpBits + mxX * (mxY - 1);
     1702
     1703        for (uint y = 0; y < mxY; y++)
     1704        {
     1705            for (uint x = 0; x < mxX; x++)
     1706            {
     1707                uint x_old = x * (uX / mxX);
     1708                uint y_old = y * (uY / mxY);
     1709
     1710                dstshp[x - y * mxX] = srcshp[x_old + y_old * uX];
     1711            }
     1712        }
     1713
     1714        hBitmap = GpiCreateBitmap(hps, &bmih2, CBM_INIT, (PBYTE)lpBits, pbi2);
     1715    }
     1716
     1717    hMonoBitmap = NULL;
     1718
     1719    //if (uAlpha)
     1720    //    printf("alpha\n");
     1721    //else
     1722    //    printf("non-alpha\n");
     1723
     1724    BITMAPINFOHEADER2 bmih;
     1725    memset(&bmih, 0, sizeof(BITMAPINFOHEADER2));
     1726    bmih.cbFix        = sizeof(BITMAPINFOHEADER2);
     1727    bmih.cx           = mxX;
     1728    bmih.cy           = mxY * 2;
     1729    bmih.cPlanes      = 1;
     1730    bmih.cBitCount    = 1;
     1731
     1732    /* Original AND mask is not word aligned. */
     1733    /* Allocate memory for aligned AND mask. */
     1734    PBITMAPINFO2 pbi = (PBITMAPINFO2)RTMemTmpAllocZ(sizeof(BITMAPINFOHEADER2)
     1735                     + (cbAndMaskScanMx + 1) * (mxY * 2 - 1));
     1736    void *pBits = NULL;
     1737
     1738    if (pbi)
     1739    {
     1740        memcpy((void *)pbi, (void *)&bmih, sizeof(BITMAPINFOHEADER2));
     1741
     1742        /* Word aligned AND mask. Will be allocated and created if necessary. */
     1743        uint8_t  *pu8AndMaskWordAligned = (uint8_t *)pbi + sizeof(BITMAPINFOHEADER2);
     1744
     1745        uint8_t  *dst = pu8AndMaskWordAligned + cbAndMaskScanMx * (mxY * 2 - 1);
     1746        uint8_t  *src = (uint8_t *)srcAndMaskPtr;
     1747 
     1748        ULONG *dstshp = (ULONG *) lpBits + mxX * (mxY - 1);
     1749
     1750        uint32_t u32PaddingBits;
     1751        uint8_t  u8LastBytesPaddingMask;
     1752
     1753        if (cbAndMaskScanMx & 1)
     1754        {
     1755            //printf("padding\n");
     1756
     1757            /* According to MSDN the padding bits must be 0.
     1758             * Compute the bit mask to set padding bits to 0 in the last byte of original AND mask. */
     1759            u32PaddingBits = cbAndMaskScanMx * 8 - mxX;
     1760            Assert(u32PaddingBits < 8);
     1761
     1762            u8LastBytesPaddingMask = (uint8_t)(0xFF << u32PaddingBits);
     1763
     1764            Log(("u8LastBytesPaddingMask = %02X, aligned w = %d, width = %d, cbAndMaskScan = %d\n",
     1765                  u8LastBytesPaddingMask, (cbAndMaskScanMx + 1) * 8, mxX, cbAndMaskScanMx));
     1766
     1767            pu8AndMaskWordAligned += mxY * 2 - 1;
     1768        }
     1769
     1770        pBits = (void *)pu8AndMaskWordAligned;
     1771        uint8_t byte  = 0;
     1772
     1773        for (uint y = 0; y < mxY; y++)
     1774        {
     1775            for (uint x = 0; x < cbAndMaskScanMx; x++)
     1776            {
     1777                uint x_old = x * (uX / mxX);
     1778                uint y_old = y * (uY / mxY);
     1779
     1780                byte = src[x_old + cbAndMaskScan * y_old];
     1781
     1782                if (uAlpha)
     1783                {
     1784                    // convert alpha channel to AND mask: set AND
     1785                    // mask bit to 1 if alpha is 0 for this pel
     1786                    for (uint i = 0; i < 8; i++)
     1787                    {
     1788                        uint8_t alpha = dstshp[8 * (x - cbAndMaskScanMx * y) + i] >> 24;
     1789
     1790                        if (alpha < 128) // transparent pel
     1791                            byte |= (1 << (7 - i));
     1792                        else // non-transparent pel
     1793                            byte &= ~(1 << (7 - i));
     1794                    }
     1795                }
     1796
     1797                dst[x - cbAndMaskScanMx * y] = byte;
     1798            }
     1799
     1800            if (cbAndMaskScanMx & 1)
     1801            {
     1802                dst[cbAndMaskScanMx - 1] &= u8LastBytesPaddingMask;
     1803                dst++;
     1804            }
     1805
     1806        }
     1807           
     1808        hMonoBitmap = GpiCreateBitmap(hps, &bmih, CBM_INIT, (PBYTE)pBits, pbi);
     1809        RTMemFree(pbi);
     1810    }
     1811
     1812    WinReleasePS(hps);
     1813    RTMemFree(pbi2);
     1814
     1815    Assert(hBitmap);
     1816    Assert(hMonoBitmap);
     1817
     1818    if (hBitmap && hMonoBitmap)
     1819    {
     1820        POINTERINFO ptri;
     1821        memset(&ptri, 0, sizeof(POINTERINFO));
     1822        ptri.fPointer   = TRUE;                        /* size indicator */
     1823        ptri.xHotspot   = uHotX * mxX / uX;            /* hotspot X      */
     1824        ptri.yHotspot   = mxY - uHotY * mxY / uY;      /* hotspot Y      */
     1825        ptri.hbmPointer = hMonoBitmap;                 /* and/xor        */
     1826        ptri.hbmColor   = hBitmap;                     /* color          */
     1827
     1828        HPOINTER hAlphaCursor = WinCreatePointerIndirect(HWND_DESKTOP, &ptri);
     1829        Assert(hAlphaCursor);
     1830
     1831        if (hAlphaCursor)
     1832        {
     1833            /* Set the new cursor: */
     1834            m_cursor = QCursor(hAlphaCursor);
     1835            if (m_alphaCursor)
     1836                WinDestroyPointer(m_alphaCursor);
     1837                //DestroyIcon(m_alphaCursor);
     1838            m_alphaCursor = hAlphaCursor;
     1839            m_fIsValidPointerShapePresent = true;
     1840        }
     1841    }
     1842
     1843    if (hMonoBitmap)
     1844        GpiDeleteBitmap(hMonoBitmap);
     1845    if (hBitmap)
     1846        GpiDeleteBitmap(hBitmap);
     1847
    16401848#elif defined(Q_WS_MAC)
    16411849
    16421850    /* Create a ARGB image out of the shape data. */
  • src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp

     
    4545# include <unistd.h>
    4646#endif
    4747
     48#ifdef RT_OS_OS2
     49# define INCL_GPIBITMAPS
     50# define INCL_WINPOINTERS
     51# define INCL_WINSYS
     52# include <os2.h>
     53
     54struct WMcursor
     55{
     56  HBITMAP               hbm;
     57  HPOINTER              hptr;
     58  PCHAR         pchData;
     59};
     60#endif
     61
    4862#ifndef RT_OS_DARWIN
    4963#include <SDL_syswm.h>           /* for SDL_GetWMInfo() */
    5064#endif
     
    230244#endif
    231245
    232246#ifdef VBOX_SECURELABEL
    233 #ifdef RT_OS_WINDOWS
     247#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    234248#define LIBSDL_TTF_NAME "SDL_ttf"
    235249#else
    236250#define LIBSDL_TTF_NAME "libSDL_ttf-2.0.so.0"
     
    30273041        {
    30283042# if defined(RT_OS_WINDOWS)
    30293043            ::DestroyCursor(*(HCURSOR *)pCustomTempWMCursor);
     3044# elif defined(RT_OS_OS2)
     3045            ::WinDestroyPointer(((struct WMcursor *)pCustomTempWMCursor)->hptr);
    30303046# elif defined(VBOXSDL_WITH_X11) && !defined(VBOX_WITHOUT_XCURSOR)
    30313047            if (gfXCursorEnabled)
    30323048                XFreeCursor(gSdlInfo.info.x11.display, *(Cursor *)pCustomTempWMCursor);
     
    47004716        if (hBitmap)
    47014717            ::DeleteObject(hBitmap);
    47024718
     4719#elif defined(RT_OS_OS2)
     4720
     4721    uint uAlpha = data->alpha;
     4722    uint uHotX  = data->xHot;
     4723    uint uHotY  = data->yHot;
     4724
     4725    uint uX  = data->width;
     4726    uint uY  = data->height;
     4727
     4728    uint mxX = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER);
     4729    uint mxY = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER);
     4730
     4731    if (uX <= mxX)
     4732        mxX = uX;
     4733
     4734    if (uY <= mxY)
     4735        mxY = uY;
     4736
     4737    /* Width in bytes of the original AND mask scan line. */
     4738    uint32_t cbAndMaskScan     = (uX  + 7) / 8;
     4739    uint32_t cbAndMaskScanMx   = (mxX + 7) / 8;
     4740
     4741    //printf("mxX=%u, mxY=%u\n", mxX, mxY);
     4742    //printf("cbAndMaskScan: %u\n", cbAndMaskScan);
     4743
     4744    BITMAPINFOHEADER2 bmih2;
     4745    PBITMAPINFO2      pbi2         = NULL;
     4746    HBITMAP           hBitmap      = NULLHANDLE;
     4747    HBITMAP           hMonoBitmap  = NULLHANDLE;
     4748    void              *lpBits      = NULL;
     4749
     4750    memset(&bmih2, 0, sizeof(BITMAPINFOHEADER2));
     4751    bmih2.cbFix        = sizeof(BITMAPINFOHEADER2);
     4752    bmih2.cx           = mxX;
     4753    bmih2.cy           = mxY;
     4754    bmih2.cPlanes      = 1;
     4755    bmih2.cBitCount    = 32;
     4756
     4757    HPS hps = WinGetPS(HWND_DESKTOP);
     4758
     4759    pbi2 = (PBITMAPINFO2)RTMemAllocZ(sizeof(BITMAPINFOHEADER2) + mxX * mxY * 4);
     4760
     4761    if (pbi2)
     4762    {
     4763        memcpy((void *)pbi2, (void *)&bmih2, sizeof(BITMAPINFOHEADER2));
     4764        lpBits = (char *)pbi2 + sizeof(BITMAPINFOHEADER2);
     4765
     4766        ULONG *srcshp = (ULONG *) srcShapePtr;
     4767        ULONG *dstshp = (ULONG *) lpBits + mxX * (mxY - 1);
     4768
     4769        for (uint y = 0; y < mxY; y++)
     4770        {
     4771            for (uint x = 0; x < mxX; x++)
     4772            {
     4773                uint x_old = x * (uX / mxX);
     4774                uint y_old = y * (uY / mxY);
     4775
     4776                dstshp[x - y * mxX] = srcshp[x_old + y_old * uX];
     4777            }
     4778        }
     4779
     4780        hBitmap = GpiCreateBitmap(hps, &bmih2, CBM_INIT, (PBYTE)lpBits, pbi2);
     4781    }
     4782
     4783    hMonoBitmap = NULL;
     4784
     4785    //if (uAlpha)
     4786    //    printf("alpha\n");
     4787    //else
     4788    //    printf("non-alpha\n");
     4789
     4790    BITMAPINFOHEADER2 bmih;
     4791    memset(&bmih, 0, sizeof(BITMAPINFOHEADER2));
     4792    bmih.cbFix        = sizeof(BITMAPINFOHEADER2);
     4793    bmih.cx           = mxX;
     4794    bmih.cy           = mxY * 2;
     4795    bmih.cPlanes      = 1;
     4796    bmih.cBitCount    = 1;
     4797
     4798    /* Original AND mask is not word aligned. */
     4799    /* Allocate memory for aligned AND mask. */
     4800    PBITMAPINFO2 pbi = (PBITMAPINFO2)RTMemTmpAllocZ(sizeof(BITMAPINFOHEADER2)
     4801                     + (cbAndMaskScanMx + 1) * (mxY * 2 - 1));
     4802    void *pBits = NULL;
     4803
     4804    if (pbi)
     4805    {
     4806        memcpy((void *)pbi, (void *)&bmih, sizeof(BITMAPINFOHEADER2));
     4807
     4808        /* Word aligned AND mask. Will be allocated and created if necessary. */
     4809        uint8_t  *pu8AndMaskWordAligned = (uint8_t *)pbi + sizeof(BITMAPINFOHEADER2);
     4810
     4811        uint8_t  *dst = pu8AndMaskWordAligned + cbAndMaskScanMx * (mxY * 2 - 1);
     4812        uint8_t  *src = (uint8_t *)srcAndMaskPtr;
     4813 
     4814        ULONG *dstshp = (ULONG *) lpBits + mxX * (mxY - 1);
     4815
     4816        uint32_t u32PaddingBits;
     4817        uint8_t  u8LastBytesPaddingMask;
     4818
     4819        if (cbAndMaskScanMx & 1)
     4820        {
     4821            //printf("padding\n");
     4822
     4823            /* According to MSDN the padding bits must be 0.
     4824             * Compute the bit mask to set padding bits to 0 in the last byte of original AND mask. */
     4825            u32PaddingBits = cbAndMaskScanMx * 8 - mxX;
     4826            Assert(u32PaddingBits < 8);
     4827
     4828            u8LastBytesPaddingMask = (uint8_t)(0xFF << u32PaddingBits);
     4829
     4830            Log(("u8LastBytesPaddingMask = %02X, aligned w = %d, width = %d, cbAndMaskScan = %d\n",
     4831                  u8LastBytesPaddingMask, (cbAndMaskScanMx + 1) * 8, mxX, cbAndMaskScanMx));
     4832
     4833            pu8AndMaskWordAligned += mxY * 2 - 1;
     4834        }
     4835
     4836        pBits = (void *)pu8AndMaskWordAligned;
     4837        uint8_t byte  = 0;
     4838
     4839        for (uint y = 0; y < mxY; y++)
     4840        {
     4841            for (uint x = 0; x < cbAndMaskScanMx; x++)
     4842            {
     4843                uint x_old = x * (uX / mxX);
     4844                uint y_old = y * (uY / mxY);
     4845
     4846                byte = src[x_old + cbAndMaskScan * y_old];
     4847
     4848                if (uAlpha)
     4849                {
     4850                    // convert alpha channel to AND mask: set AND
     4851                    // mask bit to 1 if alpha is 0 for this pel
     4852                    for (uint i = 0; i < 8; i++)
     4853                    {
     4854                        uint8_t alpha = dstshp[8 * (x - cbAndMaskScanMx * y) + i] >> 24;
     4855
     4856                        if (alpha < 128) // transparent pel
     4857                            byte |= (1 << (7 - i));
     4858                        else // non-transparent pel
     4859                            byte &= ~(1 << (7 - i));
     4860                    }
     4861                }
     4862
     4863                dst[x - cbAndMaskScanMx * y] = byte;
     4864            }
     4865
     4866            if (cbAndMaskScanMx & 1)
     4867            {
     4868                dst[cbAndMaskScanMx - 1] &= u8LastBytesPaddingMask;
     4869                dst++;
     4870            }
     4871        }
     4872           
     4873        hMonoBitmap = GpiCreateBitmap(hps, &bmih, CBM_INIT, (PBYTE)pBits, pbi);
     4874        RTMemFree(pbi);
     4875    }
     4876
     4877    WinReleasePS(hps);
     4878    RTMemFree(pbi2);
     4879
     4880    Assert(hBitmap);
     4881    Assert(hMonoBitmap);
     4882
     4883    if (hBitmap && hMonoBitmap)
     4884    {
     4885        POINTERINFO ptri;
     4886        memset(&ptri, 0, sizeof(POINTERINFO));
     4887        ptri.fPointer   = TRUE;                        /* size indicator */
     4888        ptri.xHotspot   = uHotX * mxX / uX;            /* hotspot X      */
     4889        ptri.yHotspot   = mxY - uHotY * mxY / uY;      /* hotspot Y      */
     4890        ptri.hbmPointer = hMonoBitmap;                 /* and/xor        */
     4891        ptri.hbmColor   = hBitmap;                     /* color          */
     4892
     4893        HPOINTER hAlphaCursor = WinCreatePointerIndirect(HWND_DESKTOP, &ptri);
     4894        Assert(hAlphaCursor);
     4895
     4896        if (hAlphaCursor)
     4897        {
     4898            // here we do a dirty trick by substituting a Window Manager's
     4899            // cursor handle with the handle we created
     4900            struct WMcursor *pCustomTempWMCursor = (struct WMcursor *)gpCustomCursor->wm_cursor;
     4901
     4902            // see SDL12/src/video/wincommon/SDL_sysmouse.c
     4903            struct WMcursor *wm_cursor = (struct WMcursor *)malloc(sizeof(struct WMcursor));
     4904            wm_cursor->hptr = hAlphaCursor;
     4905
     4906            gpCustomCursor->wm_cursor = wm_cursor;
     4907            SDL_SetCursor(gpCustomCursor);
     4908            SDL_ShowCursor(SDL_ENABLE);
     4909
     4910            if (pCustomTempWMCursor)
     4911            {
     4912                ::WinDestroyPointer(pCustomTempWMCursor->hptr);
     4913                free(pCustomTempWMCursor);
     4914            }
     4915            ok = true;
     4916        }
     4917    }
     4918
     4919    if (hMonoBitmap)
     4920        GpiDeleteBitmap(hMonoBitmap);
     4921    if (hBitmap)
     4922        GpiDeleteBitmap(hBitmap);
     4923
    47034924#elif defined(VBOXSDL_WITH_X11) && !defined(VBOX_WITHOUT_XCURSOR)
    47044925
    47054926        if (gfXCursorEnabled)