Пример #1
0
/* Used by PutEventMultiTouch and PutEventMultiTouchString. */
HRESULT Mouse::putEventMultiTouch(LONG aCount,
                                  LONG64 *paContacts,
                                  ULONG aScanTime)
{
    if (aCount >= 256)
    {
         return E_INVALIDARG;
    }

    DisplayMouseInterface *pDisplay = mParent->getDisplayMouseInterface();
    ComAssertRet(pDisplay, E_FAIL);

    HRESULT rc = S_OK;

    uint64_t* pau64Contacts = NULL;
    uint8_t cContacts = 0;

    /* Deliver 0 contacts too, touch device may use this to reset the state. */
    if (aCount > 0)
    {
        /* Create a copy with converted coords. */
        pau64Contacts = (uint64_t *)RTMemTmpAlloc(aCount * sizeof(uint64_t));
        if (pau64Contacts)
        {
            int32_t x1, y1, x2, y2;
            /* Takes the display lock */
            pDisplay->getFramebufferDimensions(&x1, &y1, &x2, &y2);

            LONG i;
            for (i = 0; i < aCount; i++)
            {
                uint32_t u32Lo = RT_LO_U32(paContacts[i]);
                uint32_t u32Hi = RT_HI_U32(paContacts[i]);
                int32_t x = (int16_t)u32Lo;
                int32_t y = (int16_t)(u32Lo >> 16);
                uint8_t contactId =  RT_BYTE1(u32Hi);
                bool fInContact   = (RT_BYTE2(u32Hi) & 0x1) != 0;
                bool fInRange     = (RT_BYTE2(u32Hi) & 0x2) != 0;

                LogRel3(("%s: [%d] %d,%d id %d, inContact %d, inRange %d\n",
                         __FUNCTION__, i, x, y, contactId, fInContact, fInRange));

                /* Framebuffer dimensions are 0,0 width, height, that is x2,y2 are exclusive,
                 * while coords are inclusive.
                 */
                int32_t xAdj = x1 < x2 ?   ((x - 1 - x1) * VMMDEV_MOUSE_RANGE)
                                         / (x2 - x1) : 0;
                int32_t yAdj = y1 < y2 ?   ((y - 1 - y1) * VMMDEV_MOUSE_RANGE)
                                         / (y2 - y1) : 0;

                bool fValid = (   xAdj >= VMMDEV_MOUSE_RANGE_MIN
                               && xAdj <= VMMDEV_MOUSE_RANGE_MAX
                               && yAdj >= VMMDEV_MOUSE_RANGE_MIN
                               && yAdj <= VMMDEV_MOUSE_RANGE_MAX);

                if (fValid)
                {
                    uint8_t fu8 =   (fInContact? 0x01: 0x00)
                                  | (fInRange?   0x02: 0x00);
                    pau64Contacts[cContacts] = RT_MAKE_U64_FROM_U16((uint16_t)xAdj,
                                                                    (uint16_t)yAdj,
                                                                    RT_MAKE_U16(contactId, fu8),
                                                                    0);
                    cContacts++;
                }
            }
        }
        else
        {
Пример #2
0
/* Used by PutEventMultiTouch and PutEventMultiTouchString. */
HRESULT Mouse::putEventMultiTouch(LONG aCount,
                                  LONG64 *paContacts,
                                  ULONG aScanTime)
{
    if (aCount >= 256)
    {
         return E_INVALIDARG;
    }

    DisplayMouseInterface *pDisplay = mParent->getDisplayMouseInterface();
    ComAssertRet(pDisplay, E_FAIL);

    /* Touch events are mapped to the primary monitor, because the emulated USB
     * touchscreen device is associated with one (normally the primary) screen in the guest.
     */
    ULONG uScreenId = 0;

    ULONG cWidth  = 0;
    ULONG cHeight = 0;
    LONG  xOrigin = 0;
    LONG  yOrigin = 0;
    HRESULT rc = pDisplay->getScreenResolution(uScreenId, &cWidth, &cHeight, NULL, &xOrigin, &yOrigin);
    ComAssertComRCRetRC(rc);

    uint64_t* pau64Contacts = NULL;
    uint8_t cContacts = 0;

    /* Deliver 0 contacts too, touch device may use this to reset the state. */
    if (aCount > 0)
    {
        /* Create a copy with converted coords. */
        pau64Contacts = (uint64_t *)RTMemTmpAlloc(aCount * sizeof(uint64_t));
        if (pau64Contacts)
        {
            int32_t x1 = xOrigin;
            int32_t y1 = yOrigin;
            int32_t x2 = x1 + cWidth;
            int32_t y2 = y1 + cHeight;

            LogRel3(("%s: screen [%d] %d,%d %d,%d\n",
                     __FUNCTION__, uScreenId, x1, y1, x2, y2));

            LONG i;
            for (i = 0; i < aCount; i++)
            {
                uint32_t u32Lo = RT_LO_U32(paContacts[i]);
                uint32_t u32Hi = RT_HI_U32(paContacts[i]);
                int32_t x = (int16_t)u32Lo;
                int32_t y = (int16_t)(u32Lo >> 16);
                uint8_t contactId =  RT_BYTE1(u32Hi);
                bool fInContact   = (RT_BYTE2(u32Hi) & 0x1) != 0;
                bool fInRange     = (RT_BYTE2(u32Hi) & 0x2) != 0;

                LogRel3(("%s: [%d] %d,%d id %d, inContact %d, inRange %d\n",
                         __FUNCTION__, i, x, y, contactId, fInContact, fInRange));

                /* x1,y1 are inclusive and x2,y2 are exclusive,
                 * while x,y start from 1 and are inclusive.
                 */
                if (x <= x1 || x > x2 || y <= y1 || y > y2)
                {
                    /* Out of range. Skip the contact. */
                    continue;
                }

                int32_t xAdj = x1 < x2? ((x - 1 - x1) * VMMDEV_MOUSE_RANGE) / (x2 - x1) : 0;
                int32_t yAdj = y1 < y2? ((y - 1 - y1) * VMMDEV_MOUSE_RANGE) / (y2 - y1) : 0;

                bool fValid = (   xAdj >= VMMDEV_MOUSE_RANGE_MIN
                               && xAdj <= VMMDEV_MOUSE_RANGE_MAX
                               && yAdj >= VMMDEV_MOUSE_RANGE_MIN
                               && yAdj <= VMMDEV_MOUSE_RANGE_MAX);

                if (fValid)
                {
                    uint8_t fu8 =   (fInContact? 0x01: 0x00)
                                  | (fInRange?   0x02: 0x00);
                    pau64Contacts[cContacts] = RT_MAKE_U64_FROM_U16((uint16_t)xAdj,
                                                                    (uint16_t)yAdj,
                                                                    RT_MAKE_U16(contactId, fu8),
                                                                    0);
                    cContacts++;
                }
            }
        }
        else
        {