diff --git a/headers/os/add-ons/input_server/InputServerDevice.h b/headers/os/add-ons/input_server/InputServerDevice.h index 3c335887cc..003b17d870 100644 --- a/headers/os/add-ons/input_server/InputServerDevice.h +++ b/headers/os/add-ons/input_server/InputServerDevice.h @@ -32,6 +32,7 @@ enum { B_MOUSE_SPEED_CHANGED, B_CLICK_SPEED_CHANGED, B_MOUSE_ACCELERATION_CHANGED, + B_SET_TOUCHPAD_SETTINGS, }; namespace BPrivate { diff --git a/headers/private/input/keyboard_mouse_driver.h b/headers/private/input/keyboard_mouse_driver.h index a93f37e4b1..248ea3293a 100644 --- a/headers/private/input/keyboard_mouse_driver.h +++ b/headers/private/input/keyboard_mouse_driver.h @@ -62,9 +62,10 @@ enum { MS_GET_CLICKSPEED, MS_SET_CLICKSPEED, MS_NUM_SERIAL_MICE, + MS_IS_TOUCHPAD, - MS_SET_TOUCHPAD_SETTINGS, - + MS_READ_TOUCHPAD, + IIC_WRITE = B_DEVICE_OP_CODES_END + 200, RESTART_SYSTEM, SHUTDOWN_SYSTEM @@ -127,6 +128,22 @@ typedef struct { #define B_PEN 0x08 +typedef struct { + uint16 edgeMotionWidth; + + uint16 width; + uint16 areaStartX; + uint16 areaEndX; + uint16 areaStartY; + uint16 areaEndY; + + uint16 minPressure; + // the value you reach when you hammer really hard on the touchpad + uint16 realMaxPressure; + uint16 maxPressure; +} touchpad_specs; + + typedef struct { uint8 buttons; uint32 xPosition; @@ -137,8 +154,18 @@ typedef struct { uint8 fingerWidth; // 1 - 4 normal width // 5 - 11 very wide finger or palm - // 12 maximum reportable width; extrem wide contact + // 12 maximum reportable width; extreme wide contact } touchpad_movement; +typedef struct { + bigtime_t timeout; + int32 event; + union { + touchpad_movement touchpad; + mouse_movement mouse; + } u; +} touchpad_read; + + #endif // _KB_MOUSE_DRIVER_H diff --git a/headers/private/input/touchpad_driver.h b/headers/private/input/touchpad_driver.h deleted file mode 100644 index ed8bf3a716..0000000000 --- a/headers/private/input/touchpad_driver.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// kb_mouse_driver.h -// -#ifndef _TOUCHPAD_DRIVER_H -#define _TOUCHPAD_DRIVER_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define B_ONE_FINGER 0x01 -#define B_TWO_FINGER 0x02 -#define B_MULTI_FINGER 0x04 -#define B_PEN 0x08 - -typedef struct { - uint8 buttons; - uint32 xPosition; - uint32 yPosition; - uint8 zPressure; - uint8 fingers; - bool gesture; - uint8 fingerWidth; - // 1 - 4 normal width - // 5 - 11 very wide finger or palm - // 12 maximum reportable width; extrem wide contact -} touchpad_movement; - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/add-ons/input_server/devices/mouse/Jamfile b/src/add-ons/input_server/devices/mouse/Jamfile index 62bb96cb47..824ae42329 100644 --- a/src/add-ons/input_server/devices/mouse/Jamfile +++ b/src/add-ons/input_server/devices/mouse/Jamfile @@ -4,4 +4,5 @@ UsePrivateHeaders input shared ; Addon mouse : MouseInputDevice.cpp + movement_maker.cpp : be input_server [ TargetLibsupc++ ] ; diff --git a/src/add-ons/input_server/devices/mouse/MouseInputDevice.cpp b/src/add-ons/input_server/devices/mouse/MouseInputDevice.cpp index 80fd596191..39a1b66c0b 100644 --- a/src/add-ons/input_server/devices/mouse/MouseInputDevice.cpp +++ b/src/add-ons/input_server/devices/mouse/MouseInputDevice.cpp @@ -34,6 +34,8 @@ #include #include +#include "movement_maker.h" + #undef TRACE //#define TRACE_MOUSE_DEVICE @@ -120,8 +122,7 @@ private: void _UpdateSettings(); status_t _GetTouchpadSettingsPath(BPath& path); - status_t _ReadTouchpadSettingsMsg(BMessage* message); - status_t _UpdateTouchpadSettings(); + status_t _UpdateTouchpadSettings(BMessage* message); BMessage* _BuildMouseMessage(uint32 what, uint64 when, uint32 buttons, @@ -147,7 +148,7 @@ private: volatile bool fUpdateSettings; bool fIsTouchpad; - touchpad_settings fTouchpadSettings; + TouchpadMovement fTouchpadMovementMaker; BMessage* fTouchpadSettingsMessage; BLocker fTouchpadSettingsLock; }; @@ -367,22 +368,26 @@ MouseDevice::_ControlThread() } // touchpad settings - if (ioctl(fDevice, MS_IS_TOUCHPAD, NULL) == B_OK) { + touchpad_specs touchpadSpecs; + if (ioctl(fDevice, MS_IS_TOUCHPAD, &touchpadSpecs, sizeof(touchpadSpecs)) == B_OK) { TRACE("is touchpad %s\n", fPath.String()); fIsTouchpad = true; - fTouchpadSettings = kDefaultTouchpadSettings; + touchpad_settings settings; + settings = kDefaultTouchpadSettings; BPath path; status_t status = _GetTouchpadSettingsPath(path); BFile settingsFile(path.Path(), B_READ_ONLY); if (status == B_OK && settingsFile.InitCheck() == B_OK) { - if (settingsFile.Read(&fTouchpadSettings, sizeof(touchpad_settings)) + if (settingsFile.Read(&settings, sizeof(touchpad_settings)) != sizeof(touchpad_settings)) { TRACE("failed to load settings\n"); } } - _UpdateTouchpadSettings(); + + fTouchpadMovementMaker.SetSpecs(touchpadSpecs); + fTouchpadMovementMaker.SetSettings(settings); } _UpdateSettings(); @@ -398,6 +403,10 @@ MouseDevice::_ControlThread() bigtime_t nextTransferTime = system_time() + kTransferDelay; #endif + // touchpads only + touchpad_movement lastTouchpadMovement; + bigtime_t touchpadEventTimeout = B_INFINITE_TIMEOUT; + while (fActive) { mouse_movement movements; @@ -406,11 +415,40 @@ MouseDevice::_ControlThread() nextTransferTime += kTransferDelay; #endif - if (ioctl(fDevice, MS_READ, &movements, sizeof(movements)) != B_OK) { - LOG_ERR("Mouse device exiting, %s\n", strerror(errno)); - _ControlThreadCleanup(); - // TOAST! - return; + if (!fIsTouchpad) { + if (ioctl(fDevice, MS_READ, &movements, sizeof(movements)) != B_OK) { + LOG_ERR("Mouse device exiting, %s\n", strerror(errno)); + _ControlThreadCleanup(); + // TOAST! + return; + } + } else { + touchpad_read read; + read.timeout = touchpadEventTimeout; + + status_t status = ioctl(fDevice, MS_READ_TOUCHPAD, &read, sizeof(read)); + if (status != B_OK && status != B_TIMED_OUT) { + LOG_ERR("Mouse device exiting, %s\n", strerror(errno)); + _ControlThreadCleanup(); + // TOAST! + return; + } + if (status == B_TIMED_OUT) { + read.event = MS_READ_TOUCHPAD; + read.u.touchpad = lastTouchpadMovement; + } + + if (read.event == MS_READ_TOUCHPAD) { + lastTouchpadMovement = read.u.touchpad; + status = fTouchpadMovementMaker.EventToMovement(&read.u.touchpad, + &movements, touchpadEventTimeout); + } else if (read.event == MS_READ) { + movements = read.u.mouse; + touchpadEventTimeout = -1; + } + + if (status != B_OK) + continue; } // take care of updating the settings first, if necessary @@ -419,8 +457,7 @@ MouseDevice::_ControlThread() if (fIsTouchpad) { BAutolock _(fTouchpadSettingsLock); if (fTouchpadSettingsMessage != NULL) { - _ReadTouchpadSettingsMsg(fTouchpadSettingsMessage); - _UpdateTouchpadSettings(); + _UpdateTouchpadSettings(fTouchpadSettingsMessage); delete fTouchpadSettingsMessage; fTouchpadSettingsMessage = NULL; } else @@ -524,10 +561,12 @@ MouseDevice::_UpdateSettings() = ioctl(fDevice, MS_SET_MAP, &fSettings.map) == B_OK; } - if (get_click_speed(&fSettings.click_speed) != B_OK) - LOG_ERR("error when get_click_speed\n"); - else + if (get_click_speed(&fSettings.click_speed) == B_OK) { + if (fIsTouchpad) + fTouchpadMovementMaker.click_speed = fSettings.click_speed; ioctl(fDevice, MS_SET_CLICKSPEED, &fSettings.click_speed); + } else + LOG_ERR("error when get_click_speed\n"); if (get_mouse_speed(fDeviceRef.name, &fSettings.accel.speed) != B_OK) LOG_ERR("error when get_mouse_speed\n"); @@ -561,40 +600,33 @@ MouseDevice::_GetTouchpadSettingsPath(BPath& path) status_t -MouseDevice::_ReadTouchpadSettingsMsg(BMessage* message) +MouseDevice::_UpdateTouchpadSettings(BMessage* message) { - message->FindBool("scroll_twofinger", &fTouchpadSettings.scroll_twofinger); + touchpad_settings settings; + message->FindBool("scroll_twofinger", &settings.scroll_twofinger); message->FindBool("scroll_twofinger_horizontal", - &fTouchpadSettings.scroll_twofinger_horizontal); + &settings.scroll_twofinger_horizontal); message->FindFloat("scroll_rightrange", - &fTouchpadSettings.scroll_rightrange); + &settings.scroll_rightrange); message->FindFloat("scroll_bottomrange", - &fTouchpadSettings.scroll_bottomrange); + &settings.scroll_bottomrange); message->FindInt16("scroll_xstepsize", - (int16*)&fTouchpadSettings.scroll_xstepsize); + (int16*)&settings.scroll_xstepsize); message->FindInt16("scroll_ystepsize", - (int16*)&fTouchpadSettings.scroll_ystepsize); + (int16*)&settings.scroll_ystepsize); message->FindInt8("scroll_acceleration", - (int8*)&fTouchpadSettings.scroll_acceleration); + (int8*)&settings.scroll_acceleration); message->FindInt8("tapgesture_sensibility", - (int8*)&fTouchpadSettings.tapgesture_sensibility); + (int8*)&settings.tapgesture_sensibility); + + if (fIsTouchpad) + fTouchpadMovementMaker.SetSettings(settings); return B_OK; } -status_t -MouseDevice::_UpdateTouchpadSettings() -{ - if (fIsTouchpad) { - ioctl(fDevice, MS_SET_TOUCHPAD_SETTINGS, &fTouchpadSettings); - return B_OK; - } - return B_ERROR; -} - - BMessage* MouseDevice::_BuildMouseMessage(uint32 what, uint64 when, uint32 buttons, int32 deltaX, int32 deltaY) const @@ -748,7 +780,7 @@ MouseInputDevice::Control(const char* name, void* cookie, if (command == B_NODE_MONITOR) return _HandleMonitor(message); - if (command == MS_SET_TOUCHPAD_SETTINGS) + if (command == B_SET_TOUCHPAD_SETTINGS) return device->UpdateTouchpadSettings(message); if (command >= B_MOUSE_TYPE_CHANGED diff --git a/src/add-ons/kernel/bus_managers/ps2/movement_maker.cpp b/src/add-ons/input_server/devices/mouse/movement_maker.cpp similarity index 59% rename from src/add-ons/kernel/bus_managers/ps2/movement_maker.cpp rename to src/add-ons/input_server/devices/mouse/movement_maker.cpp index 366a7beeed..12d03cdec6 100644 --- a/src/add-ons/kernel/bus_managers/ps2/movement_maker.cpp +++ b/src/add-ons/input_server/devices/mouse/movement_maker.cpp @@ -1,6 +1,12 @@ +/* + * Copyright 2008-2011, Clemens Zeidler + * Copyright 2022, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ #include "movement_maker.h" #include +#include #include @@ -13,160 +19,9 @@ #endif -typedef union { - float value; - /* FIXME: Assumes 32 bit int. */ - unsigned int word; -} ieee_float_shape_type; - -/* Get a 32 bit int from a float. */ - -#define GET_FLOAT_WORD(i,d) \ -do { \ - ieee_float_shape_type gf_u; \ - gf_u.value = (d); \ - (i) = gf_u.word; \ -} while (0) - -/* Set a float from a 32 bit int. */ - -#define SET_FLOAT_WORD(d,i) \ -do { \ - ieee_float_shape_type sf_u; \ - sf_u.word = (i); \ - (d) = sf_u.value; \ -} while (0) - -static const float huge = 1.0e30; - -float -floorf(float x) -{ - int32 i0,j0; - uint32 i; - GET_FLOAT_WORD(i0,x); - j0 = ((i0>>23)&0xff)-0x7f; - if (j0<23) { - if (j0<0) { /* raise inexact if x != 0 */ - if (huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */ - if (i0>=0) {i0=0;} - else if ((i0&0x7fffffff)!=0) - { i0=0xbf800000;} - } - } else { - i = (0x007fffff)>>j0; - if ((i0&i)==0) return x; /* x is integral */ - if (huge+x>(float)0.0) { /* raise inexact flag */ - if (i0<0) i0 += (0x00800000)>>j0; - i0 &= (~i); - } - } - } else { - if (j0==0x80) return x+x; /* inf or NaN */ - else return x; /* x is integral */ - } - SET_FLOAT_WORD(x,i0); - return x; -} - - -float -ceilf(float x) -{ - int32 i0,j0; - uint32 i; - - GET_FLOAT_WORD(i0,x); - j0 = ((i0>>23)&0xff)-0x7f; - if (j0<23) { - if (j0<0) { /* raise inexact if x != 0 */ - if (huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */ - if (i0<0) {i0=0x80000000;} - else if (i0!=0) { i0=0x3f800000;} - } - } else { - i = (0x007fffff)>>j0; - if ((i0&i)==0) return x; /* x is integral */ - if (huge+x>(float)0.0) { /* raise inexact flag */ - if (i0>0) i0 += (0x00800000)>>j0; - i0 &= (~i); - } - } - } else { - if (j0==0x80) return x+x; /* inf or NaN */ - else return x; /* x is integral */ - } - SET_FLOAT_WORD(x,i0); - return x; -} - -static const float one = 1.0, tiny=1.0e-30; - -float -sqrtf(float x) -{ - float z; - int32 sign = (int)0x80000000; - int32 ix,s,q,m,t,i; - uint32 r; - - GET_FLOAT_WORD(ix,x); - - /* take care of Inf and NaN */ - if ((ix&0x7f800000)==0x7f800000) { - return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf - sqrt(-inf)=sNaN */ - } - /* take care of zero */ - if (ix<=0) { - if ((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */ - else if (ix<0) - return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ - } - /* normalize x */ - m = (ix>>23); - if (m==0) { /* subnormal x */ - for(i=0;(ix&0x00800000)==0;i++) ix<<=1; - m -= i-1; - } - m -= 127; /* unbias exponent */ - ix = (ix&0x007fffff)|0x00800000; - if (m&1) /* odd m, double x to make it even */ - ix += ix; - m >>= 1; /* m = [m/2] */ - - /* generate sqrt(x) bit by bit */ - ix += ix; - q = s = 0; /* q = sqrt(x) */ - r = 0x01000000; /* r = moving bit from right to left */ - - while(r!=0) { - t = s+r; - if (t<=ix) { - s = t+r; - ix -= t; - q += r; - } - ix += ix; - r>>=1; - } - - /* use floating add to find out rounding direction */ - if (ix!=0) { - z = one-tiny; /* trigger inexact flag */ - if (z>=one) { - z = one+tiny; - if (z>one) - q += 2; - else - q += (q&1); - } - } - ix = (q>>1)+0x3f000000; - ix += (m <<23); - SET_FLOAT_WORD(z,ix); - return z; -} +// magic constants +#define SYN_WIDTH (4100) +#define SYN_HEIGHT (3140) static int32 @@ -179,21 +34,20 @@ make_small(float value) } - void -MovementMaker::SetSettings(touchpad_settings* settings) +MovementMaker::SetSettings(const touchpad_settings& settings) { fSettings = settings; } void -MovementMaker::SetSpecs(hardware_specs* specs) +MovementMaker::SetSpecs(const touchpad_specs& specs) { fSpecs = specs; - fAreaWidth = fSpecs->areaEndX - fSpecs->areaStartX; - fAreaHeight = fSpecs->areaEndY - fSpecs->areaStartY; + fAreaWidth = fSpecs.areaEndX - fSpecs.areaStartX; + fAreaHeight = fSpecs.areaEndY - fSpecs.areaStartY; // calibrated on the synaptics touchpad fSpeed = SYN_WIDTH / fAreaWidth; @@ -204,10 +58,10 @@ MovementMaker::SetSpecs(hardware_specs* specs) void MovementMaker::StartNewMovment() { - if (fSettings->scroll_xstepsize <= 0) - fSettings->scroll_xstepsize = 1; - if (fSettings->scroll_ystepsize <= 0) - fSettings->scroll_ystepsize = 1; + if (fSettings.scroll_xstepsize <= 0) + fSettings.scroll_xstepsize = 1; + if (fSettings.scroll_ystepsize <= 0) + fSettings.scroll_ystepsize = 1; fMovementMakerStarted = true; scrolling_x = 0; @@ -228,25 +82,25 @@ MovementMaker::GetScrolling(uint32 posX, uint32 posY) int32 stepsX = 0, stepsY = 0; _GetRawMovement(posX, posY); - _ComputeAcceleration(fSettings->scroll_acceleration); + _ComputeAcceleration(fSettings.scroll_acceleration); - if (fSettings->scroll_xstepsize > 0) { + if (fSettings.scroll_xstepsize > 0) { scrolling_x += xDelta; - stepsX = make_small(scrolling_x / fSettings->scroll_xstepsize); + stepsX = make_small(scrolling_x / fSettings.scroll_xstepsize); - scrolling_x -= stepsX * fSettings->scroll_xstepsize; + scrolling_x -= stepsX * fSettings.scroll_xstepsize; xDelta = stepsX; } else { scrolling_x = 0; xDelta = 0; } - if (fSettings->scroll_ystepsize > 0) { + if (fSettings.scroll_ystepsize > 0) { scrolling_y += yDelta; - stepsY = make_small(scrolling_y / fSettings->scroll_ystepsize); + stepsY = make_small(scrolling_y / fSettings.scroll_ystepsize); - scrolling_y -= stepsY * fSettings->scroll_ystepsize; + scrolling_y -= stepsY * fSettings.scroll_ystepsize; yDelta = -1 * stepsY; } else { scrolling_y = 0; @@ -326,7 +180,6 @@ MovementMaker::_GetRawMovement(uint32 posX, uint32 posY) } - void MovementMaker::_ComputeAcceleration(int8 accel_factor) { @@ -348,8 +201,7 @@ MovementMaker::_ComputeAcceleration(int8 accel_factor) #define fTapTimeOUT 200000 -void -TouchpadMovement::Init() +TouchpadMovement::TouchpadMovement() { fMovementStarted = false; fScrollingStarted = false; @@ -360,7 +212,8 @@ TouchpadMovement::Init() status_t -TouchpadMovement::EventToMovement(touch_event *event, mouse_movement *movement) +TouchpadMovement::EventToMovement(const touchpad_movement* event, mouse_movement* movement, + bigtime_t& repeatTimeout) { if (!movement) return B_ERROR; @@ -391,10 +244,10 @@ TouchpadMovement::EventToMovement(touch_event *event, mouse_movement *movement) fValidEdgeMotion = false; } - if (event->zPressure >= fSpecs->minPressure - && event->zPressure < fSpecs->maxPressure - && ((event->wValue >= 4 && event->wValue <= 7) - || event->wValue == 0 || event->wValue == 1) + if (event->zPressure >= fSpecs.minPressure + && event->zPressure < fSpecs.maxPressure + && ((event->fingerWidth >= 4 && event->fingerWidth <= 7) + || event->fingerWidth == 0 || event->fingerWidth == 1) && (event->xPosition != 0 || event->yPosition != 0)) { // The touch pad is in touch with at least one finger if (!_CheckScrollingToMovement(event, movement)) @@ -402,6 +255,14 @@ TouchpadMovement::EventToMovement(touch_event *event, mouse_movement *movement) } else _NoTouchToMovement(event, movement); + + if (fTapdragStarted || fValidEdgeMotion) { + // We want the current event to be repeated in 50ms if no other + // events occur in the interim. + repeatTimeout = 1000 * 50; + } else + repeatTimeout = B_INFINITE_TIMEOUT; + return B_OK; } @@ -411,7 +272,7 @@ const int32 kEdgeMotionSpeed = 200; bool -TouchpadMovement::_EdgeMotion(mouse_movement *movement, touch_event *event, +TouchpadMovement::_EdgeMotion(const touchpad_movement *event, mouse_movement *movement, bool validStart) { float xdelta = 0; @@ -430,19 +291,19 @@ TouchpadMovement::_EdgeMotion(mouse_movement *movement, touch_event *event, bool inXEdge = false; bool inYEdge = false; - if (int32(event->xPosition) < fSpecs->areaStartX + fSpecs->edgeMotionWidth) { + if (int32(event->xPosition) < fSpecs.areaStartX + fSpecs.edgeMotionWidth) { inXEdge = true; xdelta *= -1; } else if (event->xPosition > uint16( - fSpecs->areaEndX - fSpecs->edgeMotionWidth)) { + fSpecs.areaEndX - fSpecs.edgeMotionWidth)) { inXEdge = true; } - if (int32(event->yPosition) < fSpecs->areaStartY + fSpecs->edgeMotionWidth) { + if (int32(event->yPosition) < fSpecs.areaStartY + fSpecs.edgeMotionWidth) { inYEdge = true; ydelta *= -1; } else if (event->yPosition > uint16( - fSpecs->areaEndY - fSpecs->edgeMotionWidth)) { + fSpecs.areaEndY - fSpecs.edgeMotionWidth)) { inYEdge = true; } @@ -471,7 +332,7 @@ TouchpadMovement::_EdgeMotion(mouse_movement *movement, touch_event *event, Also, it sets the button state from movement->buttons. */ void -TouchpadMovement::UpdateButtons(mouse_movement *movement) +TouchpadMovement::_UpdateButtons(mouse_movement *movement) { // set click count correctly according to double click timeout if (movement->buttons != 0 && fButtonsState == 0) { @@ -491,7 +352,7 @@ TouchpadMovement::UpdateButtons(mouse_movement *movement) void -TouchpadMovement::_NoTouchToMovement(touch_event *event, +TouchpadMovement::_NoTouchToMovement(const touchpad_movement *event, mouse_movement *movement) { uint32 buttons = event->buttons; @@ -539,12 +400,12 @@ TouchpadMovement::_NoTouchToMovement(touch_event *event, } movement->buttons = buttons; - UpdateButtons(movement); + _UpdateButtons(movement); } void -TouchpadMovement::_MoveToMovement(touch_event *event, mouse_movement *movement) +TouchpadMovement::_MoveToMovement(const touchpad_movement *event, mouse_movement *movement) { bool isStartOfMovement = false; float pressure = 0; @@ -569,7 +430,7 @@ TouchpadMovement::_MoveToMovement(touch_event *event, mouse_movement *movement) movement->buttons = kLeftButton; movement->clicks = 0; - fValidEdgeMotion = _EdgeMotion(movement, event, fValidEdgeMotion); + fValidEdgeMotion = _EdgeMotion(event, movement, fValidEdgeMotion); TRACE("TouchpadMovement: tap drag\n"); } else { TRACE("TouchpadMovement: movement set buttons\n"); @@ -578,12 +439,12 @@ TouchpadMovement::_MoveToMovement(touch_event *event, mouse_movement *movement) // 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); + pressure = 20 * (event->zPressure - fSpecs.minPressure) + / (fSpecs.realMaxPressure - fSpecs.minPressure); if (!fTapStarted && isStartOfMovement - && fSettings->tapgesture_sensibility > 0. - && fSettings->tapgesture_sensibility > (20 - pressure)) { + && fSettings.tapgesture_sensibility > 0. + && fSettings.tapgesture_sensibility > (20 - pressure)) { TRACE("TouchpadMovement: tap started\n"); fTapStarted = true; fTapTime = system_time(); @@ -591,7 +452,7 @@ TouchpadMovement::_MoveToMovement(touch_event *event, mouse_movement *movement) fTapDeltaY = 0; } - UpdateButtons(movement); + _UpdateButtons(movement); } @@ -601,7 +462,7 @@ TouchpadMovement::_MoveToMovement(touch_event *event, mouse_movement *movement) \return \c true if this was a scrolling event, \c false if not. */ bool -TouchpadMovement::_CheckScrollingToMovement(touch_event *event, +TouchpadMovement::_CheckScrollingToMovement(const touchpad_movement *event, mouse_movement *movement) { bool isSideScrollingV = false; @@ -612,23 +473,23 @@ TouchpadMovement::_CheckScrollingToMovement(touch_event *event, if (fButtonsState != 0) return false; - if ((fSpecs->areaEndX - fAreaWidth * fSettings->scroll_rightrange + if ((fSpecs.areaEndX - fAreaWidth * fSettings.scroll_rightrange < event->xPosition && !fMovementStarted - && fSettings->scroll_rightrange > 0.000001) - || fSettings->scroll_rightrange > 0.999999) { + && fSettings.scroll_rightrange > 0.000001) + || fSettings.scroll_rightrange > 0.999999) { isSideScrollingV = true; } - if ((fSpecs->areaStartY + fAreaHeight * fSettings->scroll_bottomrange + if ((fSpecs.areaStartY + fAreaHeight * fSettings.scroll_bottomrange > event->yPosition && !fMovementStarted - && fSettings->scroll_bottomrange > 0.000001) - || fSettings->scroll_bottomrange > 0.999999) { + && fSettings.scroll_bottomrange > 0.000001) + || fSettings.scroll_bottomrange > 0.999999) { isSideScrollingH = true; } - if ((event->wValue == 0 || event->wValue == 1) - && fSettings->scroll_twofinger) { + if ((event->fingerWidth == 0 || event->fingerWidth == 1) + && fSettings.scroll_twofinger) { // two finger scrolling is enabled isSideScrollingV = true; - isSideScrollingH = fSettings->scroll_twofinger_horizontal; + isSideScrollingH = fSettings.scroll_twofinger_horizontal; } if (!isSideScrollingV && !isSideScrollingH) { diff --git a/src/add-ons/input_server/devices/mouse/movement_maker.h b/src/add-ons/input_server/devices/mouse/movement_maker.h new file mode 100644 index 0000000000..2cd075c011 --- /dev/null +++ b/src/add-ons/input_server/devices/mouse/movement_maker.h @@ -0,0 +1,104 @@ +/* + * Copyright 2008-2011, Clemens Zeidler + * Copyright 2022, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef MOVEMENT_MAKER_H +#define MOVEMENT_MAKER_H + +#include + +#include +#include + + +class MovementMaker { +public: + void SetSpecs(const touchpad_specs& specs); + void SetSettings(const touchpad_settings& settings); + + float xDelta; + float yDelta; + + float scrolling_x; + float scrolling_y; + +protected: + void StartNewMovment(); + void GetMovement(uint32 posX, uint32 posY); + void GetScrolling(uint32 posX, uint32 posY); + + touchpad_specs fSpecs; + touchpad_settings fSettings; + + int8 fSpeed; + int16 fAreaWidth; + int16 fAreaHeight; + +private: + void _GetRawMovement(uint32 posX, uint32 posY); + void _ComputeAcceleration(int8 accel_factor); + + + bool fMovementMakerStarted; + + uint32 fPreviousX; + uint32 fPreviousY; + float fDeltaSumX; + float fDeltaSumY; + + int8 fSmallMovement; +}; + + +enum button_ids +{ + kNoButton = 0x00, + kLeftButton = 0x01, + kRightButton = 0x02, + kMiddleButton = 0x04 +}; + + +class TouchpadMovement : public MovementMaker { +public: + TouchpadMovement(); + + status_t EventToMovement(const touchpad_movement *event, + mouse_movement *movement, bigtime_t &repeatTimeout); + + bigtime_t click_speed; +private: + void _UpdateButtons(mouse_movement *movement); + bool _EdgeMotion(const touchpad_movement *event, + mouse_movement *movement, bool validStart); + inline void _NoTouchToMovement(const touchpad_movement *event, + mouse_movement *movement); + inline void _MoveToMovement(const touchpad_movement *event, + mouse_movement *movement); + inline bool _CheckScrollingToMovement(const touchpad_movement *event, + mouse_movement *movement); + + + bool fMovementStarted; + bool fScrollingStarted; + bool fTapStarted; + bigtime_t fTapTime; + int32 fTapDeltaX; + int32 fTapDeltaY; + int32 fTapClicks; + bool fTapdragStarted; + + bool fValidEdgeMotion; + bigtime_t fLastEdgeMotion; + float fRestEdgeMotion; + + bool fDoubleClick; + + bigtime_t fClickLastTime; + int32 fClickCount; + uint32 fButtonsState; +}; + + +#endif diff --git a/src/add-ons/kernel/bus_managers/ps2/Jamfile b/src/add-ons/kernel/bus_managers/ps2/Jamfile index c5d6817669..4cf7e8815b 100644 --- a/src/add-ons/kernel/bus_managers/ps2/Jamfile +++ b/src/add-ons/kernel/bus_managers/ps2/Jamfile @@ -15,5 +15,4 @@ KernelAddon ps2 : ps2_synaptics.cpp ps2_trackpoint.cpp ps2_service.cpp - movement_maker.cpp ; diff --git a/src/add-ons/kernel/bus_managers/ps2/movement_maker.h b/src/add-ons/kernel/bus_managers/ps2/movement_maker.h deleted file mode 100644 index 5375f78dd9..0000000000 --- a/src/add-ons/kernel/bus_managers/ps2/movement_maker.h +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef MOVEMENT_MAKER_H -#define MOVEMENT_MAKER_H - -#include - -#include -#include - - -float floorf(float x); -float ceilf(float x); -float sqrtf(float x); - - -struct touch_event { - uint8 buttons; - uint32 xPosition; - uint32 yPosition; - uint8 zPressure; - // absolut mode (unused) - bool finger; - bool gesture; - // absolut w mode - uint8 wValue; -}; - - -struct hardware_specs { - uint16 edgeMotionWidth; - - uint16 areaStartX; - uint16 areaEndX; - uint16 areaStartY; - uint16 areaEndY; - - 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); - - float xDelta; - float 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 fMovementMakerStarted; - - uint32 fPreviousX; - uint32 fPreviousY; - float fDeltaSumX; - float fDeltaSumY; - - int8 fSmallMovement; -}; - - -enum button_ids -{ - kNoButton = 0x00, - kLeftButton = 0x01, - kRightButton = 0x02, - kMiddleButton = 0x04 -}; - - -class TouchpadMovement : public MovementMaker { -public: - void Init(); - - status_t EventToMovement(touch_event *event, - mouse_movement *movement); - - bool TapDragStarted() { return fTapdragStarted; } - bool WasEdgeMotion() { return fValidEdgeMotion; } - - void UpdateButtons(mouse_movement *movement); - - bigtime_t click_speed; -private: - bool _EdgeMotion(mouse_movement *movement, - touch_event *event, bool validStart); - 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 fMovementStarted; - bool fScrollingStarted; - bool fTapStarted; - bigtime_t fTapTime; - int32 fTapDeltaX; - int32 fTapDeltaY; - int32 fTapClicks; - bool fTapdragStarted; - - bool fValidEdgeMotion; - bigtime_t fLastEdgeMotion; - float fRestEdgeMotion; - - bool fDoubleClick; - - bigtime_t fClickLastTime; - int32 fClickCount; - uint32 fButtonsState; -}; - - -#endif diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_alps.cpp b/src/add-ons/kernel/bus_managers/ps2/ps2_alps.cpp index 81431474c0..685b45a575 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_alps.cpp +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_alps.cpp @@ -15,6 +15,8 @@ #include #include +#include + #include "ps2_service.h" @@ -26,71 +28,6 @@ #endif -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 B_HANDLED_INTERRUPT; -} - - const char* kALPSPath[4] = { "input/touchpad/ps2/alps_0", "input/touchpad/ps2/alps_1", @@ -179,7 +116,7 @@ static alps_model_info* sFoundModel = NULL; #define ALPS_HISTORY_SIZE 256 -static hardware_specs gHardwareSpecs; +static touchpad_specs gHardwareSpecs; /* Data taken from linux driver: @@ -192,13 +129,14 @@ byte 4: 0 y6 y5 y4 y3 y2 y1 y0 byte 5: 0 z6 z5 z4 z3 z2 z1 z0 */ static status_t -get_alps_movment(alps_cookie *cookie, mouse_movement *movement) +get_alps_movment(alps_cookie *cookie, touchpad_read *_read) { status_t status; - touch_event event; + touchpad_movement event; uint8 event_buffer[PS2_PACKET_ALPS]; - status = acquire_sem_etc(cookie->sem, 1, B_CAN_INTERRUPT, 0); + status = acquire_sem_etc(cookie->sem, 1, B_CAN_INTERRUPT | B_RELATIVE_TIMEOUT, + _read->timeout); if (status < B_OK) return status; @@ -219,18 +157,18 @@ get_alps_movment(alps_cookie *cookie, mouse_movement *movement) // finger on touchpad if (event_buffer[2] & 0x2) { // finger with normal width - event.wValue = 4; + event.fingerWidth = 4; } else { - event.wValue = 3; + event.fingerWidth = 3; } // tab gesture if (event_buffer[2] & 0x1) { event.zPressure = 60; - event.wValue = 4; + event.fingerWidth = 4; } // 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.fingerWidth == 4 && event.zPressure == 16) event.zPressure = 60; cookie->previousZ = event.zPressure; @@ -240,36 +178,29 @@ get_alps_movment(alps_cookie *cookie, mouse_movement *movement) // check for trackpoint even (z pressure 127) if (sFoundModel->flags & ALPS_DUALPOINT && event.zPressure == 127) { - movement->xdelta = event.xPosition > 383 ? event.xPosition - 768 + mouse_movement movement; + movement.xdelta = event.xPosition > 383 ? event.xPosition - 768 : event.xPosition; - movement->ydelta = event.yPosition > 255 + movement.ydelta = event.yPosition > 255 ? event.yPosition - 512 : event.yPosition; - movement->wheel_xdelta = 0; - movement->wheel_ydelta = 0; - movement->buttons = event.buttons; - movement->timestamp = system_time(); - cookie->movementMaker.UpdateButtons(movement); + movement.wheel_xdelta = 0; + movement.wheel_ydelta = 0; + movement.buttons = event.buttons; + movement.timestamp = system_time(); + + _read->event = MS_READ; + _read->u.mouse = movement; } else { event.yPosition = AREA_END_Y - (event.yPosition - AREA_START_Y); - status = cookie->movementMaker.EventToMovement(&event, movement); - } - if (cookie->movementMaker.WasEdgeMotion() - || cookie->movementMaker.TapDragStarted()) { - gEventProducer.FireEvent(cookie, event_buffer); + _read->event = MS_READ_TOUCHPAD; + _read->u.touchpad = event; } return status; } -static void -default_settings(touchpad_settings *set) -{ - memcpy(set, &kDefaultTouchpadSettings, sizeof(touchpad_settings)); -} - - status_t probe_alps(ps2_dev* dev) { @@ -393,7 +324,6 @@ alps_open(const char *name, uint32 flags, void **_cookie) goto err1; memset(cookie, 0, sizeof(*cookie)); - cookie->movementMaker.Init(); cookie->previousZ = 0; *_cookie = cookie; @@ -402,8 +332,6 @@ alps_open(const char *name, uint32 flags, void **_cookie) dev->disconnect = &alps_disconnect; dev->handle_int = &alps_handle_int; - default_settings(&cookie->settings); - gHardwareSpecs.edgeMotionWidth = EDGE_MOTION_WIDTH; gHardwareSpecs.areaStartX = AREA_START_X; @@ -415,9 +343,6 @@ alps_open(const char *name, uint32 flags, void **_cookie) gHardwareSpecs.realMaxPressure = REAL_MAX_PRESSURE; gHardwareSpecs.maxPressure = MAX_PRESSURE; - cookie->movementMaker.SetSettings(&cookie->settings); - cookie->movementMaker.SetSpecs(&gHardwareSpecs); - dev->packet_size = PS2_PACKET_ALPS; cookie->ring_buffer = create_packet_buffer( @@ -482,8 +407,6 @@ err1: status_t alps_close(void *_cookie) { - gEventProducer.CancelEvent(); - alps_cookie *cookie = (alps_cookie*)_cookie; ps2_dev_command_timeout(cookie->dev, PS2_CMD_DISABLE, NULL, 0, NULL, 0, @@ -521,29 +444,24 @@ status_t alps_ioctl(void *_cookie, uint32 op, void *buffer, size_t length) { alps_cookie *cookie = (alps_cookie*)_cookie; - mouse_movement movement; + touchpad_read read; status_t status; switch (op) { - case MS_READ: - TRACE("ALPS: MS_READ get event\n"); - if ((status = get_alps_movment(cookie, &movement)) != B_OK) - return status; - return user_memcpy(buffer, &movement, sizeof(movement)); - case MS_IS_TOUCHPAD: TRACE("ALPS: MS_IS_TOUCHPAD\n"); - return B_OK; + if (buffer == NULL) + return B_OK; + return user_memcpy(buffer, &gHardwareSpecs, sizeof(gHardwareSpecs)); - case MS_SET_TOUCHPAD_SETTINGS: - TRACE("ALPS: MS_SET_TOUCHPAD_SETTINGS"); - user_memcpy(&cookie->settings, buffer, sizeof(touchpad_settings)); - return B_OK; - - case MS_SET_CLICKSPEED: - TRACE("ALPS: ioctl MS_SETCLICK (set click speed)\n"); - return user_memcpy(&cookie->movementMaker.click_speed, buffer, - sizeof(bigtime_t)); + case MS_READ_TOUCHPAD: + TRACE("ALPS: MS_READ get event\n"); + if (user_memcpy(&read.timeout, &(((touchpad_read*)buffer)->timeout), + sizeof(bigtime_t)) != B_OK) + return B_BAD_ADDRESS; + if ((status = get_alps_movment(cookie, &read)) != B_OK) + return status; + return user_memcpy(buffer, &read, sizeof(read)); default: TRACE("ALPS: unknown opcode: %" B_PRIu32 "\n", op); @@ -573,9 +491,6 @@ alps_handle_int(ps2_dev* dev) { alps_cookie* cookie = (alps_cookie*)dev->cookie; - // we got a real event cancel the fake event - gEventProducer.CancelEvent(); - uint8 val; val = cookie->dev->history[0].data; if (cookie->packet_index == 0 diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_alps.h b/src/add-ons/kernel/bus_managers/ps2/ps2_alps.h index 4e25dc6485..3ca886f137 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_alps.h +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_alps.h @@ -10,9 +10,6 @@ #include -#include - -#include "movement_maker.h" #include "packet_buffer.h" #include "ps2_dev.h" @@ -27,9 +24,6 @@ typedef struct { uint8 mode; uint8 previousZ; - TouchpadMovement movementMaker; - - touchpad_settings settings; } alps_cookie; diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_elantech.cpp b/src/add-ons/kernel/bus_managers/ps2/ps2_elantech.cpp index 1b6b62b5e4..91c0ac9dc3 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_elantech.cpp +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_elantech.cpp @@ -15,6 +15,8 @@ #include #include +#include + #include "ps2_service.h" @@ -26,71 +28,6 @@ #endif -static int32 generate_event(timer* timer); - - -const bigtime_t kEventInterval = 1000 * 50; - - -class EventProducer { -public: - EventProducer() - { - fFired = false; - } - - status_t - FireEvent(elantech_cookie* cookie, uint8* package) - { - fCookie = cookie; - memcpy(fLastPackage, package, sizeof(uint8) * PS2_PACKET_ELANTECH); - - 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_ELANTECH) != PS2_PACKET_ELANTECH) { - // buffer is full, drop new data - return; - } - release_sem_etc(fCookie->sem, 1, B_DO_NOT_RESCHEDULE); - } - -private: - bool fFired; - uint8 fLastPackage[PS2_PACKET_ELANTECH]; - timer fEventTimer; - elantech_cookie* fCookie; -}; - - -static EventProducer gEventProducer; - - -static int32 -generate_event(timer* timer) -{ - gEventProducer.InjectEvent(); - return B_HANDLED_INTERRUPT; -} - - const char* kElantechPath[4] = { "input/touchpad/ps2/elantech_0", "input/touchpad/ps2/elantech_1", @@ -124,16 +61,17 @@ const char* kElantechPath[4] = { #define HEAD_PACKET 0x1 #define MOTION_PACKET 0x2 -static hardware_specs gHardwareSpecs; +static touchpad_specs gHardwareSpecs; static status_t -get_elantech_movement(elantech_cookie *cookie, mouse_movement *movement) +get_elantech_movement(elantech_cookie *cookie, touchpad_movement *_event, bigtime_t timeout) { - touch_event event; + touchpad_movement event; uint8 packet[PS2_PACKET_ELANTECH]; - status_t status = acquire_sem_etc(cookie->sem, 1, B_CAN_INTERRUPT, 0); + status_t status = acquire_sem_etc(cookie->sem, 1, B_CAN_INTERRUPT | B_RELATIVE_TIMEOUT, + timeout); if (status < B_OK) return status; @@ -208,25 +146,13 @@ get_elantech_movement(elantech_cookie *cookie, mouse_movement *movement) } event.buttons = 0; - event.wValue = cookie->fingers == 1 ? 4 :0; - status = cookie->movementMaker.EventToMovement(&event, movement); - - if (cookie->movementMaker.WasEdgeMotion() - || cookie->movementMaker.TapDragStarted()) { - gEventProducer.FireEvent(cookie, packet); - } + event.fingerWidth = cookie->fingers == 1 ? 4 :0; + *_event = event; return status; } -static void -default_settings(touchpad_settings *set) -{ - memcpy(set, &kDefaultTouchpadSettings, sizeof(touchpad_settings)); -} - - static status_t synaptics_dev_send_command(ps2_dev* dev, uint8 cmd, uint8 *in, int in_count) { @@ -534,7 +460,6 @@ elantech_open(const char *name, uint32 flags, void **_cookie) goto err1; memset(cookie, 0, sizeof(*cookie)); - cookie->movementMaker.Init(); cookie->previousZ = 0; *_cookie = cookie; @@ -543,8 +468,6 @@ elantech_open(const char *name, uint32 flags, void **_cookie) dev->disconnect = &elantech_disconnect; dev->handle_int = &elantech_handle_int; - default_settings(&cookie->settings); - dev->packet_size = PS2_PACKET_ELANTECH; cookie->ring_buffer = create_packet_buffer( @@ -637,9 +560,6 @@ elantech_open(const char *name, uint32 flags, void **_cookie) gHardwareSpecs.realMaxPressure = REAL_MAX_PRESSURE; gHardwareSpecs.maxPressure = MAX_PRESSURE; - cookie->movementMaker.SetSettings(&cookie->settings); - cookie->movementMaker.SetSpecs(&gHardwareSpecs); - if (ps2_dev_command(dev, PS2_CMD_ENABLE, NULL, 0, NULL, 0) != B_OK) goto err4; @@ -665,8 +585,6 @@ err1: status_t elantech_close(void *_cookie) { - gEventProducer.CancelEvent(); - elantech_cookie *cookie = (elantech_cookie*)_cookie; ps2_dev_command_timeout(cookie->dev, PS2_CMD_DISABLE, NULL, 0, NULL, 0, @@ -704,29 +622,25 @@ status_t elantech_ioctl(void *_cookie, uint32 op, void *buffer, size_t length) { elantech_cookie *cookie = (elantech_cookie*)_cookie; - mouse_movement movement; + touchpad_read read; status_t status; switch (op) { - case MS_READ: - TRACE("ELANTECH: MS_READ get event\n"); - if ((status = get_elantech_movement(cookie, &movement)) != B_OK) - return status; - return user_memcpy(buffer, &movement, sizeof(movement)); - case MS_IS_TOUCHPAD: TRACE("ELANTECH: MS_IS_TOUCHPAD\n"); - return B_OK; + if (buffer == NULL) + return B_OK; + return user_memcpy(buffer, &gHardwareSpecs, sizeof(gHardwareSpecs)); - case MS_SET_TOUCHPAD_SETTINGS: - TRACE("ELANTECH: MS_SET_TOUCHPAD_SETTINGS\n"); - user_memcpy(&cookie->settings, buffer, sizeof(touchpad_settings)); - return B_OK; - - case MS_SET_CLICKSPEED: - TRACE("ELANTECH: ioctl MS_SETCLICK (set click speed)\n"); - return user_memcpy(&cookie->movementMaker.click_speed, buffer, - sizeof(bigtime_t)); + case MS_READ_TOUCHPAD: + TRACE("ELANTECH: MS_READ get event\n"); + if (user_memcpy(&read.timeout, &(((touchpad_read*)buffer)->timeout), + sizeof(bigtime_t)) != B_OK) + return B_BAD_ADDRESS; + if ((status = get_elantech_movement(cookie, &read.u.touchpad, read.timeout)) != B_OK) + return status; + read.event = MS_READ_TOUCHPAD; + return user_memcpy(buffer, &read, sizeof(read)); default: INFO("ELANTECH: unknown opcode: 0x%" B_PRIx32 "\n", op); @@ -756,9 +670,6 @@ elantech_handle_int(ps2_dev* dev) { elantech_cookie* cookie = (elantech_cookie*)dev->cookie; - // we got a real event cancel the fake event - gEventProducer.CancelEvent(); - uint8 val; val = cookie->dev->history[0].data; cookie->buffer[cookie->packet_index] = val; @@ -771,9 +682,9 @@ elantech_handle_int(ps2_dev* dev) if (packet_buffer_write(cookie->ring_buffer, cookie->buffer, cookie->dev->packet_size) != cookie->dev->packet_size) { - // buffer is full, drop new data - return B_HANDLED_INTERRUPT; - } + // buffer is full, drop new data + return B_HANDLED_INTERRUPT; + } release_sem_etc(cookie->sem, 1, B_DO_NOT_RESCHEDULE); return B_INVOKE_SCHEDULER; } diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_elantech.h b/src/add-ons/kernel/bus_managers/ps2/ps2_elantech.h index 1089c13919..bc2adb22f6 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_elantech.h +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_elantech.h @@ -14,9 +14,6 @@ #include -#include - -#include "movement_maker.h" #include "packet_buffer.h" #include "ps2_dev.h" @@ -28,9 +25,6 @@ typedef struct { struct packet_buffer* ring_buffer; size_t packet_index; - TouchpadMovement movementMaker; - - touchpad_settings settings; uint32 version; uint32 fwVersion; @@ -47,7 +41,6 @@ typedef struct { uint8 mode; bool crcEnabled; - status_t (*send_command)(ps2_dev* dev, uint8 cmd, uint8 *in, int in_count); } elantech_cookie; diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_synaptics.cpp b/src/add-ons/kernel/bus_managers/ps2/ps2_synaptics.cpp index 5f4d785143..61fdc5bb09 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_synaptics.cpp +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_synaptics.cpp @@ -28,6 +28,15 @@ # define TRACE(x...) #endif +/*! 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_AREA_START_Y (1408 - SYN_AREA_TOP_LEFT_OFFSET) +#define SYN_AREA_END_Y (4448 + SYN_AREA_BOTTOM_RIGHT_OFFSET) + // synaptics touchpad proportions #define SYN_EDGE_MOTION_WIDTH 50 #define SYN_AREA_OFFSET 40 @@ -52,7 +61,7 @@ enum { kTrackpointQuirk = 0x10 }; -static hardware_specs gHardwareSpecs; +static touchpad_specs gHardwareSpecs; const char* kSynapticsPath[4] = { @@ -67,13 +76,6 @@ static touchpad_info sTouchpadInfo; static ps2_dev *sPassthroughDevice = &ps2_device[PS2_DEVICE_SYN_PASSTHROUGH]; -static void -default_settings(touchpad_settings *set) -{ - memcpy(set, &kDefaultTouchpadSettings, sizeof(touchpad_settings)); -} - - static status_t send_touchpad_arg_timeout(ps2_dev *dev, uint8 arg, bigtime_t timeout) { @@ -126,16 +128,17 @@ get_information_query(ps2_dev *dev, uint8 extendedQueries, uint8 query, static status_t -get_synaptics_movment(synaptics_cookie *cookie, mouse_movement *movement) +get_synaptics_movment(synaptics_cookie *cookie, touchpad_movement *_event, bigtime_t timeout) { status_t status; - touch_event event; + touchpad_movement event; uint8 event_buffer[PS2_MAX_PACKET_SIZE]; uint8 wValue0, wValue1, wValue2, wValue3, wValue; uint32 val32; uint32 xTwelfBit, yTwelfBit; - status = acquire_sem_etc(cookie->synaptics_sem, 1, B_CAN_INTERRUPT, 0); + status = acquire_sem_etc(cookie->synaptics_sem, 1, B_CAN_INTERRUPT | B_RELATIVE_TIMEOUT, + timeout); if (status < B_OK) return status; @@ -164,7 +167,7 @@ get_synaptics_movment(synaptics_cookie *cookie, mouse_movement *movement) wValue = wValue | (wValue2 << 2); wValue = wValue | (wValue3 << 3); - event.wValue = wValue; + event.fingerWidth = wValue; event.gesture = false; // Clickpad pretends that all clicks on the touchpad are middle clicks. @@ -204,7 +207,7 @@ get_synaptics_movment(synaptics_cookie *cookie, mouse_movement *movement) bool finger = event_buffer[0] >> 5 & 1; if (finger) { // finger with normal width - event.wValue = 4; + event.fingerWidth = 4; } event.gesture = event_buffer[0] >> 2 & 1; } @@ -222,9 +225,8 @@ get_synaptics_movment(synaptics_cookie *cookie, mouse_movement *movement) yTwelfBit = event_buffer[3] >> 5 & 1; event.yPosition += yTwelfBit << 12; - status = cookie->movementMaker.EventToMovement(&event, movement); - - return status; + *_event = event; + return B_OK; } @@ -460,7 +462,6 @@ synaptics_open(const char *name, uint32 flags, void **_cookie) goto err1; memset(cookie, 0, sizeof(*cookie)); - cookie->movementMaker.Init(); *_cookie = cookie; cookie->dev = dev; @@ -468,8 +469,6 @@ synaptics_open(const char *name, uint32 flags, void **_cookie) dev->disconnect = &synaptics_disconnect; dev->handle_int = &synaptics_handle_int; - default_settings(&cookie->settings); - gHardwareSpecs.edgeMotionWidth = SYN_EDGE_MOTION_WIDTH; gHardwareSpecs.areaStartX = SYN_AREA_START_X; @@ -481,9 +480,6 @@ synaptics_open(const char *name, uint32 flags, void **_cookie) gHardwareSpecs.realMaxPressure = REAL_MAX_PRESSURE; gHardwareSpecs.maxPressure = MAX_PRESSURE; - cookie->movementMaker.SetSettings(&cookie->settings); - cookie->movementMaker.SetSpecs(&gHardwareSpecs); - dev->packet_size = PS2_PACKET_SYNAPTICS; cookie->synaptics_ring_buffer @@ -607,29 +603,25 @@ status_t synaptics_ioctl(void *_cookie, uint32 op, void *buffer, size_t length) { synaptics_cookie *cookie = (synaptics_cookie*)_cookie; - mouse_movement movement; + touchpad_read read; status_t status; switch (op) { - case MS_READ: - if ((status = get_synaptics_movment(cookie, &movement)) != B_OK) - return status; - TRACE("SYNAPTICS: MS_READ get event\n"); - return user_memcpy(buffer, &movement, sizeof(movement)); - case MS_IS_TOUCHPAD: TRACE("SYNAPTICS: MS_IS_TOUCHPAD\n"); - return B_OK; + if (buffer == NULL) + return B_OK; + return user_memcpy(buffer, &gHardwareSpecs, sizeof(gHardwareSpecs)); - case MS_SET_TOUCHPAD_SETTINGS: - TRACE("SYNAPTICS: MS_SET_TOUCHPAD_SETTINGS"); - user_memcpy(&cookie->settings, buffer, sizeof(touchpad_settings)); - return B_OK; - - case MS_SET_CLICKSPEED: - TRACE("SYNAPTICS: ioctl MS_SETCLICK (set click speed)\n"); - return user_memcpy(&cookie->movementMaker.click_speed, buffer, - sizeof(bigtime_t)); + case MS_READ_TOUCHPAD: + TRACE("SYNAPTICS: MS_READ get event\n"); + if (user_memcpy(&read.timeout, &(((touchpad_read*)buffer)->timeout), + sizeof(bigtime_t)) != B_OK) + return B_BAD_ADDRESS; + if ((status = get_synaptics_movment(cookie, &read.u.touchpad, read.timeout)) != B_OK) + return status; + read.event = MS_READ_TOUCHPAD; + return user_memcpy(buffer, &read, sizeof(read)); default: TRACE("SYNAPTICS: unknown opcode: %" B_PRIu32 "\n", op); diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_synaptics.h b/src/add-ons/kernel/bus_managers/ps2/ps2_synaptics.h index 544624c8ff..fd12cbf2ce 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_synaptics.h +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_synaptics.h @@ -11,9 +11,6 @@ #include -#include - -#include "movement_maker.h" #include "packet_buffer.h" #include "ps2_service.h" @@ -65,10 +62,6 @@ struct packet_buffer* synaptics_ring_buffer; size_t packet_index; uint8 buffer[PS2_PACKET_SYNAPTICS]; uint8 mode; - - TouchpadMovement movementMaker; - - touchpad_settings settings; } synaptics_cookie; diff --git a/src/preferences/input/InputTouchpadPref.cpp b/src/preferences/input/InputTouchpadPref.cpp index 330e2a36b6..97924d3b44 100644 --- a/src/preferences/input/InputTouchpadPref.cpp +++ b/src/preferences/input/InputTouchpadPref.cpp @@ -15,7 +15,7 @@ #include #include -#include +#include TouchpadPref::TouchpadPref(BInputDevice* device) @@ -63,7 +63,7 @@ TouchpadPref::UpdateSettings() msg.AddInt8("tapgesture_sensibility", fSettings.tapgesture_sensibility); msg.AddInt32("padblocker_threshold", fSettings.padblocker_threshold); - return fTouchPad->Control(MS_SET_TOUCHPAD_SETTINGS, &msg); + return fTouchPad->Control(B_SET_TOUCHPAD_SETTINGS, &msg); }