Skip to content

Commit 50b24ba

Browse files
committed
fix: apply screen rotation from framebuffer, fixes #6
1 parent 9c3a0c0 commit 50b24ba

File tree

4 files changed

+93
-38
lines changed

4 files changed

+93
-38
lines changed

VoodooI2CGoodix/Info.plist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
<string>1.4</string>
4848
<key>com.apple.iokit.IOHIDFamily</key>
4949
<string>2.0</string>
50+
<key>com.apple.iokit.IOGraphicsFamily</key>
51+
<string>1.0.0b1</string>
5052
<key>com.apple.kpi.iokit</key>
5153
<string>14</string>
5254
<key>com.apple.kpi.libkern</key>

VoodooI2CGoodix/VoodooI2CGoodixEventDriver.cpp

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
// Copyright © 2020 lazd. All rights reserved.
77
//
88

9-
#include "VoodooI2CGoodixEventDriver.hpp"
10-
119
#include "VoodooI2CGoodixEventDriver.hpp"
1210
#include <IOKit/hid/IOHIDInterface.h>
1311
#include <IOKit/IOLib.h>
@@ -23,6 +21,8 @@ void VoodooI2CGoodixEventDriver::dispatchDigitizerEvent(int logicalX, int logica
2321
IOFixed x = ((logicalX * 1.0f) / multitouch_interface->logical_max_x) * 65535;
2422
IOFixed y = ((logicalY * 1.0f) / multitouch_interface->logical_max_y) * 65535;
2523

24+
checkRotation(&x, &y);
25+
2626
// Dispatch the actual event
2727
dispatchDigitizerEventWithTiltOrientation(timestamp, 0, kDigitiserTransducerFinger, 0x1, clickType, x, y);
2828

@@ -66,6 +66,15 @@ void VoodooI2CGoodixEventDriver::fingerLift() {
6666
}
6767

6868
void VoodooI2CGoodixEventDriver::reportTouches(struct Touch touches[], int numTouches) {
69+
if (!active_framebuffer) {
70+
active_framebuffer = getFramebuffer();
71+
}
72+
73+
if (active_framebuffer) {
74+
OSNumber* number = OSDynamicCast(OSNumber, active_framebuffer->getProperty(kIOFBTransformKey));
75+
current_rotation = number->unsigned8BitValue() / 0x10;
76+
}
77+
6978
if (numTouches == 1) {
7079
Touch touch = touches[0];
7180

@@ -111,6 +120,9 @@ void VoodooI2CGoodixEventDriver::reportTouches(struct Touch touches[], int numTo
111120
scheduleLift();
112121
}
113122
else {
123+
// Set rotation for gestures
124+
multitouch_interface->setProperty(kIOFBTransformKey, current_rotation, 8);
125+
114126
// Our finger event is multitouch, so we're not clicking
115127
click_tick = 0;
116128

@@ -168,6 +180,8 @@ bool VoodooI2CGoodixEventDriver::handleStart(IOService* provider) {
168180

169181
timer_source = IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &VoodooI2CGoodixEventDriver::fingerLift));
170182

183+
active_framebuffer = getFramebuffer();
184+
171185
if (!timer_source || work_loop->addEventSource(timer_source) != kIOReturnSuccess) {
172186
IOLog("%s::Could not add timer source to work loop\n", getName());
173187
return false;
@@ -196,6 +210,8 @@ void VoodooI2CGoodixEventDriver::handleStop(IOService* provider) {
196210

197211
OSSafeReleaseNULL(work_loop);
198212

213+
// OSSafeReleaseNULL(active_framebuffer); // Todo: do we need to do this?
214+
199215
super::handleStop(provider);
200216
}
201217

@@ -292,3 +308,47 @@ bool VoodooI2CGoodixEventDriver::start(IOService* provider) {
292308

293309
return true;
294310
}
311+
312+
IOFramebuffer* VoodooI2CGoodixEventDriver::getFramebuffer() {
313+
IODisplay* display = NULL;
314+
IOFramebuffer* framebuffer = NULL;
315+
316+
OSDictionary *match = serviceMatching("IODisplay");
317+
OSIterator *iterator = getMatchingServices(match);
318+
319+
if (iterator) {
320+
display = OSDynamicCast(IODisplay, iterator->getNextObject());
321+
322+
if (display) {
323+
IOLog("%s::Got active display\n", getName());
324+
325+
framebuffer = OSDynamicCast(IOFramebuffer, display->getParentEntry(gIOServicePlane)->getParentEntry(gIOServicePlane));
326+
327+
if (framebuffer) {
328+
IOLog("%s::Got active framebuffer\n", getName());
329+
}
330+
}
331+
332+
OSSafeReleaseNULL(iterator);
333+
}
334+
335+
OSSafeReleaseNULL(match);
336+
337+
return framebuffer;
338+
}
339+
340+
void VoodooI2CGoodixEventDriver::checkRotation(IOFixed* x, IOFixed* y) {
341+
if (active_framebuffer) {
342+
if (current_rotation & kIOFBSwapAxes) {
343+
IOFixed old_x = *x;
344+
*x = *y;
345+
*y = old_x;
346+
}
347+
if (current_rotation & kIOFBInvertX) {
348+
*x = 65535 - *x;
349+
}
350+
if (current_rotation & kIOFBInvertY) {
351+
*y = 65535 - *y;
352+
}
353+
}
354+
}

VoodooI2CGoodix/VoodooI2CGoodixEventDriver.hpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,15 @@
1818

1919
#include <IOKit/IOLib.h>
2020
#include <IOKit/IOService.h>
21+
#include <IOKit/IOWorkLoop.h>
2122
#include <IOKit/IOTimerEventSource.h>
2223

2324
#include <IOKit/hidevent/IOHIDEventService.h>
2425
#include <IOKit/hidsystem/IOHIDTypes.h>
2526

27+
#include <IOKit/graphics/IOFramebuffer.h>
28+
#include <IOKit/graphics/IODisplay.h>
29+
2630
#include "../../../Multitouch Support/VoodooI2CDigitiserStylus.hpp"
2731
#include "../../../Multitouch Support/VoodooI2CMultitouchInterface.hpp"
2832
#include "../../../Multitouch Support/MultitouchHelpers.hpp"
@@ -144,9 +148,24 @@ class EXPORT VoodooI2CGoodixEventDriver : public IOHIDEventService {
144148
*/
145149
void scheduleLift();
146150

147-
private:
151+
/* Get the active framebuffer
152+
*/
153+
IOFramebuffer* getFramebuffer();
154+
155+
/* Rotate coordinates to match current framebuffer's rotation
156+
*
157+
* @x A pointer to the X coordinate
158+
* @y A pointer to the Y coordinate
159+
*/
160+
161+
void checkRotation(IOFixed* x, IOFixed* y);
162+
163+
private:
148164
IOWorkLoop *work_loop;
149165
IOTimerEventSource *timer_source;
166+
IOFramebuffer* active_framebuffer = NULL;
167+
168+
UInt8 current_rotation;
150169

151170
IOFixed last_x = 0;
152171
IOFixed last_y = 0;

VoodooI2CGoodix/VoodooI2CGoodixTouchDriver.cpp

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ struct goodix_ts_data {
2525
bool swapped_x_y;
2626
bool inverted_x;
2727
bool inverted_y;
28-
bool swap_x_y_scale;
29-
bool swapped_x_y_values;
3028
unsigned int max_touch_num;
3129
unsigned int int_trigger_type;
3230
UInt16 id;
@@ -185,7 +183,6 @@ bool VoodooI2CGoodixTouchDriver::start(IOService* provider) {
185183
IOLog("%s::VoodooI2CGoodixTouchDriver has started\n", getName());
186184

187185
// Instantiate the event driver
188-
// Todo: how to properly attach to this service?
189186
event_driver = OSTypeAlloc(VoodooI2CGoodixEventDriver);
190187
if (!event_driver
191188
|| !event_driver->init()
@@ -340,36 +337,17 @@ void VoodooI2CGoodixTouchDriver::goodix_ts_report_touch(UInt8 *coor_data, Touch
340337

341338
// IOLog("%s::raw: %d,%d\n", getName(), input_x, input_y);
342339

343-
// Scale swapping has to happen before everything
344-
if (ts->swap_x_y_scale) {
345-
input_x = (int)(((float)input_x / ts->abs_x_max) * ts->abs_y_max);
346-
input_y = (int)(((float)input_y / ts->abs_y_max) * ts->abs_x_max);
340+
// Inversions have to happen before axis swapping
341+
if (ts->inverted_x)
342+
input_x = ts->abs_x_max - input_x;
343+
if (ts->inverted_y)
344+
input_y = ts->abs_y_max - input_y;
347345

348-
// IOLog("%s::scl: %d,%d\n", getName(), input_x, input_y);
349-
350-
// Inversions have to happen before axis swapping
351-
if (ts->inverted_x)
352-
input_x = ts->abs_y_max - input_x;
353-
if (ts->inverted_y)
354-
input_y = ts->abs_x_max - input_y;
355-
356-
if (ts->inverted_x || ts->inverted_y) {
357-
// IOLog("%s::inv: %d,%d\n", getName(), input_x, input_y);
358-
}
359-
}
360-
else {
361-
// Inversions have to happen before axis swapping
362-
if (ts->inverted_x)
363-
input_x = ts->abs_x_max - input_x;
364-
if (ts->inverted_y)
365-
input_y = ts->abs_y_max - input_y;
366-
367-
if (ts->inverted_x || ts->inverted_y) {
368-
// IOLog("%s::inv: %d,%d\n", getName(), input_x, input_y);
369-
}
346+
if (ts->inverted_x || ts->inverted_y) {
347+
// IOLog("%s::inv: %d,%d\n", getName(), input_x, input_y);
370348
}
371349

372-
if (ts->swapped_x_y || ts->swapped_x_y_values) {
350+
if (ts->swapped_x_y) {
373351
swap(input_x, input_y);
374352
// IOLog("%s::swp: %d,%d\n", getName(), input_x, input_y);
375353
}
@@ -536,19 +514,15 @@ void VoodooI2CGoodixTouchDriver::goodix_read_config() {
536514

537515
IOLog("%s::ts->abs_x_max = %d\n", getName(), ts->abs_x_max);
538516
IOLog("%s::ts->abs_y_max = %d\n", getName(), ts->abs_y_max);
539-
IOLog("%s::ts->int_trigger_type = %d\n", getName(), ts->int_trigger_type);
540517
IOLog("%s::ts->max_touch_num = %d\n", getName(), ts->max_touch_num);
541518
}
542519

543520
IOReturn VoodooI2CGoodixTouchDriver::goodix_configure_dev() {
544521
IOReturn retVal = kIOReturnSuccess;
545522

546-
// Hardcoded values for Chuwi Minibook 8
547523
ts->swapped_x_y = false;
548-
ts->inverted_x = true;
524+
ts->inverted_x = false;
549525
ts->inverted_y = false;
550-
ts->swap_x_y_scale = true;
551-
ts->swapped_x_y_values = true;
552526

553527
goodix_read_config();
554528

0 commit comments

Comments
 (0)