* Refactored the former touchevent_to_movement() code to get rid of the gotos,
and some code duplication. * Fixed the missing click count in the former "movement" label (now in the move_to_movement() function); the click count was always 0 in that case, this was most obvious with Firefox where you couldn't click anything as long as you had a finger on the touchpad. * Made the functions static that aren't exported to the outside. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33469 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -133,7 +133,7 @@ ps2_dev_detect_pointing(ps2_dev *dev, device_hooks **hooks)
|
|||||||
|
|
||||||
dev_found:
|
dev_found:
|
||||||
if (dev == &(ps2_device[PS2_DEVICE_SYN_PASSTHROUGH]))
|
if (dev == &(ps2_device[PS2_DEVICE_SYN_PASSTHROUGH]))
|
||||||
synaptics_pt_set_packagesize(dev, dev->packet_size);
|
synaptics_pass_through_set_packet_size(dev, dev->packet_size);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Authors (in chronological order):
|
* Authors (in chronological order):
|
||||||
* Clemens Zeidler ([email protected])
|
* Clemens Zeidler ([email protected])
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -32,51 +33,14 @@ static touchpad_info sTouchpadInfo;
|
|||||||
static ps2_dev *sPassthroughDevice = &ps2_device[PS2_DEVICE_SYN_PASSTHROUGH];
|
static ps2_dev *sPassthroughDevice = &ps2_device[PS2_DEVICE_SYN_PASSTHROUGH];
|
||||||
|
|
||||||
|
|
||||||
void
|
static void
|
||||||
default_settings(touchpad_settings *set)
|
default_settings(touchpad_settings *set)
|
||||||
{
|
{
|
||||||
memcpy(set, &kDefaultTouchpadSettings, sizeof(touchpad_settings));
|
memcpy(set, &kDefaultTouchpadSettings, sizeof(touchpad_settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
static status_t
|
||||||
synaptics_pt_set_packagesize(ps2_dev *dev, uint8 size)
|
|
||||||
{
|
|
||||||
synaptics_cookie *synapticsCookie = dev->parent_dev->cookie;
|
|
||||||
|
|
||||||
status_t status = ps2_dev_command(dev->parent_dev, PS2_CMD_DISABLE, NULL,
|
|
||||||
0, NULL, 0);
|
|
||||||
if (status < B_OK) {
|
|
||||||
INFO("SYNAPTICS: cannot disable touchpad %s\n", dev->parent_dev->name);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
synapticsCookie->packet_index = 0;
|
|
||||||
|
|
||||||
if (size == 4)
|
|
||||||
synapticsCookie->mode |= SYN_FOUR_BYTE_CHILD;
|
|
||||||
else
|
|
||||||
synapticsCookie->mode &= ~SYN_FOUR_BYTE_CHILD;
|
|
||||||
|
|
||||||
set_touchpad_mode(dev->parent_dev, synapticsCookie->mode);
|
|
||||||
|
|
||||||
status = ps2_dev_command(dev->parent_dev, PS2_CMD_ENABLE, NULL, 0, NULL, 0);
|
|
||||||
if (status < B_OK) {
|
|
||||||
INFO("SYNAPTICS: cannot enable touchpad %s\n", dev->parent_dev->name);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
send_touchpad_arg(ps2_dev *dev, uint8 arg)
|
|
||||||
{
|
|
||||||
return send_touchpad_arg_timeout(dev, arg, 4000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
send_touchpad_arg_timeout(ps2_dev *dev, uint8 arg, bigtime_t timeout)
|
send_touchpad_arg_timeout(ps2_dev *dev, uint8 arg, bigtime_t timeout)
|
||||||
{
|
{
|
||||||
int8 i;
|
int8 i;
|
||||||
@@ -89,7 +53,14 @@ send_touchpad_arg_timeout(ps2_dev *dev, uint8 arg, bigtime_t timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
static status_t
|
||||||
|
send_touchpad_arg(ps2_dev *dev, uint8 arg)
|
||||||
|
{
|
||||||
|
return send_touchpad_arg_timeout(dev, arg, 4000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
set_touchpad_mode(ps2_dev *dev, uint8 mode)
|
set_touchpad_mode(ps2_dev *dev, uint8 mode)
|
||||||
{
|
{
|
||||||
uint8 sample_rate = SYN_CHANGE_MODE;
|
uint8 sample_rate = SYN_CHANGE_MODE;
|
||||||
@@ -99,65 +70,7 @@ set_touchpad_mode(ps2_dev *dev, uint8 mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
static bool
|
||||||
passthrough_command(ps2_dev *dev, uint8 cmd, const uint8 *out, int outCount,
|
|
||||||
uint8 *in, int inCount, bigtime_t timeout)
|
|
||||||
{
|
|
||||||
status_t status;
|
|
||||||
uint8 passThroughCmd = SYN_PASSTHROUGH_CMD;
|
|
||||||
uint8 val;
|
|
||||||
uint32 passThroughInCount = (inCount + 1) * 6;
|
|
||||||
uint8 passThroughIn[passThroughInCount];
|
|
||||||
int8 i;
|
|
||||||
|
|
||||||
TRACE("SYNAPTICS: passthrough command 0x%x\n", cmd);
|
|
||||||
|
|
||||||
status = ps2_dev_command(dev->parent_dev, PS2_CMD_DISABLE, NULL, 0,
|
|
||||||
NULL, 0);
|
|
||||||
if (status != B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
for (i = -1; i < outCount; i++) {
|
|
||||||
if (i == -1)
|
|
||||||
val = cmd;
|
|
||||||
else
|
|
||||||
val = out[i];
|
|
||||||
status = send_touchpad_arg_timeout(dev->parent_dev, val, timeout);
|
|
||||||
if (status != B_OK)
|
|
||||||
return status;
|
|
||||||
if (i != outCount -1) {
|
|
||||||
status = ps2_dev_command_timeout(dev->parent_dev,
|
|
||||||
PS2_CMD_SET_SAMPLE_RATE, &passThroughCmd, 1, NULL, 0, timeout);
|
|
||||||
if (status != B_OK)
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
status = ps2_dev_command_timeout(dev->parent_dev, PS2_CMD_SET_SAMPLE_RATE,
|
|
||||||
&passThroughCmd, 1, passThroughIn, passThroughInCount, timeout);
|
|
||||||
if (status != B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
for (i = 0; i < inCount + 1; i++) {
|
|
||||||
uint8 *inPointer = &passThroughIn[i * 6];
|
|
||||||
if (!IS_SYN_PT_PACKAGE(inPointer)) {
|
|
||||||
TRACE("SYNAPTICS: not a pass throught package\n");
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
if (i == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
in[i - 1] = passThroughIn[i * 6 + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
status = ps2_dev_command(dev->parent_dev, PS2_CMD_ENABLE, NULL, 0, NULL, 0);
|
|
||||||
if (status != B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
edge_motion(mouse_movement *movement, touch_event *event, bool validStart)
|
edge_motion(mouse_movement *movement, touch_event *event, bool validStart)
|
||||||
{
|
{
|
||||||
int32 xdelta = 0;
|
int32 xdelta = 0;
|
||||||
@@ -185,85 +98,89 @@ edge_motion(mouse_movement *movement, touch_event *event, bool validStart)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
/*! If a button has been clicked (movement->buttons must be set accordingly),
|
||||||
touchevent_to_movement(synaptics_cookie* cookie, touch_event *event,
|
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(synaptics_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(synaptics_cookie *cookie, touch_event *event,
|
||||||
mouse_movement *movement)
|
mouse_movement *movement)
|
||||||
{
|
{
|
||||||
bool isSideScrollingV = false;
|
|
||||||
bool isSideScrollingH = false;
|
|
||||||
bool isInTouch = false;
|
|
||||||
bool isStartOfMovement = false;
|
|
||||||
float sens = 0;
|
|
||||||
bigtime_t currentTime = system_time();
|
|
||||||
touchpad_settings *settings = &cookie->settings;
|
|
||||||
uint32 buttons = event->buttons;
|
uint32 buttons = event->buttons;
|
||||||
|
|
||||||
if (!movement)
|
TRACE("SYNAPTICS: no touch event\n");
|
||||||
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 = currentTime;
|
|
||||||
|
|
||||||
if ((currentTime - cookie->tap_time) > SYN_TAP_TIMEOUT) {
|
|
||||||
TRACE("SYNAPTICS: tap gesture timed out\n");
|
|
||||||
cookie->tap_started = false;
|
|
||||||
if (!cookie->double_click
|
|
||||||
|| (currentTime - cookie->tap_time) > 2 * SYN_TAP_TIMEOUT) {
|
|
||||||
cookie->tap_clicks = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event->buttons != 0) {
|
|
||||||
cookie->tap_clicks = 0;
|
|
||||||
cookie->tapdrag_started = false;
|
|
||||||
cookie->tap_started = false;
|
|
||||||
cookie->valid_edge_motion = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event->zPressure >= MIN_PRESSURE && event->zPressure < MAX_PRESSURE
|
|
||||||
&& ((event->wValue >=4 && event->wValue <=7)
|
|
||||||
|| event->wValue == 0 || event->wValue == 1)
|
|
||||||
&& (event->xPosition != 0 || event->yPosition != 0)) {
|
|
||||||
isInTouch = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isInTouch) {
|
|
||||||
if ((SYN_AREA_END_X - SYN_AREA_WIDTH_X * settings->scroll_rightrange
|
|
||||||
< event->xPosition && !cookie->movement_started
|
|
||||||
&& settings->scroll_rightrange > 0.000001)
|
|
||||||
|| settings->scroll_rightrange > 0.999999) {
|
|
||||||
isSideScrollingV = true;
|
|
||||||
}
|
|
||||||
if ((SYN_AREA_START_Y + SYN_AREA_WIDTH_Y * settings->scroll_bottomrange
|
|
||||||
> event->yPosition && !cookie->movement_started
|
|
||||||
&& settings->scroll_bottomrange > 0.000001)
|
|
||||||
|| settings->scroll_bottomrange > 0.999999) {
|
|
||||||
isSideScrollingH = true;
|
|
||||||
}
|
|
||||||
if ((event->wValue == 0 || event->wValue == 1)
|
|
||||||
&& settings->scroll_twofinger) {
|
|
||||||
// two finger scrolling is enabled
|
|
||||||
isSideScrollingV = true;
|
|
||||||
isSideScrollingH = settings->scroll_twofinger_horizontal;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSideScrollingV || isSideScrollingH)
|
|
||||||
goto scrolling;
|
|
||||||
else
|
|
||||||
cookie->scrolling_started = false;
|
cookie->scrolling_started = false;
|
||||||
|
cookie->movement_started = false;
|
||||||
|
|
||||||
goto movement;
|
if (cookie->tapdrag_started
|
||||||
} else {
|
&& (movement->timestamp - cookie->tap_time) < SYN_TAP_TIMEOUT) {
|
||||||
goto notouch;
|
buttons = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
movement:
|
// if the movement stopped switch off the tap drag when timeout is expired
|
||||||
|
if ((movement->timestamp - cookie->tap_time) > SYN_TAP_TIMEOUT) {
|
||||||
|
cookie->tapdrag_started = false;
|
||||||
|
cookie->valid_edge_motion = false;
|
||||||
|
TRACE("SYNAPTICS: 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("SYNAPTICS: tap gesture\n");
|
||||||
|
cookie->tap_clicks++;
|
||||||
|
|
||||||
|
if (cookie->tap_clicks > 1) {
|
||||||
|
TRACE("SYNAPTICS: 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(synaptics_cookie *cookie, touch_event *event,
|
||||||
|
mouse_movement *movement)
|
||||||
|
{
|
||||||
|
touchpad_settings *settings = &cookie->settings;
|
||||||
|
bool isStartOfMovement = false;
|
||||||
|
float pressure = 0;
|
||||||
|
|
||||||
TRACE("SYNAPTICS: movement event\n");
|
TRACE("SYNAPTICS: movement event\n");
|
||||||
if (!cookie->movement_started) {
|
if (!cookie->movement_started) {
|
||||||
isStartOfMovement = true;
|
isStartOfMovement = true;
|
||||||
@@ -294,11 +211,11 @@ movement:
|
|||||||
|
|
||||||
// use only a fraction of pressure range, the max pressure seems to be
|
// use only a fraction of pressure range, the max pressure seems to be
|
||||||
// to high
|
// to high
|
||||||
sens = 20 * (event->zPressure - MIN_PRESSURE)
|
pressure = 20 * (event->zPressure - MIN_PRESSURE)
|
||||||
/ (MAX_PRESSURE - MIN_PRESSURE - 100);
|
/ (MAX_PRESSURE - MIN_PRESSURE - 100);
|
||||||
if (!cookie->tap_started
|
if (!cookie->tap_started
|
||||||
&& isStartOfMovement
|
&& isStartOfMovement
|
||||||
&& settings->tapgesture_sensibility > (20 - sens)) {
|
&& settings->tapgesture_sensibility > (20 - pressure)) {
|
||||||
TRACE("SYNAPTICS: tap started\n");
|
TRACE("SYNAPTICS: tap started\n");
|
||||||
cookie->tap_started = true;
|
cookie->tap_started = true;
|
||||||
cookie->tap_time = system_time();
|
cookie->tap_time = system_time();
|
||||||
@@ -306,12 +223,49 @@ movement:
|
|||||||
cookie->tap_delta_y = 0;
|
cookie->tap_delta_y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie->buttons_state = movement->buttons;
|
update_buttons(cookie, movement);
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
scrolling:
|
/*! 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.
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
check_scrolling_to_movement(synaptics_cookie *cookie, touch_event *event,
|
||||||
|
mouse_movement *movement)
|
||||||
|
{
|
||||||
|
touchpad_settings *settings = &cookie->settings;
|
||||||
|
bool isSideScrollingV = false;
|
||||||
|
bool isSideScrollingH = false;
|
||||||
|
|
||||||
|
if ((SYN_AREA_END_X - SYN_AREA_WIDTH_X * settings->scroll_rightrange
|
||||||
|
< event->xPosition && !cookie->movement_started
|
||||||
|
&& settings->scroll_rightrange > 0.000001)
|
||||||
|
|| settings->scroll_rightrange > 0.999999) {
|
||||||
|
isSideScrollingV = true;
|
||||||
|
}
|
||||||
|
if ((SYN_AREA_START_Y + SYN_AREA_WIDTH_Y * settings->scroll_bottomrange
|
||||||
|
> event->yPosition && !cookie->movement_started
|
||||||
|
&& settings->scroll_bottomrange > 0.000001)
|
||||||
|
|| settings->scroll_bottomrange > 0.999999) {
|
||||||
|
isSideScrollingH = true;
|
||||||
|
}
|
||||||
|
if ((event->wValue == 0 || event->wValue == 1)
|
||||||
|
&& settings->scroll_twofinger) {
|
||||||
|
// two finger scrolling is enabled
|
||||||
|
isSideScrollingV = true;
|
||||||
|
isSideScrollingH = settings->scroll_twofinger_horizontal;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSideScrollingV && !isSideScrollingH) {
|
||||||
|
cookie->scrolling_started = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("SYNAPTICS: scroll event\n");
|
TRACE("SYNAPTICS: scroll event\n");
|
||||||
|
|
||||||
cookie->tap_started = false;
|
cookie->tap_started = false;
|
||||||
cookie->tap_clicks = 0;
|
cookie->tap_clicks = 0;
|
||||||
cookie->tapdrag_started = false;
|
cookie->tapdrag_started = false;
|
||||||
@@ -332,67 +286,57 @@ scrolling:
|
|||||||
|
|
||||||
cookie->buttons_state = movement->buttons;
|
cookie->buttons_state = movement->buttons;
|
||||||
|
|
||||||
return B_OK;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
notouch:
|
|
||||||
TRACE("SYNAPTICS: no touch event\n");
|
|
||||||
cookie->scrolling_started = false;
|
|
||||||
cookie->movement_started = false;
|
|
||||||
|
|
||||||
if (cookie->tapdrag_started
|
static status_t
|
||||||
&& (currentTime - cookie->tap_time) < SYN_TAP_TIMEOUT) {
|
event_to_movement(synaptics_cookie *cookie, touch_event *event,
|
||||||
buttons = 0x01;
|
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 - cookie->tap_time) > SYN_TAP_TIMEOUT) {
|
||||||
|
TRACE("SYNAPTICS: tap gesture timed out\n");
|
||||||
|
cookie->tap_started = false;
|
||||||
|
if (!cookie->double_click
|
||||||
|
|| (movement->timestamp - cookie->tap_time) > 2 * SYN_TAP_TIMEOUT) {
|
||||||
|
cookie->tap_clicks = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the movement stopped switch off the tap drag when timeout is expired
|
if (event->buttons != 0) {
|
||||||
if ((currentTime - cookie->tap_time) > SYN_TAP_TIMEOUT) {
|
cookie->tap_clicks = 0;
|
||||||
cookie->tapdrag_started = false;
|
cookie->tapdrag_started = false;
|
||||||
|
cookie->tap_started = false;
|
||||||
cookie->valid_edge_motion = false;
|
cookie->valid_edge_motion = false;
|
||||||
TRACE("SYNAPTICS: tap drag gesture timed out\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abs(cookie->tap_delta_x) > 15 || abs(cookie->tap_delta_y) > 15) {
|
if (event->zPressure >= MIN_PRESSURE && event->zPressure < MAX_PRESSURE
|
||||||
cookie->tap_started = false;
|
&& ((event->wValue >=4 && event->wValue <=7)
|
||||||
cookie->tap_clicks = 0;
|
|| event->wValue == 0 || event->wValue == 1)
|
||||||
}
|
&& (event->xPosition != 0 || event->yPosition != 0)) {
|
||||||
|
// The touch pad is in touch with at least one finger
|
||||||
if (cookie->tap_started || cookie->double_click) {
|
if (!check_scrolling_to_movement(cookie, event, movement))
|
||||||
TRACE("SYNAPTICS: tap gesture\n");
|
move_to_movement(cookie, event, movement);
|
||||||
cookie->tap_clicks++;
|
} else
|
||||||
|
no_touch_to_movement(cookie, event, movement);
|
||||||
if (cookie->tap_clicks > 1) {
|
|
||||||
TRACE("SYNAPTICS: 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set click count correctly according to double click timeout
|
|
||||||
if (buttons != 0 && cookie->buttons_state == 0) {
|
|
||||||
if (cookie->click_last_time + cookie->click_speed > currentTime)
|
|
||||||
cookie->click_count++;
|
|
||||||
else
|
|
||||||
cookie->click_count = 1;
|
|
||||||
|
|
||||||
cookie->click_last_time = currentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
movement->buttons = buttons;
|
|
||||||
cookie->buttons_state = buttons;
|
|
||||||
if (buttons)
|
|
||||||
movement->clicks = cookie->click_count;
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
static status_t
|
||||||
get_synaptics_movment(synaptics_cookie *cookie, mouse_movement *movement)
|
get_synaptics_movment(synaptics_cookie *cookie, mouse_movement *movement)
|
||||||
{
|
{
|
||||||
status_t status;
|
status_t status;
|
||||||
@@ -455,13 +399,13 @@ get_synaptics_movment(synaptics_cookie *cookie, mouse_movement *movement)
|
|||||||
yTwelfBit = event_buffer[3] >> 5 & 1;
|
yTwelfBit = event_buffer[3] >> 5 & 1;
|
||||||
event.yPosition += yTwelfBit << 12;
|
event.yPosition += yTwelfBit << 12;
|
||||||
|
|
||||||
status = touchevent_to_movement(cookie, &event, movement);
|
status = event_to_movement(cookie, &event, movement);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
static void
|
||||||
query_capability(ps2_dev *dev)
|
query_capability(ps2_dev *dev)
|
||||||
{
|
{
|
||||||
uint8 val[3];
|
uint8 val[3];
|
||||||
@@ -483,7 +427,95 @@ query_capability(ps2_dev *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark - exported functions
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
synaptics_pass_through_set_packet_size(ps2_dev *dev, uint8 size)
|
||||||
|
{
|
||||||
|
synaptics_cookie *synapticsCookie = dev->parent_dev->cookie;
|
||||||
|
|
||||||
|
status_t status = ps2_dev_command(dev->parent_dev, PS2_CMD_DISABLE, NULL,
|
||||||
|
0, NULL, 0);
|
||||||
|
if (status < B_OK) {
|
||||||
|
INFO("SYNAPTICS: cannot disable touchpad %s\n", dev->parent_dev->name);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
synapticsCookie->packet_index = 0;
|
||||||
|
|
||||||
|
if (size == 4)
|
||||||
|
synapticsCookie->mode |= SYN_FOUR_BYTE_CHILD;
|
||||||
|
else
|
||||||
|
synapticsCookie->mode &= ~SYN_FOUR_BYTE_CHILD;
|
||||||
|
|
||||||
|
set_touchpad_mode(dev->parent_dev, synapticsCookie->mode);
|
||||||
|
|
||||||
|
status = ps2_dev_command(dev->parent_dev, PS2_CMD_ENABLE, NULL, 0, NULL, 0);
|
||||||
|
if (status < B_OK) {
|
||||||
|
INFO("SYNAPTICS: cannot enable touchpad %s\n", dev->parent_dev->name);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
passthrough_command(ps2_dev *dev, uint8 cmd, const uint8 *out, int outCount,
|
||||||
|
uint8 *in, int inCount, bigtime_t timeout)
|
||||||
|
{
|
||||||
|
status_t status;
|
||||||
|
uint8 passThroughCmd = SYN_PASSTHROUGH_CMD;
|
||||||
|
uint8 val;
|
||||||
|
uint32 passThroughInCount = (inCount + 1) * 6;
|
||||||
|
uint8 passThroughIn[passThroughInCount];
|
||||||
|
int8 i;
|
||||||
|
|
||||||
|
TRACE("SYNAPTICS: passthrough command 0x%x\n", cmd);
|
||||||
|
|
||||||
|
status = ps2_dev_command(dev->parent_dev, PS2_CMD_DISABLE, NULL, 0,
|
||||||
|
NULL, 0);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
for (i = -1; i < outCount; i++) {
|
||||||
|
if (i == -1)
|
||||||
|
val = cmd;
|
||||||
|
else
|
||||||
|
val = out[i];
|
||||||
|
status = send_touchpad_arg_timeout(dev->parent_dev, val, timeout);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
if (i != outCount -1) {
|
||||||
|
status = ps2_dev_command_timeout(dev->parent_dev,
|
||||||
|
PS2_CMD_SET_SAMPLE_RATE, &passThroughCmd, 1, NULL, 0, timeout);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
status = ps2_dev_command_timeout(dev->parent_dev, PS2_CMD_SET_SAMPLE_RATE,
|
||||||
|
&passThroughCmd, 1, passThroughIn, passThroughInCount, timeout);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
for (i = 0; i < inCount + 1; i++) {
|
||||||
|
uint8 *inPointer = &passThroughIn[i * 6];
|
||||||
|
if (!IS_SYN_PT_PACKAGE(inPointer)) {
|
||||||
|
TRACE("SYNAPTICS: not a pass throught package\n");
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
if (i == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
in[i - 1] = passThroughIn[i * 6 + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
status = ps2_dev_command(dev->parent_dev, PS2_CMD_ENABLE, NULL, 0, NULL, 0);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
* Authors (in chronological order):
|
* Authors (in chronological order):
|
||||||
* Clemens Zeidler (haiku@Clemens-Zeidler.de)
|
* Clemens Zeidler (haiku@Clemens-Zeidler.de)
|
||||||
*/
|
*/
|
||||||
#ifndef SYNAPTICS_H
|
#ifndef PS2_SYNAPTICS_H
|
||||||
#define SYNAPTICS_H
|
#define PS2_SYNAPTICS_H
|
||||||
|
|
||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
@@ -64,7 +64,6 @@ typedef struct {
|
|||||||
bool capMultiFinger;
|
bool capMultiFinger;
|
||||||
bool capPalmDetection;
|
bool capPalmDetection;
|
||||||
bool capPassThrough;
|
bool capPassThrough;
|
||||||
|
|
||||||
} touchpad_info;
|
} touchpad_info;
|
||||||
|
|
||||||
|
|
||||||
@@ -111,21 +110,10 @@ typedef struct {
|
|||||||
} synaptics_cookie;
|
} synaptics_cookie;
|
||||||
|
|
||||||
|
|
||||||
void default_settings(touchpad_settings *settings);
|
|
||||||
|
|
||||||
status_t synaptics_pt_set_packagesize(ps2_dev *dev, uint8 size);
|
status_t synaptics_pass_through_set_packet_size(ps2_dev *dev, uint8 size);
|
||||||
status_t send_touchpad_arg(ps2_dev *dev, uint8 arg);
|
|
||||||
status_t send_touchpad_arg_timeout(ps2_dev *dev, uint8 arg, bigtime_t timeout);
|
|
||||||
status_t set_touchpad_mode(ps2_dev *dev, uint8 mode);
|
|
||||||
status_t passthrough_command(ps2_dev *dev, uint8 cmd, const uint8 *out,
|
status_t passthrough_command(ps2_dev *dev, uint8 cmd, const uint8 *out,
|
||||||
int out_count, uint8 *in, int in_count, bigtime_t timeout);
|
int out_count, uint8 *in, int in_count, bigtime_t timeout);
|
||||||
|
|
||||||
bool edge_motion(mouse_movement *movement, touch_event *event, bool validStart);
|
|
||||||
status_t touchevent_to_movement(synaptics_cookie* cookie, touch_event *event,
|
|
||||||
mouse_movement *movement);
|
|
||||||
status_t get_synaptics_movment(synaptics_cookie* cookie,
|
|
||||||
mouse_movement *movement);
|
|
||||||
void query_capability(ps2_dev *dev);
|
|
||||||
status_t probe_synaptics(ps2_dev *dev);
|
status_t probe_synaptics(ps2_dev *dev);
|
||||||
|
|
||||||
status_t synaptics_open(const char *name, uint32 flags, void **_cookie);
|
status_t synaptics_open(const char *name, uint32 flags, void **_cookie);
|
||||||
@@ -138,4 +126,4 @@ void synaptics_disconnect(ps2_dev *dev);
|
|||||||
|
|
||||||
device_hooks gSynapticsDeviceHooks;
|
device_hooks gSynapticsDeviceHooks;
|
||||||
|
|
||||||
#endif
|
#endif // PS2_SYNAPTICS_H
|
||||||
|
|||||||
Reference in New Issue
Block a user