Ticket #29: mouse-integration.diff
File mouse-integration.diff, 15.7 KB (added by , 8 years ago) |
---|
-
src/VBox/Frontends/VirtualBox/src/runtime/UISession.h
447 447 #if defined(Q_WS_WIN) 448 448 HCURSOR m_alphaCursor; 449 449 #endif 450 #if defined(Q_WS_PM) 451 HPOINTER m_alphaCursor; 452 #endif 450 453 451 454 /** @name Host-screen configuration variables. 452 455 * @{ */ -
src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
26 26 # ifdef Q_WS_MAC 27 27 # include <QTimer> 28 28 # 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 29 35 30 36 /* GUI includes: */ 31 37 # include "VBoxGlobal.h" … … 923 929 #ifdef Q_WS_WIN 924 930 , m_alphaCursor(0) 925 931 #endif /* Q_WS_WIN */ 932 #ifdef Q_WS_PM 933 , m_alphaCursor(0) 934 #endif /* Q_WS_PM */ 926 935 #ifdef Q_WS_MAC 927 936 , m_pWatchdogDisplayChange(0) 928 937 #endif /* Q_WS_MAC */ … … 1406 1415 if (m_alphaCursor) 1407 1416 DestroyIcon(m_alphaCursor); 1408 1417 #endif /* Q_WS_WIN */ 1418 #ifdef Q_WS_PM 1419 if (m_alphaCursor) 1420 WinDestroyPointer(m_alphaCursor); 1421 #endif /* Q_WS_PM */ 1409 1422 1410 1423 /* Save settings: */ 1411 1424 saveSessionSettings(); … … 1637 1650 XcursorImageDestroy(img); 1638 1651 } 1639 1652 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 1640 1848 #elif defined(Q_WS_MAC) 1641 1849 1642 1850 /* Create a ARGB image out of the shape data. */ -
src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
45 45 # include <unistd.h> 46 46 #endif 47 47 48 #ifdef RT_OS_OS2 49 # define INCL_GPIBITMAPS 50 # define INCL_WINPOINTERS 51 # define INCL_WINSYS 52 # include <os2.h> 53 54 struct WMcursor 55 { 56 HBITMAP hbm; 57 HPOINTER hptr; 58 PCHAR pchData; 59 }; 60 #endif 61 48 62 #ifndef RT_OS_DARWIN 49 63 #include <SDL_syswm.h> /* for SDL_GetWMInfo() */ 50 64 #endif … … 230 244 #endif 231 245 232 246 #ifdef VBOX_SECURELABEL 233 #if def RT_OS_WINDOWS247 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 234 248 #define LIBSDL_TTF_NAME "SDL_ttf" 235 249 #else 236 250 #define LIBSDL_TTF_NAME "libSDL_ttf-2.0.so.0" … … 3027 3041 { 3028 3042 # if defined(RT_OS_WINDOWS) 3029 3043 ::DestroyCursor(*(HCURSOR *)pCustomTempWMCursor); 3044 # elif defined(RT_OS_OS2) 3045 ::WinDestroyPointer(((struct WMcursor *)pCustomTempWMCursor)->hptr); 3030 3046 # elif defined(VBOXSDL_WITH_X11) && !defined(VBOX_WITHOUT_XCURSOR) 3031 3047 if (gfXCursorEnabled) 3032 3048 XFreeCursor(gSdlInfo.info.x11.display, *(Cursor *)pCustomTempWMCursor); … … 4700 4716 if (hBitmap) 4701 4717 ::DeleteObject(hBitmap); 4702 4718 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 4703 4924 #elif defined(VBOXSDL_WITH_X11) && !defined(VBOX_WITHOUT_XCURSOR) 4704 4925 4705 4926 if (gfXCursorEnabled)