Skip to content

Commit

Permalink
Use VoodooInput Trackpoint logic for Elan Touchpads (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
1Revenger1 authored Apr 2, 2023
1 parent 4e27bd9 commit db22ab1
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 94 deletions.
99 changes: 47 additions & 52 deletions VoodooPS2Trackpad/VoodooPS2Elan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,7 @@
// ApplePS2Elan Class Implementation
//

OSDefineMetaClassAndStructors(ApplePS2Elan, IOHIPointing);

UInt32 ApplePS2Elan::deviceType()
{ return NX_EVS_DEVICE_TYPE_MOUSE; };

UInt32 ApplePS2Elan::interfaceID()
{ return NX_EVS_DEVICE_INTERFACE_BUS_ACE; };
OSDefineMetaClassAndStructors(ApplePS2Elan, IOService);

bool ApplePS2Elan::init(OSDictionary *dict) {
// Initialize this object's minimal state. This is invoked right after this
Expand Down Expand Up @@ -239,18 +233,6 @@ bool ApplePS2Elan::start(IOService *provider) {
}
#endif

// Advertise the current state of the tapping feature.
//
// Must add this property to let our superclass know that it should handle
// trackpad acceleration settings from user space. Without this, tracking
// speed adjustments from the mouse prefs panel have no effect.
setProperty(kIOHIDPointerAccelerationTypeKey, kIOHIDTrackpadAccelerationType);
setProperty(kIOHIDScrollAccelerationTypeKey, kIOHIDTrackpadScrollAccelerationKey);
setProperty(kIOHIDScrollResolutionKey, _scrollresolution << 16, 32);
// added for Sierra precise scrolling (credit @usr-sse2)
setProperty("HIDScrollResolutionX", _scrollresolution << 16, 32);
setProperty("HIDScrollResolutionY", _scrollresolution << 16, 32);

// Setup workloop with command gate for thread syncronization...
IOWorkLoop *pWorkLoop = getWorkLoop();
_cmdGate = IOCommandGate::commandGate(this);
Expand Down Expand Up @@ -340,11 +322,15 @@ void ApplePS2Elan::setParamPropertiesGated(OSDictionary *config) {

const struct {const char *name; int *var;} int32vars[] = {
{"WakeDelay", &wakedelay},
{"ScrollResolution", &_scrollresolution},
{"TrackpointDeadzone", &_trackpointDeadzone},
{"TrackpointMultiplierX", &_trackpointMultiplierX},
{"TrackpointMultiplierY", &_trackpointMultiplierY},
{"TrackpointDividerX", &_trackpointDividerX},
{"TrackpointDividerY", &_trackpointDividerY},
{"TrackpointScrollMultiplierX", &_trackpointScrollMultiplierX},
{"TrackpointScrollMultiplierY", &_trackpointScrollMultiplierY},
{"TrackpointScrollDividerY", &_trackpointScrollDividerX},
{"TrackpointScrollDividerY", &_trackpointScrollDividerY},
{"MouseResolution", &_mouseResolution},
{"MouseSampleRate", &_mouseSampleRate},
{"ForceTouchMode", (int*)&_forceTouchMode},
Expand Down Expand Up @@ -412,16 +398,8 @@ void ApplePS2Elan::setParamPropertiesGated(OSDictionary *config) {
if (attachedHIDPointerDevices && attachedHIDPointerDevices->getCount() > 0) {
ignoreall = usb_mouse_stops_trackpad;
}
}

IOReturn ApplePS2Elan::setParamProperties(OSDictionary *dict) {
if (_cmdGate) {
// syncronize through workloop...
//_cmdGate->runAction(OSMemberFunctionCast(IOCommandGate::Action, this, &ApplePS2Elan::setParamPropertiesGated), dict);
setParamPropertiesGated(dict);
}

return super::setParamProperties(dict);

setTrackpointProperties();
}

IOReturn ApplePS2Elan::setProperties(OSObject *props) {
Expand All @@ -434,6 +412,28 @@ IOReturn ApplePS2Elan::setProperties(OSObject *props) {
return super::setProperties(props);
}

void ApplePS2Elan::setTrackpointProperties()
{
// Trackpoint information for VoodooInput
OSDictionary *trackpoint = OSDictionary::withCapacity(10);
if (trackpoint == nullptr)
return;

PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_DEADZONE, _trackpointDeadzone);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_BTN_CNT, 3);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_MOUSE_MULT_X, _trackpointMultiplierX);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_MOUSE_MULT_Y, _trackpointMultiplierY);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_MOUSE_DIV_X, _trackpointDividerX);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_MOUSE_DIV_Y, _trackpointDividerY);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_SCROLL_MULT_X, _trackpointScrollMultiplierX);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_SCROLL_MULT_Y, _trackpointScrollMultiplierY);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_SCROLL_DIV_X, _trackpointScrollDividerX);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_SCROLL_DIV_Y, _trackpointScrollDividerY);

setProperty(VOODOO_TRACKPOINT_KEY, trackpoint);
OSSafeReleaseNULL(trackpoint);
}

