Skip to content

Commit

Permalink
Use Trackpoint logic in VoodooInput (#161)
Browse files Browse the repository at this point in the history
  • Loading branch information
1Revenger1 authored Feb 3, 2023
1 parent 8f03cb1 commit e73d533
Show file tree
Hide file tree
Showing 13 changed files with 140 additions and 198 deletions.
10 changes: 6 additions & 4 deletions VoodooRMI/Functions/F11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ int F11::rmi_f11_get_query_parameters(f11_2d_sensor_queries *sensor_query,

int F11::rmi_f11_initialize()
{
struct Rmi2DSensorData sensorSize;
UInt8 query_offset, buf;
UInt16 query_base_addr, control_base_addr;
UInt16 max_x_pos, max_y_pos;
Expand Down Expand Up @@ -594,8 +595,8 @@ int F11::rmi_f11_initialize()
query_offset += rc;

if (sens_query.has_physical_props) {
x_mm = sens_query.x_sensor_size_mm;
y_mm = sens_query.y_sensor_size_mm;
sensorSize.sizeX = sens_query.x_sensor_size_mm;
sensorSize.sizeY = sens_query.y_sensor_size_mm;
} else {
IOLogError("No size data from Device.");
return -ENODEV;
Expand All @@ -620,8 +621,9 @@ int F11::rmi_f11_initialize()
return rc;
}

max_x = max_x_pos;
max_y = max_y_pos;
sensorSize.maxX = max_x_pos;
sensorSize.maxY = max_y_pos;
setData(sensorSize);

rc = f11_2d_construct_data();
if (rc < 0) {
Expand Down
1 change: 0 additions & 1 deletion VoodooRMI/Functions/F11.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,6 @@ class F11 : public RMITrackpadFunction {
size_t attn_size;
struct f11_2d_sensor_queries sens_query;
struct f11_2d_data data_2d;
struct rmi_2d_sensor_platform_data sensor_pdata;
unsigned long *abs_mask;
unsigned long *rel_mask;

Expand Down
10 changes: 6 additions & 4 deletions VoodooRMI/Functions/F12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ IOReturn F12::config()
int F12::rmi_f12_read_sensor_tuning()
{
const rmi_register_desc_item *item;
struct Rmi2DSensorData sensorSize;
int ret;
int offset;
UInt8 buf[15];
Expand Down Expand Up @@ -219,8 +220,8 @@ int F12::rmi_f12_read_sensor_tuning()

offset = 0;
if (rmi_register_desc_has_subpacket(item, 0)) {
max_x = (buf[offset + 1] << 8) | buf[offset];
max_y = (buf[offset + 3] << 8) | buf[offset + 2];
sensorSize.maxX = (buf[offset + 1] << 8) | buf[offset];
sensorSize.maxY = (buf[offset + 3] << 8) | buf[offset + 2];
offset += 4;
} else {
IOLogError("F12 - No size register");
Expand Down Expand Up @@ -259,8 +260,9 @@ int F12::rmi_f12_read_sensor_tuning()
if (rmi_register_desc_has_subpacket(item, 4))
offset += 1;

x_mm = (pitch_x * rx_receivers) >> 12;
y_mm = (pitch_y * tx_receivers) >> 12;
sensorSize.sizeX = (pitch_x * rx_receivers) >> 12;
sensorSize.sizeY = (pitch_y * tx_receivers) >> 12;
setData(sensorSize);

return 0;
}
Expand Down
1 change: 0 additions & 1 deletion VoodooRMI/Functions/F12.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ class F12 : public RMITrackpadFunction {
UInt8 *data_pkt;
size_t pkt_size;
size_t attn_size;
struct rmi_2d_sensor_platform_data sensor_pdata;
bool has_dribble;

rmi_register_descriptor query_reg_desc;
Expand Down
8 changes: 6 additions & 2 deletions VoodooRMI/Functions/Input/RMIFunction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,12 @@ class RMIFunction : public IOService {
protected:

// Useful functions to talk to RMI4 devicce
inline const IOService *getVoodooInput() const { return bus->getVoodooInput(); }
inline void setVoodooInput(IOService *service) { bus->setVoodooInput(service); }
inline void sendVoodooInputPacket(UInt32 msg, void *packet) {
IOService *vi = bus->getVoodooInput();
if (vi != nullptr) {
vi->message(msg, bus, packet);
}
}
inline const RmiGpioData &getGPIOData() const { return bus->getGPIOData(); }
inline const RmiConfiguration &getConfiguration() const { return bus->getConfiguration(); }
inline IOReturn readByte(UInt16 addr, UInt8 *buf) const { return bus->read(addr, buf); }
Expand Down
8 changes: 3 additions & 5 deletions VoodooRMI/Functions/Input/RMIGPIOFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ void RMIGPIOFunction::attention()

void RMIGPIOFunction::reportButton()
{
RelativePointerEvent relativeEvent {};
TrackpointReport relativeEvent {};
unsigned int mask, trackpointBtns = 0, btns = 0;
unsigned int reg_num, bit_num;
UInt16 key_code;
Expand Down Expand Up @@ -149,16 +149,14 @@ void RMIGPIOFunction::reportButton()
}
}

const IOService *voodooInputInstance = getVoodooInput();
if (numButtons > 1 && voodooInputInstance) {
if (numButtons > 1) {
AbsoluteTime timestamp;
clock_get_uptime(&timestamp);

relativeEvent.dx = relativeEvent.dy = 0;
relativeEvent.buttons = btns;
relativeEvent.timestamp = timestamp;

messageClient(kIOMessageVoodooTrackpointRelativePointer, const_cast<IOService *>(voodooInputInstance), &relativeEvent, sizeof(RelativePointerEvent));
sendVoodooInputPacket(kIOMessageVoodooTrackpointRelativePointer, &relativeEvent);
}

if (hasTrackpointButtons) {
Expand Down
55 changes: 17 additions & 38 deletions VoodooRMI/Functions/Input/RMITrackpadFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ static void fillZone (RMI2DSensorZone *zone, int min_x, int min_y, int max_x, in
zone->y_max = max_y;
}

void RMITrackpadFunction::setData(const Rmi2DSensorData &data) {
this->data = data;
}

const Rmi2DSensorData &RMITrackpadFunction::getData() const {
return data;
}

bool RMITrackpadFunction::start(IOService *provider)
{
memset(freeFingerTypes, true, sizeof(freeFingerTypes));
Expand All @@ -39,9 +47,9 @@ bool RMITrackpadFunction::start(IOService *provider)
}

const RmiConfiguration &conf = getConfiguration();
const int palmRejectWidth = max_x * cfgToPercent(conf.palmRejectionWidth);
const int palmRejectHeight = max_y * cfgToPercent(conf.palmRejectionHeight);
const int trackpointRejectHeight = max_y * cfgToPercent(conf.palmRejectionHeightTrackpoint);
const int palmRejectWidth = data.maxX * cfgToPercent(conf.palmRejectionWidth);
const int palmRejectHeight = data.maxY * cfgToPercent(conf.palmRejectionHeight);
const int trackpointRejectHeight = data.maxY * cfgToPercent(conf.palmRejectionHeightTrackpoint);

/*
* Calculate reject zones.
Expand All @@ -56,24 +64,16 @@ bool RMITrackpadFunction::start(IOService *provider)

// Top right
fillZone(&rejectZones[1],
max_x - palmRejectWidth, 0,
max_x, palmRejectHeight);
data.maxX - palmRejectWidth, 0,
data.maxX, palmRejectHeight);

// Top band for trackpoint and buttons
fillZone(&rejectZones[2],
0, 0,
max_x, trackpointRejectHeight);

setProperty(VOODOO_INPUT_LOGICAL_MAX_X_KEY, max_x, 16);
setProperty(VOODOO_INPUT_LOGICAL_MAX_Y_KEY, max_y, 16);
// Need to be in 0.01mm units
setProperty(VOODOO_INPUT_PHYSICAL_MAX_X_KEY, x_mm * 100, 16);
setProperty(VOODOO_INPUT_PHYSICAL_MAX_Y_KEY, y_mm * 100, 16);
setProperty(VOODOO_INPUT_TRANSFORM_KEY, 0ull, 32);
data.maxX, trackpointRejectHeight);

// VoodooPS2 keyboard notifs
setProperty("RM,deliverNotifications", kOSBooleanTrue);
setProperty("VoodooInputSupported", kOSBooleanTrue);

for (int i = 0; i < VOODOO_INPUT_MAX_TRANSDUCERS; i++) {
auto& transducer = inputEvent.transducers[i];
Expand All @@ -85,27 +85,6 @@ bool RMITrackpadFunction::start(IOService *provider)
return super::start(provider);
}

bool RMITrackpadFunction::handleOpen(IOService *forClient, IOOptionBits options, void *arg)
{
if (forClient && forClient->getProperty(VOODOO_INPUT_IDENTIFIER)
&& super::handleOpen(forClient, options, arg)) {
voodooInputInstance = forClient;
setVoodooInput(voodooInputInstance);
return true;
}

return false;
}

void RMITrackpadFunction::handleClose(IOService *forClient, IOOptionBits options)
{
if (forClient && forClient == voodooInputInstance) {
setVoodooInput(voodooInputInstance);
voodooInputInstance = nullptr;
super::handleClose(forClient, options);
}
}

IOReturn RMITrackpadFunction::message(UInt32 type, IOService *provider, void *argument)
{
switch (type)
Expand Down Expand Up @@ -139,7 +118,7 @@ IOReturn RMITrackpadFunction::message(UInt32 type, IOService *provider, void *ar

bool RMITrackpadFunction::shouldDiscardReport(AbsoluteTime timestamp)
{
return !trackpadEnable || voodooInputInstance == nullptr;
return !trackpadEnable;
}

// Returns zone that finger is in (or 0 if not in a zone)
Expand Down Expand Up @@ -206,7 +185,7 @@ void RMITrackpadFunction::handleReport(RMI2DSensorReport *report)
transducer.timestamp = report->timestamp;

transducer.currentCoordinates.x = obj.x;
transducer.currentCoordinates.y = max_y - obj.y;
transducer.currentCoordinates.y = data.maxY - obj.y;

int deltaWidth = abs(obj.wx - obj.wy);

Expand Down Expand Up @@ -305,7 +284,7 @@ void RMITrackpadFunction::handleReport(RMI2DSensorReport *report)
inputEvent.contact_count = reportIdx;
inputEvent.timestamp = report->timestamp;

messageClient(kIOMessageVoodooInputMessage, voodooInputInstance, &inputEvent, sizeof(VoodooInputEvent));
sendVoodooInputPacket(kIOMessageVoodooInputMessage, &inputEvent);
for (int i = 0; i < VOODOO_INPUT_MAX_TRANSDUCERS; i++) {
inputEvent.transducers[i].isTransducerActive = false;
}
Expand Down
49 changes: 9 additions & 40 deletions VoodooRMI/Functions/Input/RMITrackpadFunction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,36 +35,11 @@ enum finger_state {
RMI_FINGER_FORCE_TOUCH, // Force touch
};

/**
* struct rmi_2d_sensor_data - overrides defaults for a 2D sensor.
* @axis_align - provides axis alignment overrides (see above).
* @sensor_type - Forces the driver to treat the sensor as an indirect
* pointing device (trackpad) rather than a direct pointing device
* (touchscreen). This is useful when F11_2D_QUERY14 register is not
* available.
* @disable_report_mask - Force data to not be reported even if it is supported
* by the firware.
* @topbuttonpad - Used with the "5 buttons trackpads" found on the Lenovo 40
* series
* @kernel_tracking - most moderns RMI f11 firmwares implement Multifinger
* Type B protocol. However, there are some corner cases where the user
* triggers some jumps by tapping with two fingers on the trackpad.
* Use this setting and dmax to filter out these jumps.
* Also, when using an old sensor using MF Type A behavior, set to true to
* report an actual MT protocol B.
* @dmax - the maximum distance (in sensor units) the kernel tracking allows two
* distincts fingers to be considered the same.
*/
struct rmi_2d_sensor_platform_data {
int x_mm;
int y_mm;
int disable_report_mask;
UInt16 rezero_wait;
bool topbuttonpad;
bool kernel_tracking;
int dmax;
int dribble;
int palm_detect;
struct Rmi2DSensorData {
UInt16 sizeX;
UInt16 sizeY;
UInt16 maxX;
UInt16 maxY;
};

struct rmi_2d_sensor_abs_object {
Expand Down Expand Up @@ -102,29 +77,23 @@ class RMITrackpadFunction : public RMIFunction {
OSDeclareDefaultStructors(RMITrackpadFunction)
public:
bool start(IOService *provider) override;
bool handleOpen(IOService *forClient, IOOptionBits options, void *arg) override;
void handleClose(IOService *forClient, IOOptionBits options) override;
IOReturn message(UInt32 type, IOService *provider, void *argument = 0) override;

protected:
UInt16 min_x{0};
UInt16 min_y{0};
UInt16 max_x;
UInt16 max_y;
UInt8 x_mm;
UInt8 y_mm;
const Rmi2DSensorData &getData() const;

protected:
UInt8 report_abs {0};
UInt8 report_rel {0};

UInt8 nbr_fingers;
IOService *voodooInputInstance {nullptr};

void handleReport(RMI2DSensorReport *report);
bool shouldDiscardReport(AbsoluteTime timestamp);
void setData(const Rmi2DSensorData &data);
private:
VoodooInputEvent inputEvent {};
RMI2DSensorZone rejectZones[3];
Rmi2DSensorData data;

bool freeFingerTypes[kMT2FingerTypeCount];
finger_state fingerState[MAX_FINGERS];
Expand Down
Loading

0 comments on commit e73d533

Please sign in to comment.