/** * Send a touch event for the provided contact ID. This makes use of * the multitouch API available in XI2.2. * * @param[in] priv * @param[in] channel Channel to send a touch event for * @param[in] no_update If 'true', TouchUpdate events will not be created. * This should be used when entering multitouch mode to ensure TouchBegin * events are sent for already-in-prox contacts. */ static void wcmSendTouchEvent(WacomDevicePtr priv, WacomChannelPtr channel, Bool no_update) { #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 16 ValuatorMask *mask = priv->common->touch_mask; WacomDeviceState state = channel->valid.state; WacomDeviceState oldstate = channel->valid.states[1]; int type = -1; wcmRotateAndScaleCoordinates (priv->pInfo, &state.x, &state.y); valuator_mask_set(mask, 0, state.x); valuator_mask_set(mask, 1, state.y); if (!state.proximity) { DBG(6, priv->common, "This is a touch end event\n"); type = XI_TouchEnd; } else if (!oldstate.proximity || no_update) { DBG(6, priv->common, "This is a touch begin event\n"); type = XI_TouchBegin; } else { DBG(6, priv->common, "This is a touch update event\n"); type = XI_TouchUpdate; } xf86PostTouchEvent(priv->pInfo->dev, state.serial_num - 1, type, 0, mask); #endif }
static void wcmFingerScroll(WacomDevicePtr priv) { WacomCommonPtr common = priv->common; WacomChannelPtr firstChannel = common->wcmChannel; WacomChannelPtr secondChannel = common->wcmChannel + 1; WacomDeviceState ds[2] = { firstChannel->valid.states[0], secondChannel->valid.states[0] }; int midPoint_new = 0; int midPoint_old = 0; int i = 0, dist = 0; WacomFilterState filterd; /* borrow this struct */ int max_spread = common->wcmGestureParameters.wcmMaxScrollFingerSpread; DBG(10, priv, "\n"); if (common->wcmGestureMode != GESTURE_SCROLL_MODE) { if (abs(touchDistance(ds[0], ds[1]) - touchDistance(common->wcmGestureState[0], common->wcmGestureState[1])) < max_spread) { /* two fingers stay close to each other all the time and * move in vertical or horizontal direction together */ if (pointsInLine(common, ds[0], common->wcmGestureState[0]) && pointsInLine(common, ds[1], common->wcmGestureState[1]) && common->wcmGestureParameters.wcmScrollDirection) { /* left button might be down. Send it up first */ wcmSendButtonClick(priv, 1, 0); common->wcmGestureMode = GESTURE_SCROLL_MODE; } } } /* still not a scroll event yet? */ if (common->wcmGestureMode != GESTURE_SCROLL_MODE) return; /* initialize the points so we can rotate them */ filterd.x[0] = ds[0].x; filterd.y[0] = ds[0].y; filterd.x[1] = ds[1].x; filterd.y[1] = ds[1].y; filterd.x[2] = common->wcmGestureState[0].x; filterd.y[2] = common->wcmGestureState[0].y; filterd.x[3] = common->wcmGestureState[1].x; filterd.y[3] = common->wcmGestureState[1].y; /* scrolling has directions so rotation has to be considered first */ for (i=0; i<6; i++) wcmRotateAndScaleCoordinates(priv->pInfo, &filterd.x[i], &filterd.y[i]); /* check vertical direction */ if (common->wcmGestureParameters.wcmScrollDirection == WACOM_VERT_ALLOWED) { midPoint_old = (((double)filterd.y[2] + (double)filterd.y[3]) / 2.); midPoint_new = (((double)filterd.y[0] + (double)filterd.y[1]) / 2.); /* allow one finger scroll */ if (!ds[0].proximity) { midPoint_old = filterd.y[3]; midPoint_new = filterd.y[1]; } if (!ds[1].proximity) { midPoint_old = filterd.y[2]; midPoint_new = filterd.y[0]; } dist = midPoint_old - midPoint_new; wcmSendScrollEvent(priv, dist, WCM_SCROLL_UP, WCM_SCROLL_DOWN); } if (common->wcmGestureParameters.wcmScrollDirection == WACOM_HORIZ_ALLOWED) { midPoint_old = (((double)filterd.x[2] + (double)filterd.x[3]) / 2.); midPoint_new = (((double)filterd.x[0] + (double)filterd.x[1]) / 2.); /* allow one finger scroll */ if (!ds[0].proximity) { midPoint_old = filterd.x[3]; midPoint_new = filterd.x[1]; } if (!ds[1].proximity) { midPoint_old = filterd.x[2]; midPoint_new = filterd.x[0]; } dist = midPoint_old - midPoint_new; wcmSendScrollEvent(priv, dist, WCM_SCROLL_RIGHT, WCM_SCROLL_LEFT); } }