[haiku-commits] r41140 - haiku/trunk/src/add-ons/kernel/bus_managers/ps2

  • From: clemens.zeidler@xxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 30 Mar 2011 11:37:41 +0200 (CEST)

Author: czeidler
Date: 2011-03-30 11:37:40 +0200 (Wed, 30 Mar 2011)
New Revision: 41140
Changeset: https://dev.haiku-os.org/changeset/41140

Modified:
   haiku/trunk/src/add-ons/kernel/bus_managers/ps2/movement_maker.cpp
   haiku/trunk/src/add-ons/kernel/bus_managers/ps2/movement_maker.h
   haiku/trunk/src/add-ons/kernel/bus_managers/ps2/ps2_alps.cpp
   haiku/trunk/src/add-ons/kernel/bus_managers/ps2/ps2_alps.h
   haiku/trunk/src/add-ons/kernel/bus_managers/ps2/ps2_synaptics.cpp
   haiku/trunk/src/add-ons/kernel/bus_managers/ps2/ps2_synaptics.h
Log:
- ALPS and synaptics are sharing the same code to generate mouse events now. 
The movement generation is calibrated on the synaptics touchpad, though. 
ALPS movements are fine now, hope the synaptics is still working. Please test! 
There are still some leftovers form switching from a c struct to a c++ 
class will fix that later.
- Support ALPS devices with passthrough.
- ALPS is still disabled because tap and edge motion is not working yet. The 
problem is that synaptics generates more helper events which makes this a lot
easier to implement. My plan is to emulate this events to imitate the synatics 
touchpad.



Modified: haiku/trunk/src/add-ons/kernel/bus_managers/ps2/movement_maker.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/bus_managers/ps2/movement_maker.cpp  
2011-03-29 22:51:41 UTC (rev 41139)
+++ haiku/trunk/src/add-ons/kernel/bus_managers/ps2/movement_maker.cpp  
2011-03-30 09:37:40 UTC (rev 41140)
@@ -1,12 +1,24 @@
 #include "movement_maker.h"
 
-#include <Debug.h>
+#include <stdlib.h>
+
+#include <KernelExport.h>
+
+
 #if 1
 #      define INFO(x...) dprintf(x)
 #else
 #      define INFO(x...)
 #endif
 
+// #define TRACE_MOVEMENT_MAKER
+#ifdef TRACE_MOVEMENT_MAKER
+#      define TRACE(x...) dprintf(x)
+#else
+#      define TRACE(x...)
+#endif
+
+
 typedef union {
   float value;
   /* FIXME: Assumes 32 bit int.  */
@@ -173,142 +185,460 @@
 }
 
 
+
 void
