Skip to content

Commit baf81bf

Browse files
committed
Start on an event driver
1 parent d5fbbcf commit baf81bf

File tree

4 files changed

+300
-1
lines changed

4 files changed

+300
-1
lines changed

VoodooI2CGoodix.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
EE80555023C2AFB20038376B /* VoodooI2CGoodixEventDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE80554E23C2AFB20038376B /* VoodooI2CGoodixEventDriver.cpp */; };
11+
EE80555123C2AFB20038376B /* VoodooI2CGoodixEventDriver.hpp in Headers */ = {isa = PBXBuildFile; fileRef = EE80554F23C2AFB20038376B /* VoodooI2CGoodixEventDriver.hpp */; };
1012
F1F613CE2090304000F1B282 /* VoodooI2CGoodixTouchDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F1F613CC2090304000F1B282 /* VoodooI2CGoodixTouchDriver.cpp */; };
1113
F1F613CF2090304000F1B282 /* VoodooI2CGoodixTouchDriver.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F1F613CD2090304000F1B282 /* VoodooI2CGoodixTouchDriver.hpp */; };
1214
/* End PBXBuildFile section */
1315

1416
/* Begin PBXFileReference section */
17+
EE80554E23C2AFB20038376B /* VoodooI2CGoodixEventDriver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = VoodooI2CGoodixEventDriver.cpp; sourceTree = "<group>"; };
18+
EE80554F23C2AFB20038376B /* VoodooI2CGoodixEventDriver.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = VoodooI2CGoodixEventDriver.hpp; sourceTree = "<group>"; };
1519
F1F613BE20902F4C00F1B282 /* VoodooI2CGoodix.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VoodooI2CGoodix.kext; sourceTree = BUILT_PRODUCTS_DIR; };
1620
F1F613C320902F4C00F1B282 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
1721
F1F613CB20902FEE00F1B282 /* goodix.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = goodix.h; sourceTree = "<group>"; };
@@ -53,6 +57,8 @@
5357
F1F613CB20902FEE00F1B282 /* goodix.h */,
5458
F1F613CC2090304000F1B282 /* VoodooI2CGoodixTouchDriver.cpp */,
5559
F1F613CD2090304000F1B282 /* VoodooI2CGoodixTouchDriver.hpp */,
60+
EE80554E23C2AFB20038376B /* VoodooI2CGoodixEventDriver.cpp */,
61+
EE80554F23C2AFB20038376B /* VoodooI2CGoodixEventDriver.hpp */,
5662
);
5763
path = VoodooI2CGoodix;
5864
sourceTree = "<group>";
@@ -64,6 +70,7 @@
6470
isa = PBXHeadersBuildPhase;
6571
buildActionMask = 2147483647;
6672
files = (
73+
EE80555123C2AFB20038376B /* VoodooI2CGoodixEventDriver.hpp in Headers */,
6774
F1F613CF2090304000F1B282 /* VoodooI2CGoodixTouchDriver.hpp in Headers */,
6875
);
6976
runOnlyForDeploymentPostprocessing = 0;
@@ -136,6 +143,7 @@
136143
buildActionMask = 2147483647;
137144
files = (
138145
F1F613CE2090304000F1B282 /* VoodooI2CGoodixTouchDriver.cpp in Sources */,
146+
EE80555023C2AFB20038376B /* VoodooI2CGoodixEventDriver.cpp in Sources */,
139147
);
140148
runOnlyForDeploymentPostprocessing = 0;
141149
};

