Esempio n. 1
0
/* Monitors for 1 finger touch and forces left button press or 1 finger
 * release and will remove left button press.
 *
 * This function relies on wcmGestureMode will only be zero if
 * WACOM_GESTURE_LAG_TIME has passed and still ony 1 finger on screen.
 */
static void wcmSingleFingerPress(WacomDevicePtr priv)
{
	WacomCommonPtr common = priv->common;
	WacomChannelPtr firstChannel = getContactNumber(common, 0);
	WacomChannelPtr secondChannel = getContactNumber(common, 1);
	Bool firstInProx = firstChannel && firstChannel->valid.states[0].proximity;
	Bool secondInProx = secondChannel && secondChannel->valid.states[0].proximity;

	DBG(10, priv, "\n");

	/* This gesture is only valid on touchscreens. */
	if (!TabletHasFeature(priv->common, WCM_LCD))
		return;

	if (!firstChannel)
		return;

	if (firstInProx && !secondInProx) {
		firstChannel->valid.states[0].buttons |= 1;
		common->wcmGestureMode = GESTURE_DRAG_MODE;
	}
	else {
		firstChannel->valid.states[0].buttons &= ~1;
		common->wcmGestureMode = GESTURE_NONE_MODE;
	}
}
Esempio n. 2
0
/* A single finger tap is defined as 1 finger tap that lasts less than
 * wcmTapTime.  It results in a left button press.
 *
 * Some work must be done to make sure two fingers were not touching
 * during this gesture. This is easy if first finger is released
 * first.  To handle case of second finger released first, require
 * second finger to have been released before first finger ever touched.
 *
 * Function relies on ds[0/1].sample to be updated only when entering or
 * exiting proximity so no storage is needed when initial touch occurs.
 */
static void wcmSingleFingerTap(WacomDevicePtr priv)
{
	WacomCommonPtr common = priv->common;
	WacomDeviceState ds[2] = {}, dsLast[2] = {};

	getStateHistory(common, ds, ARRAY_SIZE(ds), 0);
	getStateHistory(common, dsLast, ARRAY_SIZE(dsLast), 1);

	DBG(10, priv, "\n");

	/* This gesture is only valid on touchpads. */
	if (TabletHasFeature(priv->common, WCM_LCD))
		return;

	if (!ds[0].proximity && dsLast[0].proximity && !ds[1].proximity)
	{
		/* Single Tap must have lasted less than wcmTapTime
		 * and second finger must not have released after
		 * first finger touched.
		 */
		if (ds[0].sample - dsLast[0].sample <=
		    common->wcmGestureParameters.wcmTapTime &&
		    ds[1].sample < dsLast[0].sample)
		{
			common->wcmGestureMode = GESTURE_PREDRAG_MODE;

			/* Delay to detect possible drag operation */
			TimerSet(priv->tap_timer, 0, common->wcmGestureParameters.wcmTapTime, wcmSingleFingerTapTimer, priv);
		}
	}
}
Esempio n. 3
0
/**
 * Send multitouch events. If entering multitouch mode (indicated by
 * GESTURE_LAG_MODE), then touch events are sent for all in-prox
 * contacts. Otherwise, only the specified contact has a touch event
 * generated.
 *
 * @param[in] priv
 * @param[in] contact_id  ID of the contact to send event for (at minimum)
 */
static void
wcmFingerMultitouch(WacomDevicePtr priv, int contact_id) {
	Bool lag_mode = priv->common->wcmGestureMode == GESTURE_LAG_MODE;
	Bool prox = FALSE;
	int i;

	if (lag_mode && TabletHasFeature(priv->common, WCM_LCD)) {
		/* wcmSingleFingerPress triggers a button press as
		 * soon as a single finger appears. ensure we release
		 * that button before getting too far along
		 */
		wcmSendButtonClick(priv, 1, 0);
	}

	for (i = 0; i < MAX_CHANNELS; i++) {
		WacomChannelPtr channel = priv->common->wcmChannel+i;
		WacomDeviceState state  = channel->valid.state;
		if (state.device_type != TOUCH_ID)
			continue;

		if (lag_mode || state.serial_num == contact_id + 1) {
			wcmSendTouchEvent(priv, channel, lag_mode);
		}

		prox |= state.proximity;
	}

	if (!prox)
		priv->common->wcmGestureMode = GESTURE_NONE_MODE;
	else if (lag_mode)
		priv->common->wcmGestureMode = GESTURE_MULTITOUCH_MODE;
}
Esempio n. 4
0
/* A single finger tap is defined as 1 finger tap that lasts less than
 * wcmTapTime.  It results in a left button press.
 *
 * Some work must be done to make sure two fingers were not touching
 * during this gesture. This is easy if first finger is released
 * first.  To handle case of second finger released first, require
 * second finger to have been released before first finger ever touched.
 *
 * Function relies on ds[0/1].sample to be updated only when entering or
 * exiting proximity so no storage is needed when initial touch occurs.
 */
static void wcmSingleFingerTap(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] };
	WacomDeviceState dsLast[2] = { firstChannel->valid.states[1],
					secondChannel->valid.states[1] };

	DBG(10, priv, "\n");

	/* This gesture is only valid on touchpads. */
	if (TabletHasFeature(priv->common, WCM_LCD))
		return;

	if (!ds[0].proximity && dsLast[0].proximity && !ds[1].proximity)
	{
		/* Single Tap must have lasted less than wcmTapTime
		 * and second finger must not have released after
		 * first finger touched.
		 */
		if (ds[0].sample - dsLast[0].sample <=
		    common->wcmGestureParameters.wcmTapTime &&
		    ds[1].sample < dsLast[0].sample)
		{
			common->wcmGestureMode = GESTURE_PREDRAG_MODE;

			/* Delay to detect possible drag operation */
			TimerSet(NULL, 0, common->wcmGestureParameters.wcmTapTime, wcmSingleFingerTapTimer, priv);
		}
	}
}
Esempio n. 5
0
/* Monitors for 1 finger touch and forces left button press or 1 finger
 * release and will remove left button press.
 *
 * This function relies on wcmGestureMode will only be zero if
 * WACOM_GESTURE_LAG_TIME has passed and still ony 1 finger on screen.
 */
static void wcmSingleFingerPress(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] };

	DBG(10, priv, "\n");

	/* This gesture is only valid on touchscreens. */
	if (!TabletHasFeature(priv->common, WCM_LCD))
		return;

	if (ds[0].proximity && !ds[1].proximity)
		firstChannel->valid.states[0].buttons |= 1;
	if (!ds[0].proximity && !ds[1].proximity)
		firstChannel->valid.states[0].buttons &= ~1;
}