-get_raw_movement(movement_maker *move, uint32 posX, uint32 posY)
+MovementMaker::SetSettings(touchpad_settings* settings)
 {
+       fSettings = settings;
+}
+
+
+void
+MovementMaker::SetSpecs(hardware_specs* specs)
+{
+       fSpecs = specs;
+
+       fAreaWidth = fSpecs->areaEndX - fSpecs->areaStartX;
+       fAreaHeight = fSpecs->areaEndY - fSpecs->areaStartY;
+
+       // calibrated on the synaptics touchpad
+       fSpeed = 4100 / fAreaWidth;
+       fSmallMovement = 3 / fSpeed;
+}
+
+
+void
+MovementMaker::StartNewMovment()
+{
+       if (fSettings->scroll_xstepsize <= 0)
+               fSettings->scroll_xstepsize = 1;
+       if (fSettings->scroll_ystepsize <= 0)
+               fSettings->scroll_ystepsize = 1;
+
+       movementStarted = true;
+       scrolling_x = 0;
+       scrolling_y = 0;
+}
+
+
+void
+MovementMaker::GetMovement(uint32 posX, uint32 posY)
+{
+       _GetRawMovement(posX, posY);
+
+//     INFO("SYN: pos: %lu x %lu, delta: %ld x %ld, sums: %ld x %ld\n",
+//             posX, posY, xDelta, yDelta,
+//             deltaSumX, deltaSumY);
+
+       xDelta = xDelta;
+       yDelta = yDelta;
+}
+
+
+void
+MovementMaker::GetScrolling(uint32 posX, uint32 posY)
+{
+       int32 stepsX = 0, stepsY = 0;
+
+       _GetRawMovement(posX, posY);
+       _ComputeAcceleration(fSettings->scroll_acceleration);
+
+       if (fSettings->scroll_xstepsize > 0) {
+               scrolling_x += xDelta;
+
+               stepsX = make_small(scrolling_x / fSettings->scroll_xstepsize);
+
+               scrolling_x -= stepsX * fSettings->scroll_xstepsize;
+               xDelta = stepsX;
+       } else {
+               scrolling_x = 0;
+               xDelta = 0;
+       }
+       if (fSettings->scroll_ystepsize > 0) {
+               scrolling_y += yDelta;
+
+               stepsY = make_small(scrolling_y / fSettings->scroll_ystepsize);
+
+               scrolling_y -= stepsY * fSettings->scroll_ystepsize;
+               yDelta = -1 * stepsY;
+       } else {
+               scrolling_y = 0;
+               yDelta = 0;
+       }
+}
+
+
+void
+MovementMaker::_GetRawMovement(uint32 posX, uint32 posY)
+{
+       // calibrated on the synaptics touchpad
+       posX = posX * float(SYN_WIDTH) / fAreaWidth;
+       posY = posY * float(SYN_HEIGHT) / fAreaHeight;
+
        const float acceleration = 0.8;
        const float translation = 12.0;
 
        int diff;
-       float xDelta, yDelta;
 
-       if (move->movementStarted) {
-               move->movementStarted = false;
+       if (movementStarted) {
+               movementStarted = false;
                // init delta tracking
-               move->previousX = posX;
-               move->previousY = posY;
+               previousX = posX;
+               previousY = posY;
                // deltas are automatically reset
        }
 
        // accumulate delta and store current pos, reset if pos did not change
-       diff = posX - move->previousX;
+       diff = posX - previousX;
        // lessen the effect of small diffs
-       if ((diff > -3 && diff < -1) || (diff > 1 && diff < 3))
+       if ((diff > -fSmallMovement && diff < -1)
+               || (diff > 1 && diff < fSmallMovement)) {
                diff /= 2;
+       }
        if (diff == 0)
-               move->deltaSumX = 0.0;
+               deltaSumX = 0.0;
        else
-               move->deltaSumX += diff;
+               deltaSumX += diff;
 
-       diff = posY - move->previousY;
+       diff = posY - previousY;
        // lessen the effect of small diffs
-       if ((diff > -3 && diff < -1) || (diff > 1 && diff < 3))
+       if ((diff > -fSmallMovement && diff < -1)
+               || (diff > 1 && diff < fSmallMovement)) {
                diff /= 2;
+       }
        if (diff == 0)
-               move->deltaSumY = 0.0;
+               deltaSumY = 0.0;
        else
-               move->deltaSumY += diff;
+               deltaSumY += diff;
 
-       move->previousX = posX;
-       move->previousY = posY;
+       previousX = posX;
+       previousY = posY;
 
        // compute current delta and reset accumulated delta if
        // abs() is greater than 1
-       xDelta = move->deltaSumX / translation;
-       yDelta = move->deltaSumY / translation;
+       xDelta = deltaSumX / translation;
+       yDelta = deltaSumY / translation;
        if (xDelta > 1.0) {
-               move->deltaSumX = 0.0;
+               deltaSumX = 0.0;
                xDelta = 1.0 + (xDelta - 1.0) * acceleration;
        } else if (xDelta < -1.0) {
-               move->deltaSumX = 0.0;
+               deltaSumX = 0.0;
                xDelta = -1.0 + (xDelta + 1.0) * acceleration;
        }
 
        if (yDelta > 1.0) {
-               move->deltaSumY = 0.0;
+               deltaSumY = 0.0;
                yDelta = 1.0 + (yDelta - 1.0) * acceleration;
        } else if (yDelta < -1.0) {
-               move->deltaSumY = 0.0;
+               deltaSumY = 0.0;
                yDelta = -1.0 + (yDelta + 1.0) * acceleration;
        }
 
-       move->xDelta = make_small(xDelta);
-       move->yDelta = make_small(yDelta);
+       xDelta = make_small(xDelta);
+       yDelta = make_small(yDelta);
 }
 
 
+
 void
-compute_acceleration(movement_maker *move, int8 accel_factor)
+MovementMaker::_ComputeAcceleration(int8 accel_factor)
 {
        // acceleration
        float acceleration = 1;
        if (accel_factor != 0) {
-               acceleration = 1 + sqrtf(move->xDelta * move->xDelta
-                       + move->yDelta * move->yDelta) * accel_factor / 50.0;
+               acceleration = 1 + sqrtf(xDelta * xDelta
+                       + yDelta * yDelta) * accel_factor / 50.0;
        }
 
-       move->xDelta = make_small(move->xDelta * acceleration);
-       move->yDelta = make_small(move->yDelta * acceleration);
+       xDelta = make_small(xDelta * acceleration);
+       yDelta = make_small(yDelta * acceleration);
 }
 
 
+// #pragma mark -
+
+
+#define TAP_TIMEOUT                    200000
+
+
 void
-get_movement(movement_maker *move, uint32 posX, uint32 posY)
+TouchpadMovement::Init()
 {
-       get_raw_movement(move, posX, posY);
+       movement_started = false;
+       scrolling_started = false;
+       tap_started = false;
+       valid_edge_motion = false;
+       double_click = false;
+}
 
-//     INFO("SYN: pos: %lu x %lu, delta: %ld x %ld, sums: %ld x %ld\n",
-//             posX, posY, move->xDelta, move->yDelta,
-//             move->deltaSumX, move->deltaSumY);
 
-       move->xDelta = move->xDelta * move->speed;
-       move->yDelta = move->yDelta * move->speed;
+status_t
+TouchpadMovement::EventToMovement(touch_event *event, mouse_movement *movement)
+{
+       if (!movement)
+               return B_ERROR;
+
+       movement->xdelta = 0;
+       movement->ydelta = 0;
+       movement->buttons = 0;
+       movement->wheel_ydelta = 0;
+       movement->wheel_xdelta = 0;
+       movement->modifiers = 0;
+       movement->clicks = 0;
+       movement->timestamp = system_time();
+
+       if ((movement->timestamp - tap_time) > TAP_TIMEOUT) {
+               TRACE("ALPS: tap gesture timed out\n");
+               tap_started = false;
+               if (!double_click
+                       || (movement->timestamp - tap_time) > 2 * TAP_TIMEOUT) {
+                       tap_clicks = 0;
+               }
+       }
+
+       if (event->buttons & kLeftButton) {
+               tap_clicks = 0;
+               tapdrag_started = false;
+               tap_started = false;
+               valid_edge_motion = false;
+       }
+
+       if (event->zPressure >= fSpecs->minPressure
+               && event->zPressure < fSpecs->maxPressure
+               && ((event->wValue >= 4 && event->wValue <= 7)
+                       || event->wValue == 0 || event->wValue == 1)
+               && (event->xPosition != 0 || event->yPosition != 0)) {
+               // The touch pad is in touch with at least one finger
+               if (!_CheckScrollingToMovement(event, movement))
+                       _MoveToMovement(event, movement);
+       } else
+               _NoTouchToMovement(event, movement);
+
+       return B_OK;
 }
 
 
+bool
+TouchpadMovement::_EdgeMotion(mouse_movement *movement, touch_event *event,
+       bool validStart)
+{
+       int32 xdelta = 0;
+       int32 ydelta = 0;
+
+       if (event->xPosition < fSpecs->areaStartX + fSpecs->edgeMotionWidth)
+               xdelta = -fSpecs->edgeMotionSpeedFactor * fSpeed;
+       else if (event->xPosition > uint16(
+               fSpecs->areaEndX - fSpecs->edgeMotionWidth)) {
+               xdelta = fSpecs->edgeMotionSpeedFactor * fSpeed;
+       }
+
+       if (event->yPosition < fSpecs->areaStartY + fSpecs->edgeMotionWidth)
+               ydelta = -fSpecs->edgeMotionSpeedFactor * fSpeed;
+       else if (event->yPosition > uint16(
+               fSpecs->areaEndY - fSpecs->edgeMotionWidth)) {
+               ydelta = fSpecs->edgeMotionSpeedFactor * fSpeed;
+       }
+
+       if (xdelta && validStart)
+               movement->xdelta = xdelta;
+       if (ydelta && validStart)
+               movement->ydelta = ydelta;
+
+       if ((xdelta || ydelta) && !validStart)
+               return false;
+
+       return true;
+}
+
+
+/*!    If a button has been clicked (movement->buttons must be set 
accordingly),
+       this function updates the click_count, as well as the
+       \a movement's clicks field.
+       Also, it sets the button state from movement->buttons.
+*/
 void
-get_scrolling(movement_maker *move, uint32 posX, uint32 posY)
+TouchpadMovement::_UpdateButtons(mouse_movement *movement)
 {
-       int32 stepsX = 0, stepsY = 0;
+       // set click count correctly according to double click timeout
+       if (movement->buttons != 0 && buttons_state == 0) {
+               if (click_last_time + click_speed > movement->timestamp)
+                       click_count++;
+               else
+                       click_count = 1;
 
-       get_raw_movement(move, posX, posY);
-       compute_acceleration(move, move->scroll_acceleration);
+               click_last_time = movement->timestamp;
+       }
 
-       if (move->scrolling_xStep > 0) {
-               move->scrolling_x += move->xDelta;
+       if (movement->buttons != 0)
+               movement->clicks = click_count;
 
-               stepsX = make_small(move->scrolling_x / move->scrolling_xStep);
+       buttons_state = movement->buttons;
+}
 
-               move->scrolling_x -= stepsX * move->scrolling_xStep;
-               move->xDelta = stepsX;
-       } else {
-               move->scrolling_x = 0;
-               move->xDelta = 0;
+
+void
+TouchpadMovement::_NoTouchToMovement(touch_event *event,
+       mouse_movement *movement)
+{
+       uint32 buttons = event->buttons;
+
+       TRACE("ALPS: no touch event\n");
+
+       scrolling_started = false;
+       movement_started = false;
+
+       if (tapdrag_started
+               && (movement->timestamp - tap_time) < TAP_TIMEOUT) {
+               buttons = 0x01;
        }
-       if (move->scrolling_yStep > 0) {
-               move->scrolling_y += move->yDelta;
 
-               stepsY = make_small(move->scrolling_y / move->scrolling_yStep);
+       // if the movement stopped switch off the tap drag when timeout is 
expired
+       if ((movement->timestamp - tap_time) > TAP_TIMEOUT) {
+               tapdrag_started = false;
+               valid_edge_motion = false;
+               TRACE("ALPS: tap drag gesture timed out\n");
+       }
 
-               move->scrolling_y -= stepsY * move->scrolling_yStep;
-               move->yDelta = -1 * stepsY;
-       } else {
-               move->scrolling_y = 0;
-               move->yDelta = 0;
+       if (abs(tap_delta_x) > 15 || abs(tap_delta_y) > 15) {
+               tap_started = false;
+               tap_clicks = 0;
        }
+
+       if (tap_started || double_click) {
+               TRACE("ALPS: tap gesture\n");
+               tap_clicks++;
+
+               if (tap_clicks > 1) {
+                       TRACE("ALPS: empty click\n");
+                       buttons = 0x00;
+                       tap_clicks = 0;
+                       double_click = true;
+               } else {
+                       buttons = 0x01;
+                       tap_started = false;
+                       tapdrag_started = true;
+                       double_click = false;
+               }
+       }
+
+       movement->buttons = buttons;
+       _UpdateButtons(movement);
 }
 
 
 void
-start_new_movment(movement_maker *move)
+TouchpadMovement::_MoveToMovement(touch_event *event, mouse_movement *movement)
 {
-       if (move->scrolling_xStep <= 0)
-               move->scrolling_xStep = 1;
-       if (move->scrolling_yStep <= 0)
-               move->scrolling_yStep = 1;
+       bool isStartOfMovement = false;
+       float pressure = 0;
 
-       move->movementStarted = true;
-       move->scrolling_x = 0;
-       move->scrolling_y = 0;
+       TRACE("ALPS: movement event\n");
+       if (!movement_started) {
+               isStartOfMovement = true;
+               movement_started = true;
+               StartNewMovment();
+       }
+
+       GetMovement(event->xPosition, event->yPosition);
+
+       movement->xdelta = xDelta;
+       movement->ydelta = yDelta;
+
+       // tap gesture
+       tap_delta_x += xDelta;
+       tap_delta_y += yDelta;
+
+       if (tapdrag_started) {
+               movement->buttons = kLeftButton;
+               movement->clicks = 0;
+
+               valid_edge_motion = _EdgeMotion(movement, event, 
valid_edge_motion);
+               TRACE("ALPS: tap drag\n");
+       } else {
+               TRACE("ALPS: movement set buttons\n");
+               movement->buttons = event->buttons;
+       }
+
+       // use only a fraction of pressure range, the max pressure seems to be
+       // to high
+       pressure = 20 * (event->zPressure - fSpecs->minPressure)
+               / (fSpecs->realMaxPressure - fSpecs->minPressure);
+       if (!tap_started
+               && isStartOfMovement
+               && fSettings->tapgesture_sensibility > 0.
+               && fSettings->tapgesture_sensibility > (20 - pressure)) {
+               TRACE("ALPS: tap started\n");
+               tap_started = true;
+               tap_time = system_time();
+               tap_delta_x = 0;
+               tap_delta_y = 0;
+       }
+
+       _UpdateButtons(movement);
 }
 
+
+/*!    Checks if this is a scrolling event or not, and also actually does the
+       scrolling work if it is.
+
+       \return \c true if this was a scrolling event, \c false if not.
+*/
+bool
+TouchpadMovement::_CheckScrollingToMovement(touch_event *event,
+       mouse_movement *movement)
+{
+       bool isSideScrollingV = false;
+       bool isSideScrollingH = false;
+
+       // if a button is pressed don't allow to scroll, we likely be in a drag
+       // action
+       if (buttons_state != 0)
+               return false;
+
+       if ((fSpecs->areaEndX - fAreaWidth * fSettings->scroll_rightrange
+                       < event->xPosition && !movement_started
+               && fSettings->scroll_rightrange > 0.000001)
+                       || fSettings->scroll_rightrange > 0.999999) {
+               isSideScrollingV = true;
+       }
+       if ((fSpecs->areaStartY + fAreaHeight * fSettings->scroll_bottomrange
+                               > event->yPosition && !movement_started
+                       && fSettings->scroll_bottomrange > 0.000001)
+                               || fSettings->scroll_bottomrange > 0.999999) {
+               isSideScrollingH = true;
+       }
+       if ((event->wValue == 0 || event->wValue == 1)
+               && fSettings->scroll_twofinger) {
+               // two finger scrolling is enabled
+               isSideScrollingV = true;
+               isSideScrollingH = fSettings->scroll_twofinger_horizontal;
+       }
+
+       if (!isSideScrollingV && !isSideScrollingH) {
+               scrolling_started = false;
+               return false;
+       }
+
+       TRACE("ALPS: scroll event\n");
+
+       tap_started = false;
+       tap_clicks = 0;
+       tapdrag_started = false;
+       valid_edge_motion = false;
+       if (!scrolling_started) {
+               scrolling_started = true;
+               StartNewMovment();
+       }
+       GetScrolling(event->xPosition, event->yPosition);
+       movement->wheel_ydelta = yDelta;
+       movement->wheel_xdelta = xDelta;
+
+       if (isSideScrollingV && !isSideScrollingH)
+               movement->wheel_xdelta = 0;
+       else if (isSideScrollingH && !isSideScrollingV)
+               movement->wheel_ydelta = 0;
+
+       buttons_state = movement->buttons;
+
+       return true;
+}

Modified: haiku/trunk/src/add-ons/kernel/bus_managers/ps2/movement_maker.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/bus_managers/ps2/movement_maker.h    
2011-03-29 22:51:41 UTC (rev 41139)
+++ haiku/trunk/src/add-ons/kernel/bus_managers/ps2/movement_maker.h    
2011-03-30 09:37:40 UTC (rev 41140)
@@ -3,38 +3,136 @@
 
 #include <OS.h>
 
+#include <keyboard_mouse_driver.h>
+#include <touchpad_settings.h>
 
+
 float floorf(float x);
 float ceilf(float x);
 float sqrtf(float x);
 int32 make_small(float value);
 
-typedef struct {
-       int32                   xDelta;
-       int32                   yDelta;
 
-       int8                    acceleration;
-       int8                    speed;
+struct touch_event {
+       uint8           buttons;
+       uint32          xPosition;
+       uint32          yPosition;
+       uint8           zPressure;
+       // absolut mode (unused)
+       bool            finger;
+       bool            gesture;
+       // absolut w mode
+       uint8           wValue;
+};
 
-       float                   scrolling_x;
-       float                   scrolling_y;
-       int32                   scrolling_xStep;
-       int32                   scrolling_yStep;
-       int32                   scroll_acceleration;
 
-       bool                    movementStarted;
-       uint32                  previousX;
-       uint32                  previousY;
-       int32                   deltaSumX;
-       int32                   deltaSumY;
-} movement_maker;
+struct hardware_specs {
+       uint16          edgeMotionWidth;
+       uint16          edgeMotionSpeedFactor;
 
+       uint16          areaStartX;
+       uint16          areaEndX;
+       uint16          areaStartY;
+       uint16          areaEndY;
 
-void get_raw_movement(movement_maker *move, uint32 posX, uint32 posY);
-void compute_acceleration(movement_maker *move, int8 accel_factor);
-void get_movement(movement_maker *move, uint32 posX, uint32 posY);
-void get_scrolling(movement_maker *move, uint32 posX, uint32 posY);
-void start_new_movment(movement_maker *move);
+       uint16          minPressure;
+       // the value you reach when you hammer really hard on the touchpad
+       uint16          realMaxPressure;
+       uint16          maxPressure;
+};
 
 
+/*! The raw movement calculation is calibrated on ths synaptics touchpad. */
+// increase the touchpad size a little bit
+#define SYN_AREA_TOP_LEFT_OFFSET       40
+#define SYN_AREA_BOTTOM_RIGHT_OFFSET   60
+#define SYN_AREA_START_X               (1472 - SYN_AREA_TOP_LEFT_OFFSET)
+#define SYN_AREA_END_X                 (5472 + SYN_AREA_BOTTOM_RIGHT_OFFSET)
+#define SYN_WIDTH                              (SYN_AREA_END_X - 
SYN_AREA_START_X)
+#define SYN_AREA_START_Y               (1408 - SYN_AREA_TOP_LEFT_OFFSET)
+#define SYN_AREA_END_Y                 (4448 + SYN_AREA_BOTTOM_RIGHT_OFFSET)
+#define SYN_HEIGHT                             (SYN_AREA_END_Y - 
SYN_AREA_START_Y)
+
+
+class MovementMaker {
+public:
+                       void                            
SetSettings(touchpad_settings* settings);
+                       void                            
SetSpecs(hardware_specs* specs);
+
+                       int32                           xDelta;
+                       int32                           yDelta;
+
+                       float                           scrolling_x;
+                       float                           scrolling_y;
+       
+protected:
+                       void                            StartNewMovment();
+                       void                            GetMovement(uint32 
posX, uint32 posY);
+                       void                            GetScrolling(uint32 
posX, uint32 posY);
+
+                       touchpad_settings*      fSettings;
+                       hardware_specs*         fSpecs;
+
+                       int8                            fSpeed;
+                       int16                           fAreaWidth;
+                       int16                           fAreaHeight;
+private:
+                       void                            _GetRawMovement(uint32 
posX, uint32 posY);
+                       void                            
_ComputeAcceleration(int8 accel_factor);
+
+                       
+                       bool                            movementStarted;
+
+                       uint32                          previousX;
+                       uint32                          previousY;
+                       int32                           deltaSumX;
+                       int32                           deltaSumY;
+
+                       int8                            fSmallMovement;
+};
+
+
+enum button_ids
+{
+       kLeftButton = 0x01,
+       kRightButton = 0x02     
+};
+
+
+class TouchpadMovement : public MovementMaker {
+public:
+                       void                            Init();
+
+                       status_t                        
EventToMovement(touch_event *event,
+                                                                       
mouse_movement *movement);
+
+                       bigtime_t                       click_speed;
+private:
+                       bool                            
_EdgeMotion(mouse_movement *movement,
+                                                                       
touch_event *event, bool validStart);
+       inline  void                            _UpdateButtons(mouse_movement 
*movement);
+       inline  void                            _NoTouchToMovement(touch_event 
*event,
+                                                                       
mouse_movement *movement);
+       inline  void                            _MoveToMovement(touch_event 
*event,
+                                                                       
mouse_movement *movement);
+       inline  bool                            
_CheckScrollingToMovement(touch_event *event,
+                                                                       
mouse_movement *movement);
+
+                       bool                            movement_started;
+                       bool                            scrolling_started;
+                       bool                            tap_started;
+                       bigtime_t                       tap_time;
+                       int32                           tap_delta_x;
+                       int32                           tap_delta_y;
+                       int32                           tap_clicks;
+                       bool                            tapdrag_started;
+                       bool                            valid_edge_motion;
+                       bool                            double_click;
+
+                       bigtime_t                       click_last_time;
+                       int32                           click_count;
+                       uint32                          buttons_state;  
+};
+
+
 #endif

Modified: haiku/trunk/src/add-ons/kernel/bus_managers/ps2/ps2_alps.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/bus_managers/ps2/ps2_alps.cpp        
2011-03-29 22:51:41 UTC (rev 41139)
+++ haiku/trunk/src/add-ons/kernel/bus_managers/ps2/ps2_alps.cpp        
2011-03-30 09:37:40 UTC (rev 41140)
@@ -15,8 +15,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <keyboard_mouse_driver.h>
-
 #include "ps2_service.h"
 
 
@@ -28,13 +26,6 @@
 };
 
 
