- Generate helper events for ALPS touchpads. This is needed for tap drag and edge motion. This emulates the synaptics touchpad somehow. For example, we need more events to decide if a tap is a
simple click or becomes a tap drag. ALPS does not send these events. - Enable ALPS. - Force const edge motion speed. Synaptics sends events with a certain frequency ALPS don't. Even worse ALPS stops sending events durring a edge motion when you don't move your finger. Current speed is 200 pixel/s. In theory synaptics has different event frequency modes which would result in a different edge motion speed in the previous approach. Please check if synaptics works/speed is correct. Will try to get a synaptics laptop for testing... - fix class variable names. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41190 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
a16bab72a7
commit
9b35c5d38d
@ -11,7 +11,7 @@
|
|||||||
# define INFO(x...)
|
# define INFO(x...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// #define TRACE_MOVEMENT_MAKER
|
#define TRACE_MOVEMENT_MAKER
|
||||||
#ifdef TRACE_MOVEMENT_MAKER
|
#ifdef TRACE_MOVEMENT_MAKER
|
||||||
# define TRACE(x...) dprintf(x)
|
# define TRACE(x...) dprintf(x)
|
||||||
#else
|
#else
|
||||||
@ -202,7 +202,7 @@ MovementMaker::SetSpecs(hardware_specs* specs)
|
|||||||
fAreaHeight = fSpecs->areaEndY - fSpecs->areaStartY;
|
fAreaHeight = fSpecs->areaEndY - fSpecs->areaStartY;
|
||||||
|
|
||||||
// calibrated on the synaptics touchpad
|
// calibrated on the synaptics touchpad
|
||||||
fSpeed = 4100 / fAreaWidth;
|
fSpeed = SYN_WIDTH / fAreaWidth;
|
||||||
fSmallMovement = 3 / fSpeed;
|
fSmallMovement = 3 / fSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ MovementMaker::StartNewMovment()
|
|||||||
if (fSettings->scroll_ystepsize <= 0)
|
if (fSettings->scroll_ystepsize <= 0)
|
||||||
fSettings->scroll_ystepsize = 1;
|
fSettings->scroll_ystepsize = 1;
|
||||||
|
|
||||||
movementStarted = true;
|
fMovementMakerStarted = true;
|
||||||
scrolling_x = 0;
|
scrolling_x = 0;
|
||||||
scrolling_y = 0;
|
scrolling_y = 0;
|
||||||
}
|
}
|
||||||
@ -228,7 +228,7 @@ MovementMaker::GetMovement(uint32 posX, uint32 posY)
|
|||||||
|
|
||||||
// INFO("SYN: pos: %lu x %lu, delta: %ld x %ld, sums: %ld x %ld\n",
|
// INFO("SYN: pos: %lu x %lu, delta: %ld x %ld, sums: %ld x %ld\n",
|
||||||
// posX, posY, xDelta, yDelta,
|
// posX, posY, xDelta, yDelta,
|
||||||
// deltaSumX, deltaSumY);
|
// fDeltaSumX, fDeltaSumY);
|
||||||
|
|
||||||
xDelta = xDelta;
|
xDelta = xDelta;
|
||||||
yDelta = yDelta;
|
yDelta = yDelta;
|
||||||
@ -280,57 +280,57 @@ MovementMaker::_GetRawMovement(uint32 posX, uint32 posY)
|
|||||||
|
|
||||||
int diff;
|
int diff;
|
||||||
|
|
||||||
if (movementStarted) {
|
if (fMovementMakerStarted) {
|
||||||
movementStarted = false;
|
fMovementMakerStarted = false;
|
||||||
// init delta tracking
|
// init delta tracking
|
||||||
previousX = posX;
|
fPreviousX = posX;
|
||||||
previousY = posY;
|
fPreviousY = posY;
|
||||||
// deltas are automatically reset
|
// deltas are automatically reset
|
||||||
}
|
}
|
||||||
|
|
||||||
// accumulate delta and store current pos, reset if pos did not change
|
// accumulate delta and store current pos, reset if pos did not change
|
||||||
diff = posX - previousX;
|
diff = posX - fPreviousX;
|
||||||
// lessen the effect of small diffs
|
// lessen the effect of small diffs
|
||||||
if ((diff > -fSmallMovement && diff < -1)
|
if ((diff > -fSmallMovement && diff < -1)
|
||||||
|| (diff > 1 && diff < fSmallMovement)) {
|
|| (diff > 1 && diff < fSmallMovement)) {
|
||||||
diff /= 2;
|
diff /= 2;
|
||||||
}
|
}
|
||||||
if (diff == 0)
|
if (diff == 0)
|
||||||
deltaSumX = 0.0;
|
fDeltaSumX = 0.0;
|
||||||
else
|
else
|
||||||
deltaSumX += diff;
|
fDeltaSumX += diff;
|
||||||
|
|
||||||
diff = posY - previousY;
|
diff = posY - fPreviousY;
|
||||||
// lessen the effect of small diffs
|
// lessen the effect of small diffs
|
||||||
if ((diff > -fSmallMovement && diff < -1)
|
if ((diff > -fSmallMovement && diff < -1)
|
||||||
|| (diff > 1 && diff < fSmallMovement)) {
|
|| (diff > 1 && diff < fSmallMovement)) {
|
||||||
diff /= 2;
|
diff /= 2;
|
||||||
}
|
}
|
||||||
if (diff == 0)
|
if (diff == 0)
|
||||||
deltaSumY = 0.0;
|
fDeltaSumY = 0.0;
|
||||||
else
|
else
|
||||||
deltaSumY += diff;
|
fDeltaSumY += diff;
|
||||||
|
|
||||||
previousX = posX;
|
fPreviousX = posX;
|
||||||
previousY = posY;
|
fPreviousY = posY;
|
||||||
|
|
||||||
// compute current delta and reset accumulated delta if
|
// compute current delta and reset accumulated delta if
|
||||||
// abs() is greater than 1
|
// abs() is greater than 1
|
||||||
xDelta = deltaSumX / translation;
|
xDelta = fDeltaSumX / translation;
|
||||||
yDelta = deltaSumY / translation;
|
yDelta = fDeltaSumY / translation;
|
||||||
if (xDelta > 1.0) {
|
if (xDelta > 1.0) {
|
||||||
deltaSumX = 0.0;
|
fDeltaSumX = 0.0;
|
||||||
xDelta = 1.0 + (xDelta - 1.0) * acceleration;
|
xDelta = 1.0 + (xDelta - 1.0) * acceleration;
|
||||||
} else if (xDelta < -1.0) {
|
} else if (xDelta < -1.0) {
|
||||||
deltaSumX = 0.0;
|
fDeltaSumX = 0.0;
|
||||||
xDelta = -1.0 + (xDelta + 1.0) * acceleration;
|
xDelta = -1.0 + (xDelta + 1.0) * acceleration;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (yDelta > 1.0) {
|
if (yDelta > 1.0) {
|
||||||
deltaSumY = 0.0;
|
fDeltaSumY = 0.0;
|
||||||
yDelta = 1.0 + (yDelta - 1.0) * acceleration;
|
yDelta = 1.0 + (yDelta - 1.0) * acceleration;
|
||||||
} else if (yDelta < -1.0) {
|
} else if (yDelta < -1.0) {
|
||||||
deltaSumY = 0.0;
|
fDeltaSumY = 0.0;
|
||||||
yDelta = -1.0 + (yDelta + 1.0) * acceleration;
|
yDelta = -1.0 + (yDelta + 1.0) * acceleration;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,17 +358,17 @@ MovementMaker::_ComputeAcceleration(int8 accel_factor)
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
#define TAP_TIMEOUT 200000
|
#define fTapTimeOUT 200000
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TouchpadMovement::Init()
|
TouchpadMovement::Init()
|
||||||
{
|
{
|
||||||
movement_started = false;
|
fMovementStarted = false;
|
||||||
scrolling_started = false;
|
fScrollingStarted = false;
|
||||||
tap_started = false;
|
fTapStarted = false;
|
||||||
valid_edge_motion = false;
|
fValidEdgeMotion = false;
|
||||||
double_click = false;
|
fDoubleClick = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -387,20 +387,20 @@ TouchpadMovement::EventToMovement(touch_event *event, mouse_movement *movement)
|
|||||||
movement->clicks = 0;
|
movement->clicks = 0;
|
||||||
movement->timestamp = system_time();
|
movement->timestamp = system_time();
|
||||||
|
|
||||||
if ((movement->timestamp - tap_time) > TAP_TIMEOUT) {
|
if ((movement->timestamp - fTapTime) > fTapTimeOUT) {
|
||||||
TRACE("ALPS: tap gesture timed out\n");
|
TRACE("ALPS: tap gesture timed out\n");
|
||||||
tap_started = false;
|
fTapStarted = false;
|
||||||
if (!double_click
|
if (!fDoubleClick
|
||||||
|| (movement->timestamp - tap_time) > 2 * TAP_TIMEOUT) {
|
|| (movement->timestamp - fTapTime) > 2 * fTapTimeOUT) {
|
||||||
tap_clicks = 0;
|
fTapClicks = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->buttons & kLeftButton) {
|
if (event->buttons & kLeftButton) {
|
||||||
tap_clicks = 0;
|
fTapClicks = 0;
|
||||||
tapdrag_started = false;
|
fTapdragStarted = false;
|
||||||
tap_started = false;
|
fTapStarted = false;
|
||||||
valid_edge_motion = false;
|
fValidEdgeMotion = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->zPressure >= fSpecs->minPressure
|
if (event->zPressure >= fSpecs->minPressure
|
||||||
@ -418,33 +418,59 @@ TouchpadMovement::EventToMovement(touch_event *event, mouse_movement *movement)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// in pixel per second
|
||||||
|
const int32 kEdgeMotionSpeed = 200;
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TouchpadMovement::_EdgeMotion(mouse_movement *movement, touch_event *event,
|
TouchpadMovement::_EdgeMotion(mouse_movement *movement, touch_event *event,
|
||||||
bool validStart)
|
bool validStart)
|
||||||
{
|
{
|
||||||
int32 xdelta = 0;
|
float xdelta = 0;
|
||||||
int32 ydelta = 0;
|
float ydelta = 0;
|
||||||
|
|
||||||
if (event->xPosition < fSpecs->areaStartX + fSpecs->edgeMotionWidth)
|
bigtime_t time = system_time();
|
||||||
xdelta = -fSpecs->edgeMotionSpeedFactor * fSpeed;
|
if (fLastEdgeMotion != 0) {
|
||||||
else if (event->xPosition > uint16(
|
xdelta = fRestEdgeMotion + kEdgeMotionSpeed *
|
||||||
|
float(time - fLastEdgeMotion) / (1000 * 1000);
|
||||||
|
fRestEdgeMotion = xdelta - int32(xdelta);
|
||||||
|
ydelta = xdelta;
|
||||||
|
} else {
|
||||||
|
fRestEdgeMotion = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool inXEdge = false;
|
||||||
|
bool inYEdge = false;
|
||||||
|
|
||||||
|
if (event->xPosition < fSpecs->areaStartX + fSpecs->edgeMotionWidth) {
|
||||||
|
inXEdge = true;
|
||||||
|
xdelta *= -1;
|
||||||
|
} else if (event->xPosition > uint16(
|
||||||
fSpecs->areaEndX - fSpecs->edgeMotionWidth)) {
|
fSpecs->areaEndX - fSpecs->edgeMotionWidth)) {
|
||||||
xdelta = fSpecs->edgeMotionSpeedFactor * fSpeed;
|
inXEdge = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->yPosition < fSpecs->areaStartY + fSpecs->edgeMotionWidth)
|
if (event->yPosition < fSpecs->areaStartY + fSpecs->edgeMotionWidth) {
|
||||||
ydelta = -fSpecs->edgeMotionSpeedFactor * fSpeed;
|
inYEdge = true;
|
||||||
else if (event->yPosition > uint16(
|
ydelta *= -1;
|
||||||
|
} else if (event->yPosition > uint16(
|
||||||
fSpecs->areaEndY - fSpecs->edgeMotionWidth)) {
|
fSpecs->areaEndY - fSpecs->edgeMotionWidth)) {
|
||||||
ydelta = fSpecs->edgeMotionSpeedFactor * fSpeed;
|
inYEdge = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xdelta && validStart)
|
// for a edge motion the drag has to be started in the middle of the pad
|
||||||
|
// TODO: this is difficult to understand simplify the code
|
||||||
|
if (inXEdge && validStart)
|
||||||
movement->xdelta = xdelta;
|
movement->xdelta = xdelta;
|
||||||
if (ydelta && validStart)
|
if (inYEdge && validStart)
|
||||||
movement->ydelta = ydelta;
|
movement->ydelta = ydelta;
|
||||||
|
|
||||||
if ((xdelta || ydelta) && !validStart)
|
if (!inXEdge && !inYEdge)
|
||||||
|
fLastEdgeMotion = 0;
|
||||||
|
else
|
||||||
|
fLastEdgeMotion = time;
|
||||||
|
|
||||||
|
if ((inXEdge || inYEdge) && !validStart)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -452,7 +478,7 @@ TouchpadMovement::_EdgeMotion(mouse_movement *movement, touch_event *event,
|
|||||||
|
|
||||||
|
|
||||||
/*! If a button has been clicked (movement->buttons must be set accordingly),
|
/*! If a button has been clicked (movement->buttons must be set accordingly),
|
||||||
this function updates the click_count, as well as the
|
this function updates the fClickCount, as well as the
|
||||||
\a movement's clicks field.
|
\a movement's clicks field.
|
||||||
Also, it sets the button state from movement->buttons.
|
Also, it sets the button state from movement->buttons.
|
||||||
*/
|
*/
|
||||||
@ -460,19 +486,19 @@ void
|
|||||||
TouchpadMovement::_UpdateButtons(mouse_movement *movement)
|
TouchpadMovement::_UpdateButtons(mouse_movement *movement)
|
||||||
{
|
{
|
||||||
// set click count correctly according to double click timeout
|
// set click count correctly according to double click timeout
|
||||||
if (movement->buttons != 0 && buttons_state == 0) {
|
if (movement->buttons != 0 && fButtonsState == 0) {
|
||||||
if (click_last_time + click_speed > movement->timestamp)
|
if (fClickLastTime + click_speed > movement->timestamp)
|
||||||
click_count++;
|
fClickCount++;
|
||||||
else
|
else
|
||||||
click_count = 1;
|
fClickCount = 1;
|
||||||
|
|
||||||
click_last_time = movement->timestamp;
|
fClickLastTime = movement->timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (movement->buttons != 0)
|
if (movement->buttons != 0)
|
||||||
movement->clicks = click_count;
|
movement->clicks = fClickCount;
|
||||||
|
|
||||||
buttons_state = movement->buttons;
|
fButtonsState = movement->buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -484,40 +510,41 @@ TouchpadMovement::_NoTouchToMovement(touch_event *event,
|
|||||||
|
|
||||||
TRACE("ALPS: no touch event\n");
|
TRACE("ALPS: no touch event\n");
|
||||||
|
|
||||||
scrolling_started = false;
|
fScrollingStarted = false;
|
||||||
movement_started = false;
|
fMovementStarted = false;
|
||||||
|
fLastEdgeMotion = 0;
|
||||||
|
|
||||||
if (tapdrag_started
|
if (fTapdragStarted
|
||||||
&& (movement->timestamp - tap_time) < TAP_TIMEOUT) {
|
&& (movement->timestamp - fTapTime) < fTapTimeOUT) {
|
||||||
buttons = 0x01;
|
buttons = kLeftButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the movement stopped switch off the tap drag when timeout is expired
|
// if the movement stopped switch off the tap drag when timeout is expired
|
||||||
if ((movement->timestamp - tap_time) > TAP_TIMEOUT) {
|
if ((movement->timestamp - fTapTime) > fTapTimeOUT) {
|
||||||
tapdrag_started = false;
|
fTapdragStarted = false;
|
||||||
valid_edge_motion = false;
|
fValidEdgeMotion = false;
|
||||||
TRACE("ALPS: tap drag gesture timed out\n");
|
TRACE("ALPS: tap drag gesture timed out\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abs(tap_delta_x) > 15 || abs(tap_delta_y) > 15) {
|
if (abs(fTapDeltaX) > 15 || abs(fTapDeltaY) > 15) {
|
||||||
tap_started = false;
|
fTapStarted = false;
|
||||||
tap_clicks = 0;
|
fTapClicks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tap_started || double_click) {
|
if (fTapStarted || fDoubleClick) {
|
||||||
TRACE("ALPS: tap gesture\n");
|
TRACE("ALPS: tap gesture\n");
|
||||||
tap_clicks++;
|
fTapClicks++;
|
||||||
|
|
||||||
if (tap_clicks > 1) {
|
if (fTapClicks > 1) {
|
||||||
TRACE("ALPS: empty click\n");
|
TRACE("ALPS: empty click\n");
|
||||||
buttons = 0x00;
|
buttons = kNoButton;
|
||||||
tap_clicks = 0;
|
fTapClicks = 0;
|
||||||
double_click = true;
|
fDoubleClick = true;
|
||||||
} else {
|
} else {
|
||||||
buttons = 0x01;
|
buttons = kLeftButton;
|
||||||
tap_started = false;
|
fTapStarted = false;
|
||||||
tapdrag_started = true;
|
fTapdragStarted = true;
|
||||||
double_click = false;
|
fDoubleClick = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -533,9 +560,9 @@ TouchpadMovement::_MoveToMovement(touch_event *event, mouse_movement *movement)
|
|||||||
float pressure = 0;
|
float pressure = 0;
|
||||||
|
|
||||||
TRACE("ALPS: movement event\n");
|
TRACE("ALPS: movement event\n");
|
||||||
if (!movement_started) {
|
if (!fMovementStarted) {
|
||||||
isStartOfMovement = true;
|
isStartOfMovement = true;
|
||||||
movement_started = true;
|
fMovementStarted = true;
|
||||||
StartNewMovment();
|
StartNewMovment();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,14 +572,14 @@ TouchpadMovement::_MoveToMovement(touch_event *event, mouse_movement *movement)
|
|||||||
movement->ydelta = yDelta;
|
movement->ydelta = yDelta;
|
||||||
|
|
||||||
// tap gesture
|
// tap gesture
|
||||||
tap_delta_x += xDelta;
|
fTapDeltaX += xDelta;
|
||||||
tap_delta_y += yDelta;
|
fTapDeltaY += yDelta;
|
||||||
|
|
||||||
if (tapdrag_started) {
|
if (fTapdragStarted) {
|
||||||
movement->buttons = kLeftButton;
|
movement->buttons = kLeftButton;
|
||||||
movement->clicks = 0;
|
movement->clicks = 0;
|
||||||
|
|
||||||
valid_edge_motion = _EdgeMotion(movement, event, valid_edge_motion);
|
fValidEdgeMotion = _EdgeMotion(movement, event, fValidEdgeMotion);
|
||||||
TRACE("ALPS: tap drag\n");
|
TRACE("ALPS: tap drag\n");
|
||||||
} else {
|
} else {
|
||||||
TRACE("ALPS: movement set buttons\n");
|
TRACE("ALPS: movement set buttons\n");
|
||||||
@ -563,15 +590,15 @@ TouchpadMovement::_MoveToMovement(touch_event *event, mouse_movement *movement)
|
|||||||
// to high
|
// to high
|
||||||
pressure = 20 * (event->zPressure - fSpecs->minPressure)
|
pressure = 20 * (event->zPressure - fSpecs->minPressure)
|
||||||
/ (fSpecs->realMaxPressure - fSpecs->minPressure);
|
/ (fSpecs->realMaxPressure - fSpecs->minPressure);
|
||||||
if (!tap_started
|
if (!fTapStarted
|
||||||
&& isStartOfMovement
|
&& isStartOfMovement
|
||||||
&& fSettings->tapgesture_sensibility > 0.
|
&& fSettings->tapgesture_sensibility > 0.
|
||||||
&& fSettings->tapgesture_sensibility > (20 - pressure)) {
|
&& fSettings->tapgesture_sensibility > (20 - pressure)) {
|
||||||
TRACE("ALPS: tap started\n");
|
TRACE("ALPS: tap started\n");
|
||||||
tap_started = true;
|
fTapStarted = true;
|
||||||
tap_time = system_time();
|
fTapTime = system_time();
|
||||||
tap_delta_x = 0;
|
fTapDeltaX = 0;
|
||||||
tap_delta_y = 0;
|
fTapDeltaY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_UpdateButtons(movement);
|
_UpdateButtons(movement);
|
||||||
@ -592,17 +619,17 @@ TouchpadMovement::_CheckScrollingToMovement(touch_event *event,
|
|||||||
|
|
||||||
// if a button is pressed don't allow to scroll, we likely be in a drag
|
// if a button is pressed don't allow to scroll, we likely be in a drag
|
||||||
// action
|
// action
|
||||||
if (buttons_state != 0)
|
if (fButtonsState != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ((fSpecs->areaEndX - fAreaWidth * fSettings->scroll_rightrange
|
if ((fSpecs->areaEndX - fAreaWidth * fSettings->scroll_rightrange
|
||||||
< event->xPosition && !movement_started
|
< event->xPosition && !fMovementStarted
|
||||||
&& fSettings->scroll_rightrange > 0.000001)
|
&& fSettings->scroll_rightrange > 0.000001)
|
||||||
|| fSettings->scroll_rightrange > 0.999999) {
|
|| fSettings->scroll_rightrange > 0.999999) {
|
||||||
isSideScrollingV = true;
|
isSideScrollingV = true;
|
||||||
}
|
}
|
||||||
if ((fSpecs->areaStartY + fAreaHeight * fSettings->scroll_bottomrange
|
if ((fSpecs->areaStartY + fAreaHeight * fSettings->scroll_bottomrange
|
||||||
> event->yPosition && !movement_started
|
> event->yPosition && !fMovementStarted
|
||||||
&& fSettings->scroll_bottomrange > 0.000001)
|
&& fSettings->scroll_bottomrange > 0.000001)
|
||||||
|| fSettings->scroll_bottomrange > 0.999999) {
|
|| fSettings->scroll_bottomrange > 0.999999) {
|
||||||
isSideScrollingH = true;
|
isSideScrollingH = true;
|
||||||
@ -615,18 +642,18 @@ TouchpadMovement::_CheckScrollingToMovement(touch_event *event,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isSideScrollingV && !isSideScrollingH) {
|
if (!isSideScrollingV && !isSideScrollingH) {
|
||||||
scrolling_started = false;
|
fScrollingStarted = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("ALPS: scroll event\n");
|
TRACE("ALPS: scroll event\n");
|
||||||
|
|
||||||
tap_started = false;
|
fTapStarted = false;
|
||||||
tap_clicks = 0;
|
fTapClicks = 0;
|
||||||
tapdrag_started = false;
|
fTapdragStarted = false;
|
||||||
valid_edge_motion = false;
|
fValidEdgeMotion = false;
|
||||||
if (!scrolling_started) {
|
if (!fScrollingStarted) {
|
||||||
scrolling_started = true;
|
fScrollingStarted = true;
|
||||||
StartNewMovment();
|
StartNewMovment();
|
||||||
}
|
}
|
||||||
GetScrolling(event->xPosition, event->yPosition);
|
GetScrolling(event->xPosition, event->yPosition);
|
||||||
@ -638,7 +665,7 @@ TouchpadMovement::_CheckScrollingToMovement(touch_event *event,
|
|||||||
else if (isSideScrollingH && !isSideScrollingV)
|
else if (isSideScrollingH && !isSideScrollingV)
|
||||||
movement->wheel_ydelta = 0;
|
movement->wheel_ydelta = 0;
|
||||||
|
|
||||||
buttons_state = movement->buttons;
|
fButtonsState = movement->buttons;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ struct touch_event {
|
|||||||
|
|
||||||
struct hardware_specs {
|
struct hardware_specs {
|
||||||
uint16 edgeMotionWidth;
|
uint16 edgeMotionWidth;
|
||||||
uint16 edgeMotionSpeedFactor;
|
|
||||||
|
|
||||||
uint16 areaStartX;
|
uint16 areaStartX;
|
||||||
uint16 areaEndX;
|
uint16 areaEndX;
|
||||||
@ -76,17 +75,18 @@ protected:
|
|||||||
int8 fSpeed;
|
int8 fSpeed;
|
||||||
int16 fAreaWidth;
|
int16 fAreaWidth;
|
||||||
int16 fAreaHeight;
|
int16 fAreaHeight;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _GetRawMovement(uint32 posX, uint32 posY);
|
void _GetRawMovement(uint32 posX, uint32 posY);
|
||||||
void _ComputeAcceleration(int8 accel_factor);
|
void _ComputeAcceleration(int8 accel_factor);
|
||||||
|
|
||||||
|
|
||||||
bool movementStarted;
|
bool fMovementMakerStarted;
|
||||||
|
|
||||||
uint32 previousX;
|
uint32 fPreviousX;
|
||||||
uint32 previousY;
|
uint32 fPreviousY;
|
||||||
int32 deltaSumX;
|
int32 fDeltaSumX;
|
||||||
int32 deltaSumY;
|
int32 fDeltaSumY;
|
||||||
|
|
||||||
int8 fSmallMovement;
|
int8 fSmallMovement;
|
||||||
};
|
};
|
||||||
@ -94,6 +94,7 @@ private:
|
|||||||
|
|
||||||
enum button_ids
|
enum button_ids
|
||||||
{
|
{
|
||||||
|
kNoButton = 0x00,
|
||||||
kLeftButton = 0x01,
|
kLeftButton = 0x01,
|
||||||
kRightButton = 0x02
|
kRightButton = 0x02
|
||||||
};
|
};
|
||||||
@ -106,6 +107,9 @@ public:
|
|||||||
status_t EventToMovement(touch_event *event,
|
status_t EventToMovement(touch_event *event,
|
||||||
mouse_movement *movement);
|
mouse_movement *movement);
|
||||||
|
|
||||||
|
bool TapDragStarted() { return fTapdragStarted; }
|
||||||
|
bool WasEdgeMotion() { return fValidEdgeMotion; }
|
||||||
|
|
||||||
bigtime_t click_speed;
|
bigtime_t click_speed;
|
||||||
private:
|
private:
|
||||||
bool _EdgeMotion(mouse_movement *movement,
|
bool _EdgeMotion(mouse_movement *movement,
|
||||||
@ -118,20 +122,24 @@ private:
|
|||||||
inline bool _CheckScrollingToMovement(touch_event *event,
|
inline bool _CheckScrollingToMovement(touch_event *event,
|
||||||
mouse_movement *movement);
|
mouse_movement *movement);
|
||||||
|
|
||||||
bool movement_started;
|
bool fMovementStarted;
|
||||||
bool scrolling_started;
|
bool fScrollingStarted;
|
||||||
bool tap_started;
|
bool fTapStarted;
|
||||||
bigtime_t tap_time;
|
bigtime_t fTapTime;
|
||||||
int32 tap_delta_x;
|
int32 fTapDeltaX;
|
||||||
int32 tap_delta_y;
|
int32 fTapDeltaY;
|
||||||
int32 tap_clicks;
|
int32 fTapClicks;
|
||||||
bool tapdrag_started;
|
bool fTapdragStarted;
|
||||||
bool valid_edge_motion;
|
|
||||||
bool double_click;
|
|
||||||
|
|
||||||
bigtime_t click_last_time;
|
bool fValidEdgeMotion;
|
||||||
int32 click_count;
|
bigtime_t fLastEdgeMotion;
|
||||||
uint32 buttons_state;
|
float fRestEdgeMotion;
|
||||||
|
|
||||||
|
bool fDoubleClick;
|
||||||
|
|
||||||
|
bigtime_t fClickLastTime;
|
||||||
|
int32 fClickCount;
|
||||||
|
uint32 fButtonsState;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,6 +18,71 @@
|
|||||||
#include "ps2_service.h"
|
#include "ps2_service.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int32 generate_event(timer* timer);
|
||||||
|
|
||||||
|
|
||||||
|
const bigtime_t kEventInterval = 1000 * 50;
|
||||||
|
|
||||||
|
|
||||||
|
class EventProducer {
|
||||||
|
public:
|
||||||
|
EventProducer()
|
||||||
|
{
|
||||||
|
fFired = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
FireEvent(alps_cookie* cookie, uint8* package)
|
||||||
|
{
|
||||||
|
fCookie = cookie;
|
||||||
|
memcpy(fLastPackage, package, sizeof(uint8) * PS2_PACKET_ALPS);
|
||||||
|
|
||||||
|
status_t status = add_timer(&fEventTimer, &generate_event,
|
||||||
|
kEventInterval, B_ONE_SHOT_RELATIVE_TIMER);
|
||||||
|
if (status == B_OK)
|
||||||
|
fFired = true;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CancelEvent()
|
||||||
|
{
|
||||||
|
if (!fFired)
|
||||||
|
return false;
|
||||||
|
fFired = false;
|
||||||
|
return cancel_timer(&fEventTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InjectEvent()
|
||||||
|
{
|
||||||
|
if (packet_buffer_write(fCookie->ring_buffer, fLastPackage,
|
||||||
|
PS2_PACKET_ALPS) != PS2_PACKET_ALPS) {
|
||||||
|
// buffer is full, drop new data
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
release_sem_etc(fCookie->sem, 1, B_DO_NOT_RESCHEDULE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool fFired;
|
||||||
|
uint8 fLastPackage[PS2_PACKET_ALPS];
|
||||||
|
timer fEventTimer;
|
||||||
|
alps_cookie* fCookie;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static EventProducer gEventProducer;
|
||||||
|
|
||||||
|
|
||||||
|
static int32
|
||||||
|
generate_event(timer* timer)
|
||||||
|
{
|
||||||
|
gEventProducer.InjectEvent();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const char* kALPSPath[4] = {
|
const char* kALPSPath[4] = {
|
||||||
"input/touchpad/ps2/alps_0",
|
"input/touchpad/ps2/alps_0",
|
||||||
"input/touchpad/ps2/alps_1",
|
"input/touchpad/ps2/alps_1",
|
||||||
@ -100,13 +165,12 @@ static alps_model_info* sFoundModel = NULL;
|
|||||||
|
|
||||||
|
|
||||||
// touchpad proportions
|
// touchpad proportions
|
||||||
#define EDGE_MOTION_WIDTH 45
|
#define EDGE_MOTION_WIDTH 55
|
||||||
#define EDGE_MOTION_SPEED 4
|
|
||||||
// increase the touchpad size a little bit
|
// increase the touchpad size a little bit
|
||||||
#define AREA_START_X 40
|
#define AREA_START_X 40
|
||||||
#define AREA_END_X 987
|
#define AREA_END_X 987
|
||||||
#define AREA_START_Y 40
|
#define AREA_START_Y 40
|
||||||
#define AREA_END_Y 733
|
#define AREA_END_Y 734
|
||||||
|
|
||||||
#define MIN_PRESSURE 15
|
#define MIN_PRESSURE 15
|
||||||
#define REAL_MAX_PRESSURE 70
|
#define REAL_MAX_PRESSURE 70
|
||||||
@ -128,13 +192,6 @@ byte 3: 0 y9 y8 y7 1 M R L
|
|||||||
byte 4: 0 y6 y5 y4 y3 y2 y1 y0
|
byte 4: 0 y6 y5 y4 y3 y2 y1 y0
|
||||||
byte 5: 0 z6 z5 z4 z3 z2 z1 z0
|
byte 5: 0 z6 z5 z4 z3 z2 z1 z0
|
||||||
*/
|
*/
|
||||||
// debug
|
|
||||||
static uint32 minX = 50000;
|
|
||||||
static uint32 minY = 50000;
|
|
||||||
static uint32 maxX = 0;
|
|
||||||
static uint32 maxY = 0;
|
|
||||||
static uint32 maxZ = 0;
|
|
||||||
// debug end
|
|
||||||
static status_t
|
static status_t
|
||||||
get_alps_movment(alps_cookie *cookie, mouse_movement *movement)
|
get_alps_movment(alps_cookie *cookie, mouse_movement *movement)
|
||||||
{
|
{
|
||||||
@ -174,31 +231,14 @@ get_alps_movment(alps_cookie *cookie, mouse_movement *movement)
|
|||||||
event.wValue = 4;
|
event.wValue = 4;
|
||||||
}
|
}
|
||||||
// if hardware tab gesture is off a z pressure of 16 is reported
|
// if hardware tab gesture is off a z pressure of 16 is reported
|
||||||
//if (cookie->previousZ == 0 && event.wValue == 4 && event.zPressure == 16)
|
if (cookie->previousZ == 0 && event.wValue == 4 && event.zPressure == 16)
|
||||||
// event.zPressure = 60;
|
event.zPressure = 60;
|
||||||
|
|
||||||
cookie->previousZ = event.zPressure;
|
cookie->previousZ = event.zPressure;
|
||||||
|
|
||||||
event.xPosition = event_buffer[1] | ((event_buffer[2] & 0x78) << 4);
|
event.xPosition = event_buffer[1] | ((event_buffer[2] & 0x78) << 4);
|
||||||
event.yPosition = event_buffer[4] | ((event_buffer[3] & 0x70) << 3);
|
event.yPosition = event_buffer[4] | ((event_buffer[3] & 0x70) << 3);
|
||||||
|
|
||||||
// debug
|
|
||||||
if (event.xPosition < minX)
|
|
||||||
minX = event.xPosition;
|
|
||||||
if (event.yPosition < minY)
|
|
||||||
minY = event.yPosition;
|
|
||||||
if (event.xPosition > maxX)
|
|
||||||
maxX = event.xPosition;
|
|
||||||
if (event.yPosition > maxY)
|
|
||||||
maxY = event.yPosition;
|
|
||||||
if (event.zPressure > maxZ)
|
|
||||||
maxZ = event.zPressure;
|
|
||||||
bigtime_t time = system_time();
|
|
||||||
dprintf("x %i %i, y %i %i, z %i %i, time %i, fin %i ges %i\n", minX, maxX, minY, maxY,
|
|
||||||
maxZ, event.zPressure, time, event_buffer[2] & 0x2,
|
|
||||||
event_buffer[2] & 0x1);
|
|
||||||
// debug end
|
|
||||||
|
|
||||||
// check for trackpoint even (z pressure 127)
|
// check for trackpoint even (z pressure 127)
|
||||||
if (sFoundModel->flags & ALPS_DUALPOINT && event.zPressure == 127) {
|
if (sFoundModel->flags & ALPS_DUALPOINT && event.zPressure == 127) {
|
||||||
movement->xdelta = event.xPosition > 383 ? event.xPosition - 768
|
movement->xdelta = event.xPosition > 383 ? event.xPosition - 768
|
||||||
@ -212,6 +252,12 @@ dprintf("x %i %i, y %i %i, z %i %i, time %i, fin %i ges %i\n", minX, maxX, minY,
|
|||||||
event.yPosition = AREA_END_Y - (event.yPosition - AREA_START_Y);
|
event.yPosition = AREA_END_Y - (event.yPosition - AREA_START_Y);
|
||||||
status = cookie->movementMaker.EventToMovement(&event, movement);
|
status = cookie->movementMaker.EventToMovement(&event, movement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cookie->movementMaker.WasEdgeMotion()
|
||||||
|
|| cookie->movementMaker.TapDragStarted()) {
|
||||||
|
gEventProducer.FireEvent(cookie, event_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +272,6 @@ default_settings(touchpad_settings *set)
|
|||||||
status_t
|
status_t
|
||||||
probe_alps(ps2_dev* dev)
|
probe_alps(ps2_dev* dev)
|
||||||
{
|
{
|
||||||
return B_ERROR;
|
|
||||||
int i;
|
int i;
|
||||||
uint8 val[3];
|
uint8 val[3];
|
||||||
TRACE("ALPS: probe\n");
|
TRACE("ALPS: probe\n");
|
||||||
@ -345,6 +390,8 @@ alps_open(const char *name, uint32 flags, void **_cookie)
|
|||||||
alps_cookie* cookie = (alps_cookie*)malloc(sizeof(alps_cookie));
|
alps_cookie* cookie = (alps_cookie*)malloc(sizeof(alps_cookie));
|
||||||
if (cookie == NULL)
|
if (cookie == NULL)
|
||||||
goto err1;
|
goto err1;
|
||||||
|
memset(cookie, 0, sizeof(*cookie));
|
||||||
|
|
||||||
cookie->movementMaker.Init();
|
cookie->movementMaker.Init();
|
||||||
cookie->previousZ = 0;
|
cookie->previousZ = 0;
|
||||||
*_cookie = cookie;
|
*_cookie = cookie;
|
||||||
@ -357,7 +404,6 @@ alps_open(const char *name, uint32 flags, void **_cookie)
|
|||||||
default_settings(&cookie->settings);
|
default_settings(&cookie->settings);
|
||||||
|
|
||||||
gHardwareSpecs.edgeMotionWidth = EDGE_MOTION_WIDTH;
|
gHardwareSpecs.edgeMotionWidth = EDGE_MOTION_WIDTH;
|
||||||
gHardwareSpecs.edgeMotionSpeedFactor = EDGE_MOTION_SPEED;
|
|
||||||
|
|
||||||
gHardwareSpecs.areaStartX = AREA_START_X;
|
gHardwareSpecs.areaStartX = AREA_START_X;
|
||||||
gHardwareSpecs.areaEndX = AREA_END_X;
|
gHardwareSpecs.areaEndX = AREA_END_X;
|
||||||
@ -392,7 +438,7 @@ alps_open(const char *name, uint32 flags, void **_cookie)
|
|||||||
goto err4;
|
goto err4;
|
||||||
|
|
||||||
// switch tap mode off
|
// switch tap mode off
|
||||||
if (switch_hardware_tab(dev, true) != B_OK)
|
if (switch_hardware_tab(dev, false) != B_OK)
|
||||||
goto err4;
|
goto err4;
|
||||||
|
|
||||||
// init the alps device to absolut mode
|
// init the alps device to absolut mode
|
||||||
@ -435,7 +481,8 @@ err1:
|
|||||||
status_t
|
status_t
|
||||||
alps_close(void *_cookie)
|
alps_close(void *_cookie)
|
||||||
{
|
{
|
||||||
status_t status;
|
gEventProducer.CancelEvent();
|
||||||
|
|
||||||
alps_cookie *cookie = (alps_cookie*)_cookie;
|
alps_cookie *cookie = (alps_cookie*)_cookie;
|
||||||
|
|
||||||
ps2_dev_command_timeout(cookie->dev, PS2_CMD_DISABLE, NULL, 0, NULL, 0,
|
ps2_dev_command_timeout(cookie->dev, PS2_CMD_DISABLE, NULL, 0, NULL, 0,
|
||||||
@ -450,7 +497,7 @@ alps_close(void *_cookie)
|
|||||||
// Reset the touchpad so it generate standard ps2 packets instead of
|
// Reset the touchpad so it generate standard ps2 packets instead of
|
||||||
// extended ones. If not, BeOS is confused with such packets when rebooting
|
// extended ones. If not, BeOS is confused with such packets when rebooting
|
||||||
// without a complete shutdown.
|
// without a complete shutdown.
|
||||||
status = ps2_reset_mouse(cookie->dev);
|
status_t status = ps2_reset_mouse(cookie->dev);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
INFO("ps2: reset failed\n");
|
INFO("ps2: reset failed\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@ -505,7 +552,7 @@ alps_ioctl(void *_cookie, uint32 op, void *buffer, size_t length)
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
alps_read(void *cookie, off_t pos, void *buffer, size_t *_length)
|
alps_read(void* cookie, off_t pos, void* buffer, size_t* _length)
|
||||||
{
|
{
|
||||||
*_length = 0;
|
*_length = 0;
|
||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
@ -513,7 +560,7 @@ alps_read(void *cookie, off_t pos, void *buffer, size_t *_length)
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
alps_write(void *cookie, off_t pos, const void *buffer, size_t *_length)
|
alps_write(void* cookie, off_t pos, const void* buffer, size_t* _length)
|
||||||
{
|
{
|
||||||
*_length = 0;
|
*_length = 0;
|
||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
@ -521,11 +568,14 @@ alps_write(void *cookie, off_t pos, const void *buffer, size_t *_length)
|
|||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
alps_handle_int(ps2_dev *dev)
|
alps_handle_int(ps2_dev* dev)
|
||||||
{
|
{
|
||||||
alps_cookie *cookie = (alps_cookie*)dev->cookie;
|
alps_cookie* cookie = (alps_cookie*)dev->cookie;
|
||||||
uint8 val;
|
|
||||||
|
|
||||||
|
// we got a real event cancel the fake event
|
||||||
|
gEventProducer.CancelEvent();
|
||||||
|
|
||||||
|
uint8 val;
|
||||||
val = cookie->dev->history[0].data;
|
val = cookie->dev->history[0].data;
|
||||||
if (cookie->packet_index == 0
|
if (cookie->packet_index == 0
|
||||||
&& (val & sFoundModel->maskFirstByte) != sFoundModel->firstByte) {
|
&& (val & sFoundModel->maskFirstByte) != sFoundModel->firstByte) {
|
||||||
|
@ -11,18 +11,18 @@
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ps2_dev* dev;
|
ps2_dev* dev;
|
||||||
|
|
||||||
sem_id sem;
|
sem_id sem;
|
||||||
struct packet_buffer* ring_buffer;
|
struct packet_buffer* ring_buffer;
|
||||||
size_t packet_index;
|
size_t packet_index;
|
||||||
uint8 buffer[PS2_PACKET_ALPS];
|
uint8 buffer[PS2_PACKET_ALPS];
|
||||||
uint8 mode;
|
uint8 mode;
|
||||||
|
|
||||||
uint8 previousZ;
|
uint8 previousZ;
|
||||||
TouchpadMovement movementMaker;
|
TouchpadMovement movementMaker;
|
||||||
|
|
||||||
touchpad_settings settings;
|
touchpad_settings settings;
|
||||||
} alps_cookie;
|
} alps_cookie;
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
// synaptics touchpad proportions
|
// synaptics touchpad proportions
|
||||||
#define SYN_EDGE_MOTION_WIDTH 50
|
#define SYN_EDGE_MOTION_WIDTH 50
|
||||||
#define SYN_EDGE_MOTION_SPEED 5
|
|
||||||
#define SYN_AREA_OFFSET 40
|
#define SYN_AREA_OFFSET 40
|
||||||
|
|
||||||
#define MIN_PRESSURE 30
|
#define MIN_PRESSURE 30
|
||||||
@ -345,7 +344,6 @@ synaptics_open(const char *name, uint32 flags, void **_cookie)
|
|||||||
default_settings(&cookie->settings);
|
default_settings(&cookie->settings);
|
||||||
|
|
||||||
gHardwareSpecs.edgeMotionWidth = SYN_EDGE_MOTION_WIDTH;
|
gHardwareSpecs.edgeMotionWidth = SYN_EDGE_MOTION_WIDTH;
|
||||||
gHardwareSpecs.edgeMotionSpeedFactor = SYN_EDGE_MOTION_SPEED;
|
|
||||||
|
|
||||||
gHardwareSpecs.areaStartX = SYN_AREA_START_X;
|
gHardwareSpecs.areaStartX = SYN_AREA_START_X;
|
||||||
gHardwareSpecs.areaEndX = SYN_AREA_END_X;
|
gHardwareSpecs.areaEndX = SYN_AREA_END_X;
|
||||||
|
Loading…
Reference in New Issue
Block a user