IOReturn ApplePS2Elan::message(UInt32 type, IOService* provider, void* argument) {
// Here is where we receive messages from the keyboard driver
//
Expand Down Expand Up @@ -1870,19 +1870,6 @@ void ApplePS2Elan::elantechReportTrackpoint() {
int dx = packet[4] - (int)((packet[1] ^ 0x80) << 1);
int dy = (int)((packet[2] ^ 0x80) << 1) - packet[5];

dx = dx * _trackpointMultiplierX / _trackpointDividerX;
dy = dy * _trackpointMultiplierY / _trackpointDividerY;

// enable trackpoint scroll mode when middle button was pressed and the trackpoint moved
if (trackpointMiddleButton == 4 && (dx != 0 || dy != 0)) {
trackpointScrolling = true;
}

// disable trackpoint scrolling mode when middle button is released
if (trackpointScrolling && trackpointMiddleButton == 0) {
trackpointScrolling = false;
}

AbsoluteTime timestamp;
clock_get_uptime(&timestamp);

Expand All @@ -1891,12 +1878,13 @@ void ApplePS2Elan::elantechReportTrackpoint() {
uint64_t timestamp_ns;
absolutetime_to_nanoseconds(timestamp, &timestamp_ns);
keytime = timestamp_ns;

if (trackpointScrolling) {
dispatchScrollWheelEvent(dy, dx, 0, timestamp);
} else {
dispatchRelativePointerEvent(dx, dy, trackpointRightButton | trackpointLeftButton | trackpointMiddleButton, timestamp);
}

trackpointReport.timestamp = timestamp;
trackpointReport.buttons = trackpointLeftButton | trackpointMiddleButton | trackpointRightButton;
trackpointReport.dx = dx;
trackpointReport.dy = dy;
super::messageClient(kIOMessageVoodooTrackpointMessage, voodooInputInstance,
&trackpointReport, sizeof(trackpointReport));
}

void ApplePS2Elan::processPacketStatusV4() {
Expand Down Expand Up @@ -2108,8 +2096,11 @@ void ApplePS2Elan::sendTouchData() {

if (!info.is_buttonpad) {
if (transducers_count == 0) {
UInt32 buttons = leftButton | rightButton;
dispatchRelativePointerEvent(0, 0, buttons, timestamp);
trackpointReport.timestamp = timestamp;
trackpointReport.buttons = leftButton | rightButton;
trackpointReport.dx = trackpointReport.dy = 0;
super::messageClient(kIOMessageVoodooTrackpointMessage, voodooInputInstance,
&trackpointReport, sizeof(trackpointReport));
} else {
UInt32 buttons = 0;
bool send = false;
Expand All @@ -2122,7 +2113,11 @@ void ApplePS2Elan::sendTouchData() {
send = true;
}
if (send) {
dispatchRelativePointerEvent(0, 0, buttons, timestamp);
trackpointReport.timestamp = timestamp;
trackpointReport.buttons = buttons;
trackpointReport.dx = trackpointReport.dy = 0;
super::messageClient(kIOMessageVoodooTrackpointMessage, voodooInputInstance,
&trackpointReport, sizeof(trackpointReport));
}
}

Expand Down
18 changes: 9 additions & 9 deletions VoodooPS2Trackpad/VoodooPS2Elan.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ struct elantech_data {
// ApplePS2Elan Class Declaration
//

class EXPORT ApplePS2Elan : public IOHIPointing {
typedef IOHIPointing super;
class EXPORT ApplePS2Elan : public IOService {
typedef IOService super;
OSDeclareDefaultStructors(ApplePS2Elan);

private:
Expand All @@ -225,6 +225,7 @@ class EXPORT ApplePS2Elan : public IOHIPointing {
IOCommandGate* _cmdGate {nullptr};

VoodooInputEvent inputEvent {};
TrackpointReport trackpointReport {};

// when trackpad has physical button
UInt32 leftButton = 0;
Expand All @@ -236,8 +237,6 @@ class EXPORT ApplePS2Elan : public IOHIPointing {
const float cos30deg = 0.86602540378f;
UInt32 lastFingers = 0;

bool trackpointScrolling {false};

int heldFingers = 0;
int headPacketsCount = 0;
elan_virtual_finger_state virtualFinger[ETP_MAX_FINGERS] {};
Expand All @@ -246,12 +245,16 @@ class EXPORT ApplePS2Elan : public IOHIPointing {

ForceTouchMode _forceTouchMode {FORCE_TOUCH_BUTTON};

int _scrollresolution {2300};
int wakedelay {1000};
int _trackpointDeadzone {1};
int _trackpointMultiplierX {120};
int _trackpointMultiplierY {120};
int _trackpointDividerX {120};
int _trackpointDividerY {120};
int _trackpointScrollMultiplierX {120};
int _trackpointScrollMultiplierY {120};
int _trackpointScrollDividerX {120};
int _trackpointScrollDividerY {120};

int _mouseResolution {0x3};
int _mouseSampleRate {200};
Expand Down Expand Up @@ -285,6 +288,7 @@ class EXPORT ApplePS2Elan : public IOHIPointing {

void setParamPropertiesGated(OSDictionary *dict);
void injectVersionDependentProperties(OSDictionary *dict);
void setTrackpointProperties();

void registerHIDPointerNotifications();
void unregisterHIDPointerNotifications();
Expand Down Expand Up @@ -344,10 +348,6 @@ class EXPORT ApplePS2Elan : public IOHIPointing {
bool start(IOService *provider) override;
void stop(IOService *provider) override;

UInt32 deviceType() override;
UInt32 interfaceID() override;

IOReturn setParamProperties(OSDictionary* dict) override;
IOReturn setProperties(OSObject *props) override;

IOReturn message(UInt32 type, IOService* provider, void* argument) override;
Expand Down
45 changes: 12 additions & 33 deletions VoodooPS2Trackpad/VoodooPS2SynapticsTouchPad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1901,43 +1901,22 @@ IOReturn ApplePS2SynapticsTouchPad::setProperties(OSObject *props)
void ApplePS2SynapticsTouchPad::setTrackpointProperties()
{
// Trackpoint information for VoodooInput
OSDictionary *trackpoint = OSDictionary::withCapacity(5);
OSDictionary *trackpoint = OSDictionary::withCapacity(10);
if (trackpoint == nullptr)
return;

OSNumber *deadzone = OSNumber::withNumber(_deadzone, 32);
OSNumber *buttonCnt = OSNumber::withNumber(3, 32);
OSNumber *multX = OSNumber::withNumber(_mouseMultiplierX, 32);
OSNumber *multY = OSNumber::withNumber(_mouseMultiplierY, 32);
OSNumber *divX = OSNumber::withNumber(_mouseDivisorX, 32);
OSNumber *divY = OSNumber::withNumber(_mouseDivisorY, 32);
OSNumber *scrollMultX = OSNumber::withNumber(_scrollMultiplierX, 32);
OSNumber *scrollMultY = OSNumber::withNumber(_scrollMultiplierY, 32);
OSNumber *scrollDivX = OSNumber::withNumber(_scrollDivisorX, 32);
OSNumber *scrollDivY = OSNumber::withNumber(_scrollDivisorY, 32);

trackpoint->setObject(VOODOO_TRACKPOINT_DEADZONE, deadzone);
trackpoint->setObject(VOODOO_TRACKPOINT_BTN_CNT, buttonCnt);
trackpoint->setObject(VOODOO_TRACKPOINT_MOUSE_MULT_X, multX);
trackpoint->setObject(VOODOO_TRACKPOINT_MOUSE_MULT_Y, multY);
trackpoint->setObject(VOODOO_TRACKPOINT_MOUSE_DIV_X, divX);
trackpoint->setObject(VOODOO_TRACKPOINT_MOUSE_DIV_Y, divY);
trackpoint->setObject(VOODOO_TRACKPOINT_SCROLL_MULT_X, scrollMultX);
trackpoint->setObject(VOODOO_TRACKPOINT_SCROLL_MULT_Y, scrollMultY);
trackpoint->setObject(VOODOO_TRACKPOINT_SCROLL_DIV_X, scrollDivX);
trackpoint->setObject(VOODOO_TRACKPOINT_SCROLL_DIV_Y, scrollDivY);
setProperty(VOODOO_TRACKPOINT_KEY, trackpoint);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_DEADZONE, _deadzone);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_BTN_CNT, 3);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_MOUSE_MULT_X, _mouseMultiplierX);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_MOUSE_MULT_Y, _mouseMultiplierY);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_MOUSE_DIV_X, _mouseDivisorX);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_MOUSE_DIV_Y, _mouseDivisorY);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_SCROLL_MULT_X, _scrollMultiplierX);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_SCROLL_MULT_Y, _scrollMultiplierY);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_SCROLL_DIV_X, _scrollDivisorX);
PS2DictSetNumber(trackpoint, VOODOO_TRACKPOINT_SCROLL_DIV_Y, _scrollDivisorY);

OSSafeReleaseNULL(deadzone);
OSSafeReleaseNULL(buttonCnt);
OSSafeReleaseNULL(multX);
OSSafeReleaseNULL(multY);
OSSafeReleaseNULL(divX);
OSSafeReleaseNULL(divY);
OSSafeReleaseNULL(scrollMultX);
OSSafeReleaseNULL(scrollMultY);
OSSafeReleaseNULL(scrollDivX);
OSSafeReleaseNULL(scrollDivY);
setProperty(VOODOO_TRACKPOINT_KEY, trackpoint);
OSSafeReleaseNULL(trackpoint);
}

Expand Down
8 changes: 8 additions & 0 deletions VoodooPS2Trackpad/VoodooPS2TrackpadCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@

#define TEST_BIT(x, y) ((x >> y) & 0x1)

void inline PS2DictSetNumber(OSDictionary *dict, const char *key, unsigned int num) {
OSNumber *val = OSNumber::withNumber(num, 32);
if (val != nullptr) {
dict->setObject(key, val);
val->release();
}
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// SimpleAverage Class Declaration
//
Expand Down

0 comments on commit db22ab1

Please sign in to comment.