-enum button_ids
-{
-       kLeftButton = 0x01,
-       kRightButton = 0x02     
-};
-
-
 typedef struct alps_model_info {
        uint8           id[3];
        uint8           firstByte;
@@ -55,7 +46,7 @@
                                                                                
// 6-byte ALPS packet
 
 static const struct alps_model_info gALPSModelInfos[] = {
-//     {{0x32, 0x02, 0x14}, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT},
+       {{0x32, 0x02, 0x14}, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT},
                // Toshiba Salellite Pro M10 
 //     {{0x33, 0x02, 0x0a}, 0x88, 0xf8, ALPS_OLDPROTO},
                // UMAX-530T
@@ -65,29 +56,29 @@
                // HP ze1115
        {{0x63, 0x02, 0x0a}, 0xf8, 0xf8, 0},
        {{0x63, 0x02, 0x14}, 0xf8, 0xf8, 0},
-//     {{0x63, 0x02, 0x28}, 0xf8, 0xf8, ALPS_FW_BK_2},
+       {{0x63, 0x02, 0x28}, 0xf8, 0xf8, ALPS_FW_BK_2},
                // Fujitsu Siemens S6010
 //     {{0x63, 0x02, 0x3c}, 0x8f, 0x8f, ALPS_WHEEL},
                // Toshiba Satellite S2400-103
-//     {{0x63, 0x02, 0x50}, 0xef, 0xef, ALPS_FW_BK_1},
+       {{0x63, 0x02, 0x50}, 0xef, 0xef, ALPS_FW_BK_1},
                // NEC Versa L320
        {{0x63, 0x02, 0x64}, 0xf8, 0xf8, 0},
-//     {{0x63, 0x03, 0xc8}, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT},
+       {{0x63, 0x03, 0xc8}, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT},
                // Dell Latitude D800
        {{0x73, 0x00, 0x0a}, 0xf8, 0xf8, ALPS_DUALPOINT},
                // ThinkPad R61 8918-5QG, x301
        {{0x73, 0x02, 0x0a}, 0xf8, 0xf8, 0},
-//     {{0x73, 0x02, 0x14}, 0xf8, 0xf8, ALPS_FW_BK_2},
+       {{0x73, 0x02, 0x14}, 0xf8, 0xf8, ALPS_FW_BK_2},
                // Ahtec Laptop
-//     {{0x20, 0x02, 0x0e}, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT},
+       {{0x20, 0x02, 0x0e}, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT},
                // XXX
-//     {{0x22, 0x02, 0x0a}, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT},
-//     {{0x22, 0x02, 0x14}, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT},
+       {{0x22, 0x02, 0x0a}, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT},
+       {{0x22, 0x02, 0x14}, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT},
                // Dell Latitude D600
 //     {{0x62, 0x02, 0x14}, 0xcf, 0xcf,  ALPS_PASS | ALPS_DUALPOINT
 //             | ALPS_PS2_INTERLEAVED},
                // Dell Latitude E5500, E6400, E6500, Precision M4400
-//     {{0x73, 0x02, 0x50}, 0xcf, 0xcf, ALPS_FOUR_BUTTONS},
+       {{0x73, 0x02, 0x50}, 0xcf, 0xcf, ALPS_FOUR_BUTTONS},
                // Dell Vostro 1400
 //     {{0x52, 0x01, 0x14}, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT
 //             | ALPS_PS2_INTERLEAVED},
@@ -109,309 +100,25 @@
 
 
 // touchpad proportions
-#define SPEED_FACTOR           5
-#define EDGE_MOTION_WIDTH      10 
-#define EDGE_MOTION_SPEED      (5 * SPEED_FACTOR)
+#define EDGE_MOTION_WIDTH      45 
+#define EDGE_MOTION_SPEED      4
 // increase the touchpad size a little bit
-#define AREA_START_X           50
-#define AREA_END_X                     985
-#define AREA_WIDTH_X           (AREA_END_X - AREA_START_X)
-#define AREA_START_Y           45
-#define AREA_END_Y                     735
-#define AREA_WIDTH_Y           (AREA_END_Y - AREA_START_Y)
+#define AREA_START_X           40
+#define AREA_END_X                     987
+#define AREA_START_Y           40
+#define AREA_END_Y                     733
 
-#define TAP_TIMEOUT                    200000
-
 #define MIN_PRESSURE           15
+#define REAL_MAX_PRESSURE      70
 #define MAX_PRESSURE           115
 
+
 #define ALPS_HISTORY_SIZE      256
 
 
-typedef struct {
-       uint8           buttons;
-       uint32          xPosition;
-       uint32          yPosition;
-       uint8           zPressure;
-       // absolut mode
-       bool            finger;
-       // absolut w mode
-       uint8           wValue;
-} touch_event;
+static hardware_specs gHardwareSpecs;
 
 
-static bool
-edge_motion(mouse_movement *movement, touch_event *event, bool validStart)
-{
-       int32 xdelta = 0;
-       int32 ydelta = 0;
-
-       if (event->xPosition < AREA_START_X + EDGE_MOTION_WIDTH)
-               xdelta = -EDGE_MOTION_SPEED;
-       else if (event->xPosition > AREA_END_X - EDGE_MOTION_WIDTH)
-               xdelta = EDGE_MOTION_SPEED;
-
-       if (event->yPosition < AREA_START_Y + EDGE_MOTION_WIDTH)
-               ydelta = -EDGE_MOTION_SPEED;
-       else if (event->yPosition > AREA_END_Y - EDGE_MOTION_WIDTH)
-               ydelta = EDGE_MOTION_SPEED;
-
-       if (xdelta && validStart)
-               movement->xdelta = xdelta;
-       if (ydelta && validStart)
-               movement->ydelta = ydelta;
-
-       if ((xdelta || ydelta) && !validStart)
-               return false;
-
-       return true;
-}
-
-
-/*!    If a button has been clicked (movement->buttons must be set 
accordingly),
-       this function updates the click_count of the \a cookie, as well as the
-       \a movement's clicks field.
-       Also, it sets the cookie's button state from movement->buttons.
-*/
-static inline void
-update_buttons(alps_cookie *cookie, mouse_movement *movement)
-{
-       // set click count correctly according to double click timeout
-       if (movement->buttons != 0 && cookie->buttons_state == 0) {
-               if (cookie->click_last_time + cookie->click_speed > 
movement->timestamp)
-                       cookie->click_count++;
-               else
-                       cookie->click_count = 1;
-
-               cookie->click_last_time = movement->timestamp;
-       }
-
-       if (movement->buttons != 0)
-               movement->clicks = cookie->click_count;
-
-       cookie->buttons_state = movement->buttons;
-}
-
-
-static inline void
-no_touch_to_movement(alps_cookie *cookie, touch_event *event,
-       mouse_movement *movement)
-{
-       uint32 buttons = event->buttons;
-
-       TRACE("ALPS: no touch event\n");
-
-       cookie->scrolling_started = false;
-       cookie->movement_started = false;
-
-       if (cookie->tapdrag_started
-               && (movement->timestamp - cookie->tap_time) < TAP_TIMEOUT) {
-               buttons = 0x01;
-       }
-
-       // if the movement stopped switch off the tap drag when timeout is 
expired
-       if ((movement->timestamp - cookie->tap_time) > TAP_TIMEOUT) {
-               cookie->tapdrag_started = false;
-               cookie->valid_edge_motion = false;
-               TRACE("ALPS: tap drag gesture timed out\n");
-       }
-
-       if (abs(cookie->tap_delta_x) > 15 || abs(cookie->tap_delta_y) > 15) {
-               cookie->tap_started = false;
-               cookie->tap_clicks = 0;
-       }
-
-       if (cookie->tap_started || cookie->double_click) {
-               TRACE("ALPS: tap gesture\n");
-               cookie->tap_clicks++;
-
-               if (cookie->tap_clicks > 1) {
-                       TRACE("ALPS: empty click\n");
-                       buttons = 0x00;
-                       cookie->tap_clicks = 0;
-                       cookie->double_click = true;
-               } else {
-                       buttons = 0x01;
-                       cookie->tap_started = false;
-                       cookie->tapdrag_started = true;
-                       cookie->double_click = false;
-               }
-       }
-
-       movement->buttons = buttons;
-       update_buttons(cookie, movement);
-}
-
-
-static inline void
-move_to_movement(alps_cookie *cookie, touch_event *event,
-       mouse_movement *movement)
-{
-       touchpad_settings *settings = &cookie->settings;
-       bool isStartOfMovement = false;
-       float pressure = 0;
-
-       TRACE("ALPS: movement event\n");
-       if (!cookie->movement_started) {
-               isStartOfMovement = true;
-               cookie->movement_started = true;
-               start_new_movment(&cookie->movementMaker);
-       }
-
-       get_movement(&cookie->movementMaker, event->xPosition, 
event->yPosition);
-
-       movement->xdelta = cookie->movementMaker.xDelta;
-       movement->ydelta = cookie->movementMaker.yDelta;
-
-       // tap gesture
-       cookie->tap_delta_x += cookie->movementMaker.xDelta;
-       cookie->tap_delta_y += cookie->movementMaker.yDelta;
-
-       if (cookie->tapdrag_started) {
-               movement->buttons = kLeftButton;
-               movement->clicks = 0;
-
-               cookie->valid_edge_motion = edge_motion(movement, event,
-                       cookie->valid_edge_motion);
-               TRACE("ALPS: tap drag\n");
-       } else {
-               TRACE("ALPS: movement set buttons\n");
-               movement->buttons = event->buttons;
-       }
-
-       // use only a fraction of pressure range, the max pressure seems to be
-       // to high
-       pressure = 20 * (event->zPressure - MIN_PRESSURE)
-               / (MAX_PRESSURE - MIN_PRESSURE - 40);
-       if (!cookie->tap_started
-               && isStartOfMovement
-               && settings->tapgesture_sensibility > 0.
-               && settings->tapgesture_sensibility > (20 - pressure)) {
-               TRACE("ALPS: tap started\n");
-               cookie->tap_started = true;
-               cookie->tap_time = system_time();
-               cookie->tap_delta_x = 0;
-               cookie->tap_delta_y = 0;
-       }
-
-       update_buttons(cookie, movement);
-}
-
-
-/*!    Checks if this is a scrolling event or not, and also actually does the
-       scrolling work if it is.
-
-       \return \c true if this was a scrolling event, \c false if not.
-*/

[... truncated: 852 lines follow ...]

Other related posts:

  • » [haiku-commits] r41140 - haiku/trunk/src/add-ons/kernel/bus_managers/ps2 - clemens . zeidler