VoodooI2CGoodix.xcodeproj/xcuserdata/lazd.xcuserdatad/xcschemes/xcschememanagement.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<key>VoodooI2CGoodix.xcscheme_^#shared#^_</key>
88
<dict>
99
<key>orderHint</key>
10-
<integer>5</integer>
10+
<integer>4</integer>
1111
</dict>
1212
</dict>
1313
</dict>
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
//
2+
// VoodooI2CGoodixEventDriver.cpp
3+
// VoodooI2CGoodix
4+
//
5+
// Created by Larry Davis on 1/5/20.
6+
// Copyright © 2020 lazd. All rights reserved.
7+
//
8+
9+
#include "VoodooI2CGoodixEventDriver.hpp"
10+
11+
#include "VoodooI2CGoodixEventDriver.hpp"
12+
#include <IOKit/hid/IOHIDInterface.h>
13+
#include <IOKit/IOLib.h>
14+
15+
#define super IOHIDEventService
16+
OSDefineMetaClassAndStructors(VoodooI2CGoodixEventDriver, IOHIDEventService);
17+
18+
bool VoodooI2CGoodixEventDriver::didTerminate(IOService* provider, IOOptionBits options, bool* defer) {
19+
if (hid_interface)
20+
hid_interface->close(this);
21+
hid_interface = NULL;
22+
23+
return super::didTerminate(provider, options, defer);
24+
}
25+
26+
void VoodooI2CGoodixEventDriver::forwardReport(VoodooI2CMultitouchEvent event, AbsoluteTime timestamp) {
27+
if (multitouch_interface)
28+
multitouch_interface->handleInterruptReport(event, timestamp);
29+
}
30+
31+
const char* VoodooI2CGoodixEventDriver::getProductName() {
32+
return "Goodix HID Device";
33+
}
34+
35+
bool VoodooI2CGoodixEventDriver::handleStart(IOService* provider) {
36+
if(!super::handleStart(provider)) {
37+
return false;
38+
}
39+
40+
hid_interface = OSDynamicCast(IOHIDInterface, provider);
41+
42+
if (!hid_interface)
43+
return false;
44+
45+
name = getProductName();
46+
47+
publishMultitouchInterface();
48+
49+
digitiser.fingers = OSArray::withCapacity(1);
50+
51+
if (!digitiser.fingers)
52+
return false;
53+
54+
digitiser.styluses = OSArray::withCapacity(1);
55+
56+
if (!digitiser.styluses)
57+
return false;
58+
59+
digitiser.transducers = OSArray::withCapacity(1);
60+
61+
if (!digitiser.transducers)
62+
return false;
63+
64+
setDigitizerProperties();
65+
66+
PMinit();
67+
hid_interface->joinPMtree(this);
68+
registerPowerDriver(this, VoodooI2CIOPMPowerStates, kVoodooI2CIOPMNumberPowerStates);
69+
70+
return true;
71+
}
72+
73+
void VoodooI2CGoodixEventDriver::handleStop(IOService* provider) {
74+
OSSafeReleaseNULL(digitiser.transducers);
75+
OSSafeReleaseNULL(digitiser.wrappers);
76+
OSSafeReleaseNULL(digitiser.styluses);
77+
OSSafeReleaseNULL(digitiser.fingers);
78+
79+
OSSafeReleaseNULL(attached_hid_pointer_devices);
80+
81+
if (multitouch_interface) {
82+
multitouch_interface->stop(this);
83+
multitouch_interface->detach(this);
84+
OSSafeReleaseNULL(multitouch_interface);
85+
}
86+
87+
PMstop();
88+
super::handleStop(provider);
89+
}
90+
91+
IOReturn VoodooI2CGoodixEventDriver::publishMultitouchInterface() {
92+
multitouch_interface = OSTypeAlloc(VoodooI2CMultitouchInterface);
93+
94+
if (!multitouch_interface ||
95+
!multitouch_interface->init(NULL) ||
96+
!multitouch_interface->attach(this))
97+
goto exit;
98+
99+
if (!multitouch_interface->start(this)) {
100+
multitouch_interface->detach(this);
101+
goto exit;
102+
}
103+
104+
multitouch_interface->setProperty(kIOHIDVendorIDKey, 0x0416, 32);
105+
multitouch_interface->setProperty(kIOHIDProductIDKey, 0x0416, 32);
106+
107+
// Todo: should this be true?
108+
multitouch_interface->setProperty(kIOHIDDisplayIntegratedKey, kOSBooleanFalse);
109+
110+
multitouch_interface->registerService();
111+
112+
return kIOReturnSuccess;
113+
114+
exit:
115+
OSSafeReleaseNULL(multitouch_interface);
116+
return kIOReturnError;
117+
}
118+
119+
void VoodooI2CGoodixEventDriver::setDigitizerProperties() {
120+
OSDictionary* properties = OSDictionary::withCapacity(4);
121+
122+
if (!properties)
123+
return;
124+
125+
if (!digitiser.transducers)
126+
goto exit;
127+
128+
properties->setObject("Contact Count Element", digitiser.contact_count);
129+
properties->setObject("Input Mode Element", digitiser.input_mode);
130+
properties->setObject("Contact Count Maximum Element", digitiser.contact_count_maximum);
131+
properties->setObject("Button Element", digitiser.button);
132+
properties->setObject("Transducer Count", OSNumber::withNumber(digitiser.transducers->getCount(), 32));
133+
134+
setProperty("Digitizer", properties);
135+
136+
exit:
137+
OSSafeReleaseNULL(properties);
138+
}
139+
140+
IOReturn VoodooI2CGoodixEventDriver::setPowerState(unsigned long whichState, IOService* whatDevice) {
141+
return kIOPMAckImplied;
142+
}
143+
144+
bool VoodooI2CGoodixEventDriver::start(IOService* provider) {
145+
if (!super::start(provider))
146+
return false;
147+
148+
attached_hid_pointer_devices = OSSet::withCapacity(1);
149+
150+
setProperty("VoodooI2CServices Supported", kOSBooleanTrue);
151+
152+
return true;
153+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
//
2+
// VoodooI2CGoodixEventDriver.hpp
3+
// VoodooI2CGoodix
4+
//
5+
// Created by Larry Davis on 1/5/20.
6+
// Copyright © 2020 lazd. All rights reserved.
7+
//
8+
9+
#ifndef VoodooI2CGoodixEventDriver_hpp
10+
#define VoodooI2CGoodixEventDriver_hpp
11+
12+
// hack to prevent IOHIDEventDriver from loading when
13+
// we include IOHIDEventService
14+
15+
#define _IOKIT_HID_IOHIDEVENTDRIVER_H
16+
17+
#include <libkern/OSBase.h>
18+
19+
#include <IOKit/IOLib.h>
20+
#include <IOKit/IOService.h>
21+
22+
#include <IOKit/hidevent/IOHIDEventService.h>
23+
#include <IOKit/hidsystem/IOHIDTypes.h>
24+
25+
#include "../../../Multitouch Support/VoodooI2CDigitiserStylus.hpp"
26+
#include "../../../Multitouch Support/VoodooI2CMultitouchInterface.hpp"
27+
#include "../../../Multitouch Support/MultitouchHelpers.hpp"
28+
29+
#include "../../../Dependencies/helpers.hpp"
30+
31+
/* Implements an HID Event Driver for HID devices that expose a digitiser usage page.
32+
*
33+
* The members of this class are responsible for parsing, processing and interpreting digitiser-related HID objects.
34+
*/
35+
36+
class EXPORT VoodooI2CGoodixEventDriver : public IOHIDEventService {
37+
OSDeclareDefaultStructors(VoodooI2CGoodixEventDriver);
38+
39+
public:
40+
struct {
41+
OSArray* fingers = NULL;
42+
OSArray* styluses = NULL;
43+
44+
OSArray* wrappers = NULL;
45+
OSArray*
46+
transducers= NULL;
47+
48+
// report level elements
49+
50+
IOHIDElement* contact_count;
51+
IOHIDElement* input_mode;
52+
IOHIDElement* button;
53+
54+
// collection level elements
55+
56+
IOHIDElement* contact_count_maximum;
57+
58+
59+
UInt8 current_contact_count = 1;
60+
UInt8 report_count = 1;
61+
UInt8 current_report = 1;
62+
} digitiser;
63+
64+
/* Notification that a provider has been terminated, sent after recursing up the stack, in leaf-to-root order.
65+
* @options The terminated provider of this object.
66+
* @defer If there is pending I/O that requires this object to persist, and the provider is not opened by this object set defer to true and call the IOService::didTerminate() implementation when the I/O completes. Otherwise, leave defer set to its default value of false.
67+
*
68+
* @return *true*
69+
*/
70+
71+
bool didTerminate(IOService* provider, IOOptionBits options, bool* defer);
72+
73+
const char* getProductName();
74+
75+
/* Called during the start routine to set up the HID Event Driver
76+
* @provider The <IOHIDInterface> object which we have matched against.
77+
*
78+
* This function is reponsible for opening a client connection with the <IOHIDInterface> provider and for publishing
79+
* a multitouch interface into the IOService plane.
80+
*
81+
* @return *true* on successful start, *false* otherwise
82+
*/
83+
84+
bool handleStart(IOService* provider);
85+
86+
/* Publishes a <VoodooI2CMultitouchInterface> into the IOService plane
87+
*
88+
* @return *kIOReturnSuccess* on successful publish, *kIOReturnError* otherwise.
89+
*/
90+
91+
IOReturn publishMultitouchInterface();
92+
93+
/* Publishes some miscellaneous properties to the IOService plane
94+
*/
95+
96+
void setDigitizerProperties();
97+
98+
/* Called by the OS in order to notify the driver that the device should change power state
99+
* @whichState The power state the device is expected to enter represented by either
100+
* *kIOPMPowerOn* or *kIOPMPowerOff*
101+
* @whatDevice The power management policy maker
102+
*
103+
* This function exists to be overriden by inherited classes should they need it.
104+
*
105+
* @return *kIOPMAckImplied* on succesful state change, *kIOReturnError* otherwise
106+
*/
107+
108+
virtual IOReturn setPowerState(unsigned long whichState, IOService* whatDevice);
109+
110+
/* Called during the stop routine to terminate the HID Event Driver
111+
* @provider The <IOHIDInterface> object which we have matched against.
112+
*
113+
* This function is reponsible for releasing the resources allocated in <start>
114+
*/
115+
116+
void handleStop(IOService* provider);
117+
118+
/* Implemented to set a certain property
119+
* @provider The <IOHIDInterface> object which we have matched against.
120+
*/
121+
122+
bool start(IOService* provider);
123+
124+
protected:
125+
const char* name;
126+
bool awake = true;
127+
IOHIDInterface* hid_interface;
128+
VoodooI2CMultitouchInterface* multitouch_interface;
129+
130+
virtual void forwardReport(VoodooI2CMultitouchEvent event, AbsoluteTime timestamp);
131+
132+
private:
133+
OSSet* attached_hid_pointer_devices;
134+
};
135+
136+
137+
#endif /* VoodooI2CGoodixEventDriver_hpp */
138+

0 commit comments

Comments
 (0)