├── .github
└── workflows
│ └── main.yml
├── .gitignore
├── Changelog.md
├── Docs
├── ACPI
│ ├── SSDT-AlternateSwipes.dsl
│ ├── SSDT-DisableDeepSleep.dsl
│ ├── SSDT-DisableElanWakeDelay.dsl
│ ├── SSDT-DisableTrackpadProbe.dsl
│ ├── SSDT-HP-FixLidSleep.dsl
│ ├── SSDT-KEY-DELL-WN09.dsl
│ ├── SSDT-NumLockOnAtBoot.dsl
│ ├── SSDT-NumLockSupport.dsl
│ ├── SSDT-PrtSc-Remap.dsl
│ ├── SSDT-Swap-CommandOption.dsl
│ ├── SSDT-Swap-LeftControlCapsLock.dsl
│ ├── SSDT-Swap-LeftControlCommand.dsl
│ ├── SSDT-Thinkpad_Clickpad.dsl
│ └── SSDT-Thinkpad_Trackpad.dsl
├── SynapticsRevB.pdf
├── force_touch.png
└── voodoops2ioio.sh
├── LICENSE.md
├── README.md
├── VoodooPS2Controller.xcodeproj
├── project.pbxproj
└── xcshareddata
│ └── xcschemes
│ ├── VoodooPS2Controller.xcscheme
│ ├── VoodooPS2Keyboard.xcscheme
│ ├── VoodooPS2Mouse.xcscheme
│ └── VoodooPS2Trackpad.xcscheme
├── VoodooPS2Controller
├── AppleACPIPS2Nub.cpp
├── AppleACPIPS2Nub.h
├── ApplePS2Device.cpp
├── ApplePS2Device.h
├── ApplePS2KeyboardDevice.cpp
├── ApplePS2KeyboardDevice.h
├── ApplePS2MouseDevice.cpp
├── ApplePS2MouseDevice.h
├── VoodooPS2Controller-Info.plist
├── VoodooPS2Controller.cpp
├── VoodooPS2Controller.h
└── en.lproj
│ └── InfoPlist.strings
├── VoodooPS2Keyboard
├── ApplePS2ToADBMap.h
├── VoodooPS2Keyboard-Breakless-Info.plist
├── VoodooPS2Keyboard-Info.plist
├── VoodooPS2Keyboard-RemapFN-Info.plist
├── VoodooPS2Keyboard.cpp
├── VoodooPS2Keyboard.h
└── en.lproj
│ └── InfoPlist.strings
├── VoodooPS2Mouse
├── VoodooPS2Mouse-Info.plist
├── VoodooPS2Mouse.cpp
├── VoodooPS2Mouse.h
└── en.lproj
│ └── InfoPlist.strings
└── VoodooPS2Trackpad
├── VoodooPS2ALPSGlidePoint.cpp
├── VoodooPS2ALPSGlidePoint.h
├── VoodooPS2Elan.cpp
├── VoodooPS2Elan.h
├── VoodooPS2SMBusDevice.cpp
├── VoodooPS2SMBusDevice.h
├── VoodooPS2SentelicFSP.cpp
├── VoodooPS2SentelicFSP.h
├── VoodooPS2SynapticsTouchPad.cpp
├── VoodooPS2SynapticsTouchPad.h
├── VoodooPS2Trackpad-Info.plist
├── VoodooPS2TrackpadCommon.h
└── en.lproj
└── InfoPlist.strings
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | pull_request:
6 | workflow_dispatch:
7 | release:
8 | types: [published]
9 |
10 | env:
11 | PROJECT_TYPE: KEXT
12 |
13 | jobs:
14 | build:
15 | name: Build
16 | runs-on: macos-latest
17 | env:
18 | JOB_TYPE: BUILD
19 | steps:
20 | - uses: actions/checkout@v3
21 | - uses: actions/checkout@v3
22 | with:
23 | repository: acidanthera/MacKernelSDK
24 | path: MacKernelSDK
25 | - name: CI Bootstrap
26 | run: |
27 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1
28 | - name: VoodooInput Bootstrap
29 | run: |
30 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/VoodooInput/master/VoodooInput/Scripts/bootstrap.sh) && eval "$src" || exit 1
31 |
32 | - run: xcodebuild -jobs 1 -configuration Debug
33 | - run: xcodebuild -jobs 1 -configuration Release
34 |
35 | - name: Upload to Artifacts
36 | uses: actions/upload-artifact@v3
37 | with:
38 | name: Artifacts
39 | path: build/*/*/*.zip
40 | - name: Upload to Release
41 | if: github.event_name == 'release'
42 | uses: svenstaro/upload-release-action@e74ff71f7d8a4c4745b560a485cc5fdb9b5b999d
43 | with:
44 | repo_token: ${{ secrets.GITHUB_TOKEN }}
45 | file: build/*/*/*.zip
46 | tag: ${{ github.ref }}
47 | file_glob: true
48 |
49 | analyze-clang:
50 | name: Analyze Clang
51 | runs-on: macos-latest
52 | env:
53 | JOB_TYPE: ANALYZE
54 | steps:
55 | - uses: actions/checkout@v3
56 | - uses: actions/checkout@v3
57 | with:
58 | repository: acidanthera/MacKernelSDK
59 | path: MacKernelSDK
60 | - name: CI Bootstrap
61 | run: |
62 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1
63 | - name: VoodooInput Bootstrap
64 | run: |
65 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/VoodooInput/master/VoodooInput/Scripts/bootstrap.sh) && eval "$src" || exit 1
66 |
67 | - run: xcodebuild analyze -quiet -scheme VoodooPS2Controller -configuration Debug CLANG_ANALYZER_OUTPUT=plist-html CLANG_ANALYZER_OUTPUT_DIR="$(pwd)/clang-analyze" && [ "$(find clang-analyze -name "*.html")" = "" ]
68 | - run: xcodebuild analyze -quiet -scheme VoodooPS2Controller -configuration Release CLANG_ANALYZER_OUTPUT=plist-html CLANG_ANALYZER_OUTPUT_DIR="$(pwd)/clang-analyze" && [ "$(find clang-analyze -name "*.html")" = "" ]
69 |
70 | analyze-coverity:
71 | name: Analyze Coverity
72 | runs-on: macos-latest
73 | env:
74 | JOB_TYPE: COVERITY
75 | if: github.repository_owner == 'acidanthera' && github.event_name != 'pull_request'
76 | steps:
77 | - uses: actions/checkout@v3
78 | - uses: actions/checkout@v3
79 | with:
80 | repository: acidanthera/MacKernelSDK
81 | path: MacKernelSDK
82 | - name: CI Bootstrap
83 | run: |
84 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1
85 | - name: Run Coverity
86 | run: |
87 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/coverity/covstrap.sh) && eval "$src" || exit 1
88 | env:
89 | COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
90 | COVERITY_SCAN_EMAIL: ${{ secrets.COVERITY_SCAN_EMAIL }}
91 | COVERITY_BUILD_COMMAND: xcodebuild -configuration Release
92 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | Build
2 | DerivedData
3 | Distribute
4 | *.xccheckout
5 | .DS_Store
6 | xcuserdata
7 | xcshareddata
8 | project.xcworkspace
9 | VoodooInput
10 | /MacKernelSDK
11 |
--------------------------------------------------------------------------------
/Changelog.md:
--------------------------------------------------------------------------------
1 | VoodooPS2 Changelog
2 | ============================
3 | #### v2.3.7
4 | - Fixed multiple PS2/SMBus devices attaching
5 | - Fixed eratic pointer in bootpicker by disabling SMBus/PS2 devices on shutdown
6 |
7 | #### v2.3.6
8 | - Lowered macOS requirements to 10.10
9 | - Added PS/2 stub driver for better VoodooRMI compatibility
10 | - Removed old external reset interface originally used by VoodooRMI
11 |
12 | #### v2.3.5
13 | - Removed actAsTrackpad and related logic
14 | - Fix Trackpoints connected to Elan Touchpads
15 | - Use VoodooInput Trackpoint logic for Elan Touchpads
16 |
17 | #### v2.3.4
18 | - Fixed device count detection when `ps2rst=0` is set
19 | - Fixed handleClose not being called by VoodooInput
20 |
21 | #### v2.3.3
22 | - Fixed rapidly opening pages in browsers while scrolling with the trackpoint
23 | - Fixed buttons on various trackpads (especially those without trackpoints attached)
24 | - Fixed DynamicEWMode problem on Lenovo ThinkPad Laptops (acidanthera/bugtracker#890)
25 |
26 | #### v2.3.2
27 | - Added `ps2kbdonly=1` argument not to disable touchpad line on reboot, thx @Kethen
28 |
29 | #### v2.3.1
30 | - Fixed disabled keyboard after reboot
31 |
32 | #### v2.3.0
33 | - Fixed variable shadowing
34 |
35 | #### v2.2.9
36 | - Improved stability of ALPS touchpads
37 | - V8 touchpads can pass all four fingers to VoodooInput natively
38 | - Fixed unpressing during 3 fingers gesture on ALPS V7
39 | - Use VoodooTrackpoint for trackstick and non-MT ALPS touchpads
40 |
41 | #### v2.2.8
42 | - Added ALPS touchpad support
43 | - Fixed ELAN trackpoint scrolling in the wrong direction
44 |
45 | #### v2.2.7
46 | - Fixed kernel panic after S3
47 |
48 | #### v2.2.6
49 | - Fixed some touchpads not waking after S3
50 |
51 | #### v2.2.5
52 | - Added support for touchpads with multiplexors
53 |
54 | #### v2.2.4
55 | - Fixed incorrect command gate initialization causing panics
56 |
57 | #### v2.2.3
58 | - Added `DisableDeepSleep` to workaround ACPI S3 wakes on some Synaptics touchpads
59 |
60 | #### v2.2.2
61 | - Added NumLockSupport & NumLockOnAtBoot
62 |
63 | #### v2.2.1
64 | - Fix issue with registering of services matched by property name "RM,deliverNotifications". It solves issue with broadcasting timestamp for the last pressed key and handling of QuietTimeAfterTyping [see bug #1415](https://github.com/acidanthera/bugtracker/issues/1415)
65 |
66 | #### v2.2.0
67 | - Added VoodooRmi compatibility to allow external touchpad resets
68 |
69 | #### v2.1.9
70 | - Disabled PrntScr remap by default, see `SSDT-PrtSc-Remap.dsl` for example to re-enable it
71 | - Disabled Command and Option remap by default, see `SSDT-Swap-CommandOption.dsl` for example to re-enable it
72 |
73 | #### v2.1.8
74 | - Added support for receiving input form other kexts
75 | - Fixed dynamic coordinate refresh for ELAN v3 touchpads
76 |
77 | #### v2.1.7
78 | - Initial MacKernelSDK and Xcode 12 compatibility
79 | - Added support for select ELAN touchpads by BAndysc and hieplpvip
80 | - Added constants for 11.0 support
81 |
82 | #### v2.1.6
83 | - Upgraded to VoodooInput 1.0.7
84 | - Fixed swiping desktops when holding a dragged item by improving thumb detection
85 | - Fixed keyboard timeout error on some laptop configurations
86 | - Fix Command key being pressed after disabling the keyboard and trackpad with Command-PrtScr key combo
87 | - Added a message to allow other kexts to disable the keyboard
88 |
89 | #### v2.1.5
90 | - Upgraded to VoodooInput 1.0.6
91 | - Added logo + print scr hotkey to disable trackpad
92 |
93 | #### v2.1.4
94 | - Upgraded to VoodooInput 1.0.5
95 | - Improved Smart Zoom and four finger gestures
96 | - Enabled Extended W mode on all trackpads that support it
97 | - Added ability for one special key to block trackpad longer than other keys
98 | - Added a new Force Touch emulation mode
99 |
100 | #### v2.1.3
101 | - Added `ps2rst=0` boot-arg for select CFL laptop compatibility
102 | - Added compatibility with VoodooInput 1.0.4
103 | - VoodooInput is now bundled with VoodooPS2
104 |
105 | #### v2.1.2
106 | - Fixed initialisation race conditions causing kernel panics
107 |
108 | #### v2.1.1
109 | - Fixed kext unloading causing kernel panics
110 | - Fixed Caps Lock LED issues (thx @Goshin)
111 |
112 | #### v2.1.0
113 | - Improved reliability of three-finger dragging
114 | - Improved reliability of finger renumbering algorithm
115 | - Support for four-finger swipes
116 | - Experimental support for four-finger pinch and spread gestures (very unstable)
117 | - Magic Trackpad 2 simulation moved to VoodooInput project
118 |
119 | #### v2.0.4
120 | - Patched CapsLock workaround for Mojave
121 |
122 | #### v2.0.3
123 | - Use touchpad sleep mode during mainboard sleep
124 | - Improve physical and trackpad button support
125 |
126 | #### v2.0.2
127 | - Unified release archive names
128 | - Initial workaround to rare kernel panics
129 | - Rebranding and conflict resolution with other drivers
130 | - Improve reliability of edge swipe gestures
131 | - Support macOS 10.11 to 10.15 beta
132 | - Support Xcode 11 beta
133 | - Support clicking with multiple fingers
134 | - Fix bugs in finger renumbering algorithm
135 | - Ignore hovering above the touchpad
136 | - \[Temporary\] Support overriding touchpad dimensions for old touchpads that don't report minimum coordinates
137 |
138 | Change of earlier versions may be tracked in [commits](https://github.com/acidanthera/VoodooPS2/commits/master) and [releases](https://github.com/acidanthera/VoodooPS2/releases).
139 |
--------------------------------------------------------------------------------
/Docs/ACPI/SSDT-AlternateSwipes.dsl:
--------------------------------------------------------------------------------
1 | // This sample shows how to remap the the default swipes to Option+Arrows,
2 | // instead of the Ctrl+Option+Arrows
3 | DefinitionBlock ("", "SSDT", 2, "ACDT", "ps2", 0)
4 | {
5 | External (_SB_.PCI0.LPCB.PS2K, DeviceObj)
6 |
7 | Name(_SB.PCI0.LPCB.PS2K.RMCF, Package()
8 | {
9 | "Keyboard", Package()
10 | {
11 | "ActionSwipeUp", "37 d, 7e d, 7e u, 37 u",
12 | "ActionSwipeDown", "37 d, 7d d, 7d u, 37 u",
13 | "ActionSwipeLeft", "37 d, 7b d, 7b u, 37 u",
14 | "ActionSwipeRight", "37 d, 7c d, 7c u, 37 u",
15 | },
16 | })
17 | }
18 | //EOF
19 |
--------------------------------------------------------------------------------
/Docs/ACPI/SSDT-DisableDeepSleep.dsl:
--------------------------------------------------------------------------------
1 | // For computers with Synaptics touchpad that wake immediately after
2 | // going to sleep deeper touchpad sleep can be disabled.
3 | //
4 | // This will cause the touchpad to consume more power in ACPI S3.
5 | DefinitionBlock("", "SSDT", 2, "ACDT", "ps2", 0)
6 | {
7 | External (_SB_.PCI0.LPCB.PS2K, DeviceObj)
8 |
9 | Name(_SB.PCI0.LPCB.PS2K.RMCF, Package()
10 | {
11 | "Synaptics TouchPad", Package()
12 | {
13 | "DisableDeepSleep", ">y",
14 | }
15 | })
16 | }
17 | //EOF
18 |
--------------------------------------------------------------------------------
/Docs/ACPI/SSDT-DisableElanWakeDelay.dsl:
--------------------------------------------------------------------------------
1 | // For some computers wake delay needs to be shorter
2 | // for ELAN touchpad to work after wakeup.
3 |
4 | DefinitionBlock("", "SSDT", 2, "ACDT", "ps2", 0)
5 | {
6 | External (_SB_.PCI0.LPCB.PS2K, DeviceObj)
7 |
8 | Name(_SB.PCI0.LPCB.PS2K.RMCF, Package()
9 | {
10 | "Elantech TouchPad", Package()
11 | {
12 | "WakeDelay", 0,
13 | },
14 | })
15 | }
16 | //EOF
17 |
--------------------------------------------------------------------------------
/Docs/ACPI/SSDT-DisableTrackpadProbe.dsl:
--------------------------------------------------------------------------------
1 | // For computers that either have no trackpad (eg. desktop with PS2 mouse)
2 | // or laptops without any support by VoodooPS2Trackpad.kext, you can disable
3 | // each of the trackpad drivers, such that they don't probe.
4 | //
5 | // This can improve the reliability of VoodooPS2Mouse.kext and is more efficient as well.
6 | DefinitionBlock("", "SSDT", 2, "ACDT", "ps2", 0)
7 | {
8 | External (_SB_.PCI0.LPCB.PS2K, DeviceObj)
9 |
10 | Name(_SB.PCI0.LPCB.PS2K.RMCF, Package()
11 | {
12 | "Synaptics TouchPad", Package()
13 | {
14 | "DisableDevice", ">y",
15 | },
16 | "ALPS GlidePoint", Package()
17 | {
18 | "DisableDevice", ">y",
19 | },
20 | "Sentelic FSP", Package()
21 | {
22 | "DisableDevice", ">y",
23 | },
24 | })
25 | }
26 | //EOF
27 |
--------------------------------------------------------------------------------
/Docs/ACPI/SSDT-HP-FixLidSleep.dsl:
--------------------------------------------------------------------------------
1 | // SSDT-HP-FixLidSleep.dsl
2 | // Fix for LID sleep on certain HP computers.
3 | // Make sure you verify _SB.PCI0.LPCB.PS2K ACPI path.
4 | DefinitionBlock ("", "SSDT", 2, "ACDT", "ps2", 0)
5 | {
6 | External (_SB_.PCI0.LPCB.PS2K, DeviceObj)
7 |
8 | Name(_SB.PCI0.LPCB.PS2K.RMCF, Package()
9 | {
10 | "Keyboard", Package()
11 | {
12 | "Custom PS2 Map", Package()
13 | {
14 | Package(){},
15 | "e005=0", // nullify ps2 code 'e0 05' to prevent keygen at lid close
16 | },
17 | },
18 | })
19 | }
20 | //EOF
21 |
--------------------------------------------------------------------------------
/Docs/ACPI/SSDT-KEY-DELL-WN09.dsl:
--------------------------------------------------------------------------------
1 | // Fix for Dell breakless PS2 keys
2 | // This SSDT selects the Dell profile in the Info.plist for VoodooPS2Keyboard.kext
3 |
4 | // Note: the path to your ACPI keyboard object must match as specified in the SSDT
5 | // This example assumes _SB.PCI0.LPCB.PS2K
6 | // Other common paths are _SB.PCI0.LPCB.KBC, _SB.PCI0.LPC.KBD, etc.
7 |
8 | DefinitionBlock ("", "SSDT", 2, "ACDT", "ps2dell", 0)
9 | {
10 | External (_SB_.PCI0.LPCB.PS2K, DeviceObj)
11 |
12 | // Select Dell specific keyboard map in VoodooPS2Keyboard.kext
13 | Method(_SB.PCI0.LPCB.PS2K._DSM, 4)
14 | {
15 | If (!Arg2) { Return (Buffer() { 0x03 } ) }
16 | Return (Package()
17 | {
18 | "RM,oem-id", "DELL",
19 | "RM,oem-table-id", "WN09",
20 | })
21 | }
22 | }
23 | // EOF
24 |
--------------------------------------------------------------------------------
/Docs/ACPI/SSDT-NumLockOnAtBoot.dsl:
--------------------------------------------------------------------------------
1 | // Set NumLock state to ON at Bootup
2 |
3 | DefinitionBlock ("", "SSDT", 2, "ACDT", "ps2", 0)
4 | {
5 | External (_SB_.PCI0.LPCB.PS2K, DeviceObj)
6 |
7 | Name(_SB.PCI0.LPCB.PS2K.RMCF, Package()
8 | {
9 | "Keyboard", Package()
10 | {
11 | "NumLockOnAtBoot", ">y",
12 | },
13 | })
14 | }
15 | //EOF
16 |
--------------------------------------------------------------------------------
/Docs/ACPI/SSDT-NumLockSupport.dsl:
--------------------------------------------------------------------------------
1 | // Add Support for Num Lock key
2 | // By Default Voodoo maps Num Lock to Clear key because of the following
3 | // 1) On USB keyboards Num Lock is translated to the Clear key
4 | // 2) On Apple keyboards there is no Num Lock key
5 |
6 | DefinitionBlock ("", "SSDT", 2, "ACDT", "ps2", 0)
7 | {
8 | External (_SB_.PCI0.LPCB.PS2K, DeviceObj)
9 |
10 | Name(_SB.PCI0.LPCB.PS2K.RMCF, Package()
11 | {
12 | "Keyboard", Package()
13 | {
14 | "NumLockSupport", ">y",
15 | },
16 | })
17 | }
18 | //EOF
19 |
--------------------------------------------------------------------------------
/Docs/ACPI/SSDT-PrtSc-Remap.dsl:
--------------------------------------------------------------------------------
1 | // Remap PrntScr to disable touchpad/keyboard
2 | // Supported Voodoo PrntScr Key combinations:
3 |
4 | // PrntScr Enable/Disable touchpad
5 | // Windows+PrntScr Enable/Disable touchpad+keyboard
6 | // Ctrl+Alt+PrntScr Reset and enable touchpad
7 | // Shift+PrntScr Send SysRq scancode to the kernel
8 |
9 | DefinitionBlock ("", "SSDT", 2, "ACDT", "ps2", 0)
10 | {
11 | External (_SB_.PCI0.LPCB.PS2K, DeviceObj)
12 |
13 | Name(_SB.PCI0.LPCB.PS2K.RMCF, Package()
14 | {
15 | "Keyboard", Package()
16 | {
17 | "RemapPrntScr", ">y",
18 | },
19 | })
20 | }
21 | //EOF
22 |
--------------------------------------------------------------------------------
/Docs/ACPI/SSDT-Swap-CommandOption.dsl:
--------------------------------------------------------------------------------
1 | // This sample shows how to remap the Command and Option.
2 | DefinitionBlock ("", "SSDT", 2, "ACDT", "ps2", 0)
3 | {
4 | External (_SB_.PCI0.LPCB.PS2K, DeviceObj)
5 |
6 | Name(_SB.PCI0.LPCB.PS2K.RMCF, Package()
7 | {
8 | "Keyboard", Package()
9 | {
10 | "Swap command and option", ">y",
11 | }
12 | })
13 | }
14 | //EOF
15 |
--------------------------------------------------------------------------------
/Docs/ACPI/SSDT-Swap-LeftControlCapsLock.dsl:
--------------------------------------------------------------------------------
1 | // This sample shows how to remap the Left Control to CapsLock,
2 | // and CapsLock to Left Control.
3 | // Be sure to specify the correct path to your device, followed by ".RMCF"
4 | // For example, a Lenovo x1 Carbon 5th Gen would be "_SB.PCI0.LPCB.KBD.RMCF"
5 | DefinitionBlock ("", "SSDT", 2, "ACDT", "ps2", 0)
6 | {
7 | External (_SB_.PCI0.LPCB.PS2K, DeviceObj)
8 |
9 | Name(_SB.PCI0.LPCB.PS2K.RMCF, Package()
10 | {
11 | "Keyboard", Package()
12 | {
13 | "Custom ADB Map", Package()
14 | {
15 | Package(){},
16 | "3a=3b", // 3a is PS2 for capslock, 3b is ADB for left control (normal map is 3a=39)
17 | "1d=39", // 1d is PS2 for left control, 39 is ADB for caps lock (normal map is 1d=3b)
18 | },
19 | },
20 | })
21 | }
22 | //EOF
23 |
--------------------------------------------------------------------------------
/Docs/ACPI/SSDT-Swap-LeftControlCommand.dsl:
--------------------------------------------------------------------------------
1 | // This sample shows how to remap the Left Control to Command,
2 | // and Command (left Alt) to Left Control.
3 | DefinitionBlock ("", "SSDT", 2, "ACDT", "ps2", 0)
4 | {
5 | External (_SB_.PCI0.LPCB.PS2K, DeviceObj)
6 |
7 | Name(_SB.PCI0.LPCB.PS2K.RMCF, Package()
8 | {
9 | "Keyboard", Package()
10 | {
11 | "Custom ADB Map", Package()
12 | {
13 | Package(){},
14 | "1d=3a", // 1d is PS2 for left control, 3a is ADB for command
15 | "38=3b", // 38 is PS2 for left alt, 3b is ADB for left control
16 | },
17 | },
18 | })
19 | }
20 | //EOF
21 |
--------------------------------------------------------------------------------
/Docs/ACPI/SSDT-Thinkpad_Clickpad.dsl:
--------------------------------------------------------------------------------
1 | // Example overrides for Thinkpad models with ClickPad
2 | DefinitionBlock ("", "SSDT", 2, "ACDT", "ps2", 0)
3 | {
4 | // Change _SB.PCI0.LPC.KBD if your PS2 keyboard is at a different ACPI path
5 | External(_SB.PCI0.LPC.KBD, DeviceObj)
6 | Scope(_SB.PCI0.LPC.KBD)
7 | {
8 | // Select specific configuration in VoodooPS2Trackpad.kext
9 | Method(_DSM, 4)
10 | {
11 | If (!Arg2) { Return (Buffer() { 0x03 } ) }
12 | Return (Package()
13 | {
14 | "RM,oem-id", "LENOVO",
15 | "RM,oem-table-id", "Thinkpad_ClickPad",
16 | })
17 | }
18 | // Overrides (the example data here is default in the Info.plist)
19 | Name(RMCF, Package()
20 | {
21 | "Synaptics TouchPad", Package()
22 | {
23 | "HWResetOnStart", ">y",
24 | "QuietTimeAfterTyping", 500000000,
25 | "FingerZ", 30,
26 | "MouseMultiplierX", 2,
27 | "MouseMultiplierY", 2,
28 | "MouseDivisorX", 1,
29 | "MouseDivisorY", 1,
30 | // Change multipliers to 0xFFFE in order to inverse the scroll direction
31 | // of the Trackpoint when holding the middle mouse button.
32 | "TrackpointScrollXMultiplier", 2,
33 | "TrackpointScrollYMultiplier", 2,
34 | "TrackpointScrollXDivisor", 1,
35 | "TrackpointScrollYDivisor", 1
36 | },
37 | })
38 | }
39 | }
40 | //EOF
41 |
--------------------------------------------------------------------------------
/Docs/ACPI/SSDT-Thinkpad_Trackpad.dsl:
--------------------------------------------------------------------------------
1 | // Example overrides for Thinkpad models with TrackPad
2 | DefinitionBlock ("", "SSDT", 2, "ACDT", "ps2", 0)
3 | {
4 | External(_SB_.PCI0.LPCB.PS2K, DeviceObj)
5 | // Change _SB.PCI0.LPC.KBD if your PS2 keyboard is at a different ACPI path
6 | External(_SB_.PCI0.LPC.KBD, DeviceObj)
7 | Scope(_SB.PCI0.LPC.KBD)
8 | {
9 | // Select specific configuration in VoodooPS2Trackpad.kext
10 | Method(_SB.PCI0.LPCB.PS2K._DSM, 4)
11 | {
12 | If (!Arg2) { Return (Buffer() { 0x03 } ) }
13 | Return (Package()
14 | {
15 | "RM,oem-id", "LENOVO",
16 | "RM,oem-table-id", "Thinkpad_TrackPad",
17 | })
18 | }
19 | // Overrides (the example data here is default in the Info.plist)
20 | Name(_SB.PCI0.LPCB.PS2K.RMCF, Package()
21 | {
22 | "Synaptics TouchPad", Package()
23 | {
24 | "HWResetOnStart", ">y",
25 | "PalmNoAction When Typing", ">y",
26 | "FingerZ", 47,
27 | "MouseMultiplierX", 8,
28 | "MouseMultiplierY", 8,
29 | "MouseDivisorX", 1,
30 | "MouseDivisorY", 1,
31 | // Change multipliers to 0xFFFE in order to inverse the scroll direction
32 | // of the Trackpoint when holding the middle mouse button.
33 | "TrackpointScrollXMultiplier", 2,
34 | "TrackpointScrollYMultiplier", 2,
35 | "TrackpointScrollXDivisor", 1,
36 | "TrackpointScrollYDivisor", 1
37 | },
38 | })
39 | }
40 | }
41 | //EOF
42 |
--------------------------------------------------------------------------------
/Docs/SynapticsRevB.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/acidanthera/VoodooPS2/b6713c37b9919bd95c3b7f4d484bd049371bcfc1/Docs/SynapticsRevB.pdf
--------------------------------------------------------------------------------
/Docs/force_touch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/acidanthera/VoodooPS2/b6713c37b9919bd95c3b7f4d484bd049371bcfc1/Docs/force_touch.png
--------------------------------------------------------------------------------
/Docs/voodoops2ioio.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | ioio=/usr/local/bin/ioio
4 |
5 | $ioio -s ApplePS2SynapticsTouchPad Dragging 1
6 | $ioio -s ApplePS2SynapticsTouchPad DragExitDelayTime 500000000
7 | # $ioio -s ApplePS2SynapticsTouchPad DragExitDelayTime 250000000
8 | $ioio -s ApplePS2Keyboard "Swap command and option" true
9 |
10 | #3 finger gestures are disabled when three-finger drag is on
11 | # avoid using with three finger drag
12 | $ioio -s ApplePS2Keyboard Action3FingersSpread :""
13 | $ioio -s ApplePS2Keyboard Action3FingersPinch :""
14 |
15 | # cmd-left/right
16 | $ioio -s ApplePS2Keyboard ActionSwipeLeft :"" #37 d, 1e d, 1e u, 37 u"
17 | $ioio -s ApplePS2Keyboard ActionSwipeRight :"" #37 d, 21 d, 21 u, 37 u"
18 | $ioio -s ApplePS2Keyboard ActionSwipeUp :""
19 | $ioio -s ApplePS2Keyboard ActionSwipeDown :""
20 |
21 | # ctrl-right/left/up/down
22 | $ioio -s ApplePS2Keyboard ActionSwipe4FingersLeft :"3b d, 7c d, 7c u, 3b u"
23 | $ioio -s ApplePS2Keyboard ActionSwipe4FingersRight :"3b d, 7b d, 7b u, 3b u"
24 | $ioio -s ApplePS2Keyboard ActionSwipe4FingersUp :"3b d, 7e d, 7e u, 3b u"
25 | $ioio -s ApplePS2Keyboard ActionSwipe4FingersDown :"3b d, 7d d, 7d u, 3b u"
26 |
27 | # not ready
28 | $ioio -s ApplePS2Keyboard Action4FingersSpread :""
29 | $ioio -s ApplePS2Keyboard Action4FingersPinch :""
30 |
31 | # cmd-space
32 | $ioio -s ApplePS2Keyboard Action2FingersTap :"" # implementation not ready
33 | $ioio -s ApplePS2Keyboard Action3FingersTap :"" #37 d, 31 d, 31 u, 37 u"
34 | $ioio -s ApplePS2Keyboard Action4FingersTap :"37 d, 31 d, 31 u, 37 u"
35 |
36 | $ioio -s ApplePS2SynapticsTouchPad TrackpadRightClick 1
37 | $ioio -s ApplePS2SynapticsTouchPad TrackpadMiddleClick 1
38 |
39 | $ioio -s ApplePS2SynapticsTouchPad TrackpadThreeFingerDrag 1
40 |
41 | $ioio -s ApplePS2Keyboard LogScanCodes 0
42 |
43 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | ## APPLE PUBLIC SOURCE LICENSE
2 | ## Version 2.0 - August 6, 2003
3 |
4 | Please read this License carefully before downloading this software. By downloading or using this software, you are agreeing to be bound by the terms of this License. If you do not or cannot agree to the terms of this License, please do not download or use the software.
5 |
6 | 1\. General; Definitions. This License applies to any program or other work which Apple Computer, Inc. ("Apple") makes publicly available and which contains a notice placed by Apple identifying such program or work as "Original Code" and stating that it is subject to the terms of this Apple Public Source License version 2.0 ("License"). As used in this License:
7 |
8 | 1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is the grantor of rights, (i) claims of patents that are now or hereafter acquired, owned by or assigned to Apple and (ii) that cover subject matter contained in the Original Code, but only to the extent necessary to use, reproduce and/or distribute the Original Code without infringement; and (b) in the case where You are the grantor of rights, (i) claims of patents that are now or hereafter acquired, owned by or assigned to You and (ii) that cover subject matter in Your Modifications, taken alone or in combination with Original Code.
9 |
10 | 1.2 "Contributor" means any person or entity that creates or contributes to the creation of Modifications.
11 |
12 | 1.3 "Covered Code" means the Original Code, Modifications, the combination of Original Code and any Modifications, and/or any respective portions thereof.
13 |
14 | 1.4 "Externally Deploy" means: (a) to sublicense, distribute or otherwise make Covered Code available, directly or indirectly, to anyone other than You; and/or (b) to use Covered Code, alone or as part of a Larger Work, in any way to provide a service, including but not limited to delivery of content, through electronic communication with a client other than You.
15 |
16 | 1.5 "Larger Work" means a work which combines Covered Code or portions thereof with code not governed by the terms of this License.
17 |
18 | 1.6 "Modifications" mean any addition to, deletion from, and/or change to, the substance and/or structure of the Original Code, any previous Modifications, the combination of Original Code and any previous Modifications, and/or any respective portions thereof. When code is released as a series of files, a Modification is: (a) any addition to or deletion from the contents of a file containing Covered Code; and/or (b) any new file or other representation of computer program statements that contains any part of Covered Code.
19 |
20 | 1.7 "Original Code" means (a) the Source Code of a program or other work as originally made available by Apple under this License, including the Source Code of any updates or upgrades to such programs or works made available by Apple under this License, and that has been expressly identified by Apple as such in the header file(s) of such work; and (b) the object code compiled from such Source Code and originally made available by Apple under this License.
21 |
22 | 1.8 "Source Code" means the human readable form of a program or other work that is suitable for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an executable (object code).
23 |
24 | 1.9 "You" or "Your" means an individual or a legal entity exercising rights under this License. For legal entities, "You" or "Your" includes any entity which controls, is controlled by, or is under common control with, You, where "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of fifty percent (50%) or more of the outstanding shares or beneficial ownership of such entity.
25 |
26 | 2\. Permitted Uses; Conditions & Restrictions. Subject to the terms and conditions of this License, Apple hereby grants You, effective on the date You accept this License and download the Original Code, a world-wide, royalty-free, non-exclusive license, to the extent of Apple's Applicable Patent Rights and copyrights covering the Original Code, to do the following:
27 |
28 | 2.1 Unmodified Code. You may use, reproduce, display, perform, internally distribute within Your organization, and Externally Deploy verbatim, unmodified copies of the Original Code, for commercial or non-commercial purposes, provided that in each instance:
29 |
30 | (a) You must retain and reproduce in all copies of Original Code the copyright and other proprietary notices and disclaimers of Apple as they appear in the Original Code, and keep intact all notices in the Original Code that refer to this License; and
31 |
32 | (b) You must include a copy of this License with every copy of Source Code of Covered Code and documentation You distribute or Externally Deploy, and You may not offer or impose any terms on such Source Code that alter or restrict this License or the recipients' rights hereunder, except as permitted under Section 6.
33 |
34 | 2.2 Modified Code. You may modify Covered Code and use, reproduce, display, perform, internally distribute within Your organization, and Externally Deploy Your Modifications and Covered Code, for commercial or non-commercial purposes, provided that in each instance You also meet all of these conditions:
35 |
36 | (a) You must satisfy all the conditions of Section 2.1 with respect to the Source Code of the Covered Code;
37 |
38 | (b) You must duplicate, to the extent it does not already exist, the notice in Exhibit A in each file of the Source Code of all Your Modifications, and cause the modified files to carry prominent notices stating that You changed the files and the date of any change; and
39 |
40 | (c) If You Externally Deploy Your Modifications, You must make Source Code of all Your Externally Deployed Modifications either available to those to whom You have Externally Deployed Your Modifications, or publicly available. Source Code of Your Externally Deployed Modifications must be released under the terms set forth in this License, including the license grants set forth in Section 3 below, for as long as you Externally Deploy the Covered Code or twelve (12) months from the date of initial External Deployment, whichever is longer. You should preferably distribute the Source Code of Your Externally Deployed Modifications electronically (e.g. download from a web site).
41 |
42 | 2.3 Distribution of Executable Versions. In addition, if You Externally Deploy Covered Code (Original Code and/or Modifications) in object code, executable form only, You must include a prominent notice, in the code itself as well as in related documentation, stating that Source Code of the Covered Code is available under the terms of this License with information on how and where to obtain such Source Code.
43 |
44 | 2.4 Third Party Rights. You expressly acknowledge and agree that although Apple and each Contributor grants the licenses to their respective portions of the Covered Code set forth herein, no assurances are provided by Apple or any Contributor that the Covered Code does not infringe the patent or other intellectual property rights of any other entity. Apple and each Contributor disclaim any liability to You for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, You hereby assume sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow You to distribute the Covered Code, it is Your responsibility to acquire that license before distributing the Covered Code.
45 |
46 | 3\. Your Grants. In consideration of, and as a condition to, the licenses granted to You under this License, You hereby grant to any person or entity receiving or distributing Covered Code under this License a non-exclusive, royalty-free, perpetual, irrevocable license, under Your Applicable Patent Rights and other intellectual property rights (other than patent) owned or controlled by You, to use, reproduce, display, perform, modify, sublicense, distribute and Externally Deploy Your Modifications of the same scope and extent as Apple's licenses under Sections 2.1 and 2.2 above.
47 |
48 | 4\. Larger Works. You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In each such instance, You must make sure the requirements of this License are fulfilled for the Covered Code or any portion thereof.
49 |
50 | 5\. Limitations on Patent License. Except as expressly stated in Section 2, no other patent rights, express or implied, are granted by Apple herein. Modifications and/or Larger Works may require additional patent licenses from Apple which Apple may grant in its sole discretion.
51 |
52 | 6\. Additional Terms. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the scope of the license granted herein ("Additional Terms") to one or more recipients of Covered Code. However, You may do so only on Your own behalf and as Your sole responsibility, and not on behalf of Apple or any Contributor. You must obtain the recipient's agreement that any such Additional Terms are offered by You alone, and You hereby agree to indemnify, defend and hold Apple and every Contributor harmless for any liability incurred by or claims asserted against Apple or such Contributor by reason of any such Additional Terms.
53 |
54 | 7\. Versions of the License. Apple may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Once Original Code has been published under a particular version of this License, You may continue to use it under the terms of that version. You may also choose to use such Original Code under the terms of any subsequent version of this License published by Apple. No one other than Apple has the right to modify the terms applicable to Covered Code created under this License.
55 |
56 | 8\. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in part pre-release, untested, or not fully tested works. The Covered Code may contain errors that could cause failures or loss of data, and may be incomplete or contain inaccuracies. You expressly acknowledge and agree that use of the Covered Code, or any portion thereof, is at Your sole and entire risk. THE COVERED CODE IS PROVIDED "AS IS" AND WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND AND APPLE AND APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT WARRANT AGAINST INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS, THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY. You acknowledge that the Covered Code is not intended for use in the operation of nuclear facilities, aircraft navigation, communication systems, or air traffic control machines in which case the failure of the Covered Code could lead to death, personal injury, or severe physical or environmental damage.
57 |
58 | 9\. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO THIS LICENSE OR YOUR USE OR INABILITY TO USE THE COVERED CODE, OR ANY PORTION THEREOF, WHETHER UNDER A THEORY OF CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, EVEN IF APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY TO YOU. In no event shall Apple's total liability to You for all damages (other than as may be required by applicable law) under this License exceed the amount of fifty dollars ($50.00).
59 |
60 | 10\. Trademarks. This License does not grant any rights to use the trademarks or trade names "Apple", "Apple Computer", "Mac", "Mac OS", "QuickTime", "QuickTime Streaming Server" or any other trademarks, service marks, logos or trade names belonging to Apple (collectively "Apple Marks") or to any trademark, service mark, logo or trade name belonging to any Contributor. You agree not to use any Apple Marks in or as part of the name of products derived from the Original Code or to endorse or promote products derived from the Original Code other than as expressly permitted by and in strict compliance at all times with Apple's third party trademark usage guidelines which are posted at http://www.apple.com/legal/guidelinesfor3rdparties.html.
61 |
62 | 11\. Ownership. Subject to the licenses granted under this License, each Contributor retains all rights, title and interest in and to any Modifications made by such Contributor. Apple retains all rights, title and interest in and to the Original Code and any Modifications made by or on behalf of Apple ("Apple Modifications"), and such Apple Modifications will not be automatically subject to this License. Apple may, at its sole discretion, choose to license such Apple Modifications under this License, or on different terms from those contained in this License or may choose not to license them at all.
63 |
64 | 12\. Termination.
65 |
66 | 12.1 Termination. This License and the rights granted hereunder will terminate:
67 |
68 | (a) automatically without notice from Apple if You fail to comply with any term(s) of this License and fail to cure such breach within 30 days of becoming aware of such breach;
69 |
70 | (b) immediately in the event of the circumstances described in Section 13.5(b); or
71 |
72 | (c) automatically without notice from Apple if You, at any time during the term of this License, commence an action for patent infringement against Apple; provided that Apple did not first commence an action for patent infringement against You in that instance.
73 |
74 | 12.2 Effect of Termination. Upon termination, You agree to immediately stop any further use, reproduction, modification, sublicensing and distribution of the Covered Code. All sublicenses to the Covered Code which have been properly granted prior to termination shall survive any termination of this License. Provisions which, by their nature, should remain in effect beyond the termination of this License shall survive, including but not limited to Sections 3, 5, 8, 9, 10, 11, 12.2 and 13. No party will be liable to any other for compensation, indemnity or damages of any sort solely as a result of terminating this License in accordance with its terms, and termination of this License will be without prejudice to any other right or remedy of any party.
75 |
76 | 13\. Miscellaneous.
77 |
78 | 13.1 Government End Users. The Covered Code is a "commercial item" as defined in FAR 2.101. Government software and technical data rights in the Covered Code include only those rights customarily provided to the public as defined in this License. This customary commercial license in technical data and software is provided in accordance with FAR 12.211 (Technical Data) and 12.212 (Computer Software) and, for Department of Defense purchases, DFAR 252.227-7015 (Technical Data -- Commercial Items) and 227.7202-3 (Rights in Commercial Computer Software or Computer Software Documentation). Accordingly, all U.S. Government End Users acquire Covered Code with only those rights set forth herein.
79 |
80 | 13.2 Relationship of Parties. This License will not be construed as creating an agency, partnership, joint venture or any other form of legal association between or among You, Apple or any Contributor, and You will not represent to the contrary, whether expressly, by implication, appearance or otherwise.
81 |
82 | 13.3 Independent Development. Nothing in this License will impair Apple's right to acquire, license, develop, have others develop for it, market and/or distribute technology or products that perform the same or similar functions as, or otherwise compete with, Modifications, Larger Works, technology or products that You may develop, produce, market or distribute.
83 |
84 | 13.4 Waiver; Construction. Failure by Apple or any Contributor to enforce any provision of this License will not be deemed a waiver of future enforcement of that or any other provision. Any law or regulation which provides that the language of a contract shall be construed against the drafter will not apply to this License.
85 |
86 | 13.5 Severability. (a) If for any reason a court of competent jurisdiction finds any provision of this License, or portion thereof, to be unenforceable, that provision of the License will be enforced to the maximum extent permissible so as to effect the economic benefits and intent of the parties, and the remainder of this License will continue in full force and effect. (b) Notwithstanding the foregoing, if applicable law prohibits or restricts You from fully and/or specifically complying with Sections 2 and/or 3 or prevents the enforceability of either of those Sections, this License will immediately terminate and You must immediately discontinue any use of the Covered Code and destroy all copies of it that are in your possession or control.
87 |
88 | 13.6 Dispute Resolution. Any litigation or other dispute resolution between You and Apple relating to this License shall take place in the Northern District of California, and You and Apple hereby consent to the personal jurisdiction of, and venue in, the state and federal courts within that District with respect to this License. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded.
89 |
90 | 13.7 Entire Agreement; Governing Law. This License constitutes the entire agreement between the parties with respect to the subject matter hereof. This License shall be governed by the laws of the United States and the State of California, except that body of California law concerning conflicts of law.
91 |
92 | Where You are located in the province of Quebec, Canada, the following clause applies: The parties hereby confirm that they have requested that this License and all related documents be drafted in English. Les parties ont exige que le present contrat et tous les documents connexes soient rediges en anglais.
93 |
94 | EXHIBIT A.
95 |
96 | "Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
97 |
98 | This file contains Original Code and/or Modifications of Original Code as defined in and that are subject to the Apple Public Source License Version 2.0 (the 'License'). You may not use this file except in compliance with the License. Please obtain a copy of the License at http://www.opensource.apple.com/apsl/ and read it before using this file.
99 |
100 | The Original Code and all software distributed under the License are distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the specific language governing rights and limitations under the License."
101 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | VoodooPS2
2 | =========
3 |
4 | [](https://github.com/acidanthera/VoodooPS2/actions) [](https://scan.coverity.com/projects/22190)
5 |
6 | New **VoodooPS2Trackpad** uses VoodooInput's Magic Trackpad II emulation in order to use macOS native driver instead of handling all gestures itself. This enables the use of any from one to four finger gestures defined by Apple including:
7 | * Look up & data detectors
8 | * Secondary click (*with two fingers, in bottom left corner\*, in bottom right corner\**)
9 | * Tap to click
10 | * Scrolling
11 | * Zoom in or out
12 | * Smart zoom
13 | * Rotate
14 | * Swipe between pages
15 | * Swipe between full-screen apps (*with three or four fingers*)
16 | * Notification Centre
17 | * Mission Control (*with three or four fingers*)
18 | * App Exposé (*with three or four fingers*)
19 | * Dragging with or without drag lock (*configured in 'Accessibility'/'Universal Access' prefpane*)
20 | * Three finger drag (*configured in 'Accessibility'/'Universal Access' prefpane, may work unreliably\*\**)
21 | * Launchpad (*may work unreliably*)
22 | * Show Desktop (*may work unreliably*)
23 | * Screen zoom (*configured in 'Accessibility'/'Universal Access' -> Zoom -> Advanced -> Controls -> Use trackpad gesture to zoom*)
24 |
25 | It also supports **BetterTouchTool**.
26 |
27 | In addition this kext supports **Force Touch** emulation (*configured in `Info.plist`*):
28 | * **Mode 0** – Force Touch emulation is disabled (*you can also disable it in **System Preferences** without setting the mode*).
29 | * **Mode 1** – Force Touch emulation using a physical button: on ClickPads (touchpads which have the whole surface clickable (the physical button is inside the laptop under the bottom of touchpad)), the physical button can be remapped to Force Touch. In such mode a tap is a regular click, if **Tap to click** gesture is enabled in **System Preferences**, and a click is a Force Touch. This mode is convenient for people who usually tap on the touchpad, not click.
30 | * **Mode 2** – *'wide tap'*: for Force Touch one needs to increase the area of a finger touching the touchpad\*\*\*. The necessary width can be set in `Info.plist`.
31 | * **Mode 3** – pressure value is passed to the system as is; this mode shouldn't be used.
32 | * **Mode 4** (*by @Tarik02*) – pressure is passed to the system using the following formula: 
33 | The parameters in the formula are configured using `ForceTouchCustomUpThreshold`, `ForceTouchCustomDownThreshold` and `ForceTouchCustomPower` keys in `Info.plist` or configuration SSDT. Note that `ForceTouchCustomDownThreshold` is the *upper* limit on the pressure value and vice versa, because it corresponds to the touchpad being fully pressed *down*.
34 |
35 | For Elan touchpad, only mode 0 and mode 1 are supported.
36 |
37 | For ALPS touchpads, V1, V2 and V6 do not support Force Touch. V3, V4 and V5 only support mode 0, 2, 3 and 4. V7 only supports mode 0 and 1. V8 supports all modes.
38 |
39 | ## Installation and compilation
40 |
41 | For VoodooPS2Trackpad.kext to work multitouch interface engine, named VoodooInput.kext, is required.
42 |
43 | - For released binaries a compatible version of VoodooInput.kext is already included in the PlugIns directory.
44 | - For custom compiled versions VoodooInput.kext bootstrapping is required prior to compilation.
45 | By default Xcode project will do this automatically. If you prefer to have your own control over the
46 | process execute the following command in the project directory to have VoodooInput bootstrapped:
47 |
48 | ```
49 | src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/VoodooInput/master/VoodooInput/Scripts/bootstrap.sh) && eval "$src" || exit 1
50 | ```
51 |
52 | ## Touchpad and Keyboard Input Toggle
53 |
54 | This kext supports disabling touch input by pressing the Printscreen key on your keyboard, or the touchpad disable key on many laptops. Simply press the key to toggle touchpad input off and again to toggle it back on.
55 |
56 | In addition, for 2-in-1 systems that do not support disabling the keyboard in hardware while in tablet mode you may toggle keyboard input off and on by holding option(Windows) and pressing the Printscreen key. Repeat the keypress to re-enable keyboard input. These settings are runtime only and do not persist across a reboot.
57 |
58 | ## Credits:
59 | * VoodooPS2Controller etc. – turbo, mackerintel, @RehabMan, nhand42, phb, Chunnan, jape, bumby (see RehabMan's repository).
60 | * Magic Trackpad 2 reverse engineering and implementation – https://github.com/alexandred/VoodooI2C project team.
61 | * VoodooPS2Trackpad integration – @kprinssu.
62 | * Force Touch emulation and finger renumbering algorithm** – @usr-sse2.
63 | * Elan touchpad driver – linux kernel contributors, @kprinssu, @BAndysc and @hieplpvip
64 |
65 | \* On my touchpad this gesture was practically impossible to perform with the old VoodooPS2Trackpad. Now it works well.
66 |
67 | \*\* Due to the limitations of PS/2 bus, Synaptics touchpad reports only the number of fingers and coordinates of two of them to the computer. When there are two fingers on the touchpad and third finger is added, a 'jump' may happen, because the coordinates of one of the fingers are replaced with the coordinates of the added finger. Finger renumbering algorithm estimates the distance from old coordinates to new ones in order to hide this 'jump' from the OS ~~and to calculate approximate position of the 'hidden' finger, in assumption that fingers move together in parallel to each other~~. Now third and fourth fingers are reported at the same position as one of the first two fingers. It allows Launchpad/Show desktop gesture to work more reliably.
68 |
69 | \*\*\* The touchpad reports both finger width (ranged from 4 to 15) and pressure (ranged from 0 to 255), but in practice the measured width is almost always 4, and the reported pressure depends more on actual touch width than on actual pressure.
70 |
--------------------------------------------------------------------------------
/VoodooPS2Controller.xcodeproj/xcshareddata/xcschemes/VoodooPS2Controller.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
43 |
49 |
50 |
51 |
57 |
63 |
64 |
65 |
71 |
77 |
78 |
79 |
85 |
91 |
92 |
93 |
94 |
95 |
100 |
101 |
107 |
108 |
109 |
110 |
111 |
112 |
122 |
123 |
129 |
130 |
131 |
132 |
138 |
139 |
145 |
146 |
147 |
148 |
150 |
151 |
154 |
155 |
156 |
--------------------------------------------------------------------------------
/VoodooPS2Controller.xcodeproj/xcshareddata/xcschemes/VoodooPS2Keyboard.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/VoodooPS2Controller.xcodeproj/xcshareddata/xcschemes/VoodooPS2Mouse.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/VoodooPS2Controller.xcodeproj/xcshareddata/xcschemes/VoodooPS2Trackpad.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/VoodooPS2Controller/AppleACPIPS2Nub.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * This file contains Original Code and/or Modifications of Original Code
7 | * as defined in and that are subject to the Apple Public Source License
8 | * Version 2.0 (the 'License'). You may not use this file except in
9 | * compliance with the License. Please obtain a copy of the License at
10 | * http://www.opensource.apple.com/apsl/ and read it before using this
11 | * file.
12 | *
13 | * The Original Code and all software distributed under the License are
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 | * Please see the License for the specific language governing rights and
19 | * limitations under the License.
20 | *
21 | * @APPLE_LICENSE_HEADER_END@
22 | */
23 | /*! @file AppleACPIPS2Nub.cpp
24 | @abstract AppleACPIPS2Nub class implementation
25 | @discussion
26 | Implements the ACPI PS/2 nub for ApplePS2Controller.kext.
27 | Reverse-engineered from the Darwin 8 binary ACPI kext.
28 | Copyright 2007 David Elliott
29 | */
30 |
31 | #include "AppleACPIPS2Nub.h"
32 |
33 | #if 0
34 | #define DEBUG_LOG(args...)
35 | #else
36 | #undef DEBUG_LOG
37 | #define DEBUG_LOG(args...)
38 | #endif
39 |
40 | static IOPMPowerState myTwoStates[2] = {
41 | {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
42 | {1, kIOPMPowerOn, kIOPMPowerOn, kIOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0}
43 | };
44 |
45 | OSDefineMetaClassAndStructors(AppleACPIPS2Nub, IOPlatformDevice);
46 |
47 | // We could simply ask for the PE rather than importing the global
48 | // from AppleACPIPlatformExpert.kext
49 | // extern IOPlatformExpert *gAppleACPIPlatformExpert;
50 |
51 | bool AppleACPIPS2Nub::start(IOService *provider)
52 | {
53 | if (!super::start(provider))
54 | return false;
55 |
56 | DEBUG_LOG("AppleACPIPS2Nub::start: provider=%p\n", provider);
57 |
58 | /* Initialize our interrupt controller/specifier i-vars */
59 | m_interruptControllers = OSArray::withCapacity(2);
60 | m_interruptSpecifiers = OSArray::withCapacity(2);
61 | if(m_interruptControllers == NULL || m_interruptSpecifiers == NULL)
62 | return false;
63 |
64 | /* Merge in the keyboard (primary) provider interrupt properties */
65 | mergeInterruptProperties(provider, LEGACY_KEYBOARD_IRQ);
66 |
67 | /* Initialize and register our power management properties */
68 | PMinit();
69 | registerPowerDriver(this, myTwoStates, 2);
70 | provider->joinPMtree(this);
71 |
72 | /* Find the mouse provider */
73 | m_mouseProvider = findMouseDevice();
74 | if(m_mouseProvider != NULL)
75 | {
76 | DEBUG_LOG("AppleACPIPS2Nub::start: Found mouse PNP device\n");
77 | if(attach(m_mouseProvider))
78 | {
79 | mergeInterruptProperties(m_mouseProvider, LEGACY_MOUSE_IRQ);
80 | if(m_mouseProvider->inPlane(gIOPowerPlane))
81 | {
82 | m_mouseProvider->joinPMtree(this);
83 | }
84 | }
85 | }
86 |
87 | /* Set our interrupt properties in the IO registry */
88 | if(m_interruptControllers->getCount() != 0 && m_interruptSpecifiers->getCount() != 0)
89 | {
90 | setProperty(gIOInterruptControllersKey, m_interruptControllers);
91 | setProperty(gIOInterruptSpecifiersKey, m_interruptSpecifiers);
92 | }
93 |
94 | /* Release the arrays we allocated. Our properties dictionary has them retained */
95 | m_interruptControllers->release();
96 | m_interruptControllers = NULL;
97 | m_interruptSpecifiers->release();
98 | m_interruptSpecifiers = NULL;
99 |
100 | /* Make ourselves the ps2controller nub and register so ApplePS2Controller can find us. */
101 | setName("ps2controller");
102 | registerService();
103 |
104 | DEBUG_LOG("AppleACPIPS2Nub::start: startup complete\n");
105 |
106 | return true;
107 | }
108 |
109 | void AppleACPIPS2Nub::stop(IOService *provider)
110 | {
111 | PMstop();
112 | return super::stop(provider);
113 | }
114 |
115 | IOService *AppleACPIPS2Nub::findMouseDevice()
116 | {
117 | OSObject *prop = getProperty("MouseNameMatch");
118 | /* Slight delay to allow PS2 mouse entry in IOACPIPlane to populate */
119 | UInt32 findMouseDelay = 100; // default 100ms delay before checking iroeg for mouse matches
120 | if (OSNumber* number = OSDynamicCast(OSNumber, getProperty("FindMouseDelay")))
121 | findMouseDelay = number->unsigned32BitValue();
122 | UInt32 vps2FindMouseDelay;
123 | if (PE_parse_boot_argn("vps2_findmousedelay", &vps2FindMouseDelay, sizeof vps2FindMouseDelay))
124 | findMouseDelay = vps2FindMouseDelay;
125 | if (findMouseDelay)
126 | IOSleep(findMouseDelay);
127 | /* Search from the root of the ACPI plane for the mouse PNP nub */
128 | IORegistryIterator *i = IORegistryIterator::iterateOver(gIOACPIPlane, kIORegistryIterateRecursively);
129 | IORegistryEntry *entry;
130 | if(i != NULL)
131 | {
132 | while((entry = i->getNextObject()))
133 | {
134 | if(entry->compareNames(prop))
135 | break;
136 | }
137 | i->release();
138 | }
139 | else
140 | entry = NULL;
141 | return OSDynamicCast(IOService, entry);
142 | }
143 |
144 | void AppleACPIPS2Nub::mergeInterruptProperties(IOService *pnpProvider, long)
145 | {
146 | /* Get the interrupt controllers/specifiers arrays from the provider, and make sure they
147 | * exist and contain at least one entry. We assume they contain exactly one entry.
148 | */
149 | OSArray *controllers = OSDynamicCast(OSArray,pnpProvider->getProperty(gIOInterruptControllersKey));
150 | OSArray *specifiers = OSDynamicCast(OSArray,pnpProvider->getProperty(gIOInterruptSpecifiersKey));
151 | if(controllers == NULL || specifiers == NULL)
152 | return;
153 | if(controllers->getCount() == 0 || specifiers->getCount() == 0)
154 | return;
155 |
156 | /* Append the first object of each array into our own respective array */
157 | m_interruptControllers->setObject(controllers->getObject(0));
158 | m_interruptSpecifiers->setObject(specifiers->getObject(0));
159 | }
160 |
161 | IOReturn AppleACPIPS2Nub::registerInterrupt(int source, OSObject *target, IOInterruptAction handler, void *refCon)
162 | {
163 | if(source == LEGACY_KEYBOARD_IRQ)
164 | return super::registerInterrupt(0, target, handler, refCon);
165 | else if(source == LEGACY_MOUSE_IRQ)
166 | return super::registerInterrupt(1, target, handler, refCon);
167 | else
168 | return kIOReturnBadArgument;
169 | }
170 |
171 | IOReturn AppleACPIPS2Nub::unregisterInterrupt(int source)
172 | {
173 | if(source == LEGACY_KEYBOARD_IRQ)
174 | return super::unregisterInterrupt(0);
175 | else if(source == LEGACY_MOUSE_IRQ)
176 | return super::unregisterInterrupt(1);
177 | else
178 | return kIOReturnBadArgument;
179 | }
180 |
181 | IOReturn AppleACPIPS2Nub::getInterruptType(int source, int *interruptType)
182 | {
183 | if(source == LEGACY_KEYBOARD_IRQ)
184 | return super::getInterruptType(0, interruptType);
185 | else if(source == LEGACY_MOUSE_IRQ)
186 | return super::getInterruptType(1, interruptType);
187 | else
188 | return kIOReturnBadArgument;
189 | }
190 |
191 | IOReturn AppleACPIPS2Nub::enableInterrupt(int source)
192 | {
193 | if(source == LEGACY_KEYBOARD_IRQ)
194 | return super::enableInterrupt(0);
195 | else if(source == LEGACY_MOUSE_IRQ)
196 | return super::enableInterrupt(1);
197 | else
198 | return kIOReturnBadArgument;
199 | }
200 |
201 | IOReturn AppleACPIPS2Nub::disableInterrupt(int source)
202 | {
203 | if(source == LEGACY_KEYBOARD_IRQ)
204 | return super::disableInterrupt(0);
205 | else if(source == LEGACY_MOUSE_IRQ)
206 | return super::disableInterrupt(1);
207 | else
208 | return kIOReturnBadArgument;
209 | }
210 |
211 | bool AppleACPIPS2Nub::compareName( OSString * name, OSString ** matched ) const
212 | {
213 | // return gAppleACPIPlatformExpert->compareNubName( this, name, matched );
214 | return( this->IORegistryEntry::compareName( name, matched ));
215 | }
216 |
217 | IOReturn AppleACPIPS2Nub::getResources( void )
218 | {
219 | // return gAppleACPIPlatformExpert->getNubResources(this);
220 | return( kIOReturnSuccess );
221 | }
222 |
223 | IOReturn AppleACPIPS2Nub::message( UInt32 type, IOService *provider, void *argument )
224 | {
225 | ////DEBUG_LOG("AppleACPIPS2Nub::message: type=%x, provider=%p, argument=%p\n", type, provider, argument);
226 |
227 | // forward to all interested sub-entries
228 | IORegistryIterator *i = IORegistryIterator::iterateOver(this, gIOServicePlane, kIORegistryIterateRecursively);
229 | IORegistryEntry *entry;
230 | if(i != NULL)
231 | {
232 | while((entry = i->getNextObject()))
233 | {
234 | IOService* service = OSDynamicCast(IOService, entry);
235 | if(service != NULL && service->getProperty(kDeliverNotifications))
236 | {
237 | service->message(type, provider, argument);
238 | }
239 | }
240 | i->release();
241 | }
242 |
243 | return( kIOReturnSuccess );
244 | }
245 |
--------------------------------------------------------------------------------
/VoodooPS2Controller/AppleACPIPS2Nub.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * This file contains Original Code and/or Modifications of Original Code
7 | * as defined in and that are subject to the Apple Public Source License
8 | * Version 2.0 (the 'License'). You may not use this file except in
9 | * compliance with the License. Please obtain a copy of the License at
10 | * http://www.opensource.apple.com/apsl/ and read it before using this
11 | * file.
12 | *
13 | * The Original Code and all software distributed under the License are
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 | * Please see the License for the specific language governing rights and
19 | * limitations under the License.
20 | *
21 | * @APPLE_LICENSE_HEADER_END@
22 | */
23 | /*! @file AppleACPIPS2Nub.h
24 | @abstract AppleACPIPS2Nub class definition
25 | @discussion
26 | Implements the ACPI PS/2 nub for ApplePS2Controller.kext.
27 | Reverse-engineered from the Darwin 8 binary ACPI kext.
28 | Copyright 2007 David Elliott
29 | */
30 |
31 | #ifndef __AppleACPIPS2Nub__
32 | #define __AppleACPIPS2Nub__
33 |
34 | #include
35 | #include
36 | #include
37 |
38 | #include "ApplePS2Device.h"
39 |
40 | #define EXPORT __attribute__((visibility("default")))
41 |
42 | class IOPlatformExpert;
43 |
44 | /*! @class AppleACPIPS2Nub
45 | @abstract Provides a nub that ApplePS2Controller can attach to
46 | @discussion
47 | The ApplePS2Controller driver is written to the nub provided by the
48 | AppleI386PlatformExpert class which exposes the controller as it is found
49 | on a legacy x86 machine.
50 |
51 | To make that kext work on an ACPI machine, a nub providing the same
52 | service must exist. Previous releases of the official ACPI PE included
53 | this class. Newer release do not. This implementation is intended
54 | to be fully ABI compatible with the one Apple used to provide.
55 | */
56 | class EXPORT AppleACPIPS2Nub: public IOPlatformDevice
57 | {
58 | typedef IOPlatformDevice super;
59 | OSDeclareDefaultStructors(AppleACPIPS2Nub);
60 |
61 | private:
62 | /*! @field m_mouseProvider
63 | @abstract Our second provider which provides the mouse nub
64 | @discussion
65 | We attach to the keyboard nub but we need to be attached to both the
66 | keyboard and mouse nub in order to make ourselves a proper nub for
67 | the ApplePS2Controller.kext driver.
68 | */
69 | IOService *m_mouseProvider;
70 |
71 | /*! @field m_interruptControllers
72 | @abstract Our array of interrupt controllers
73 | */
74 | OSArray *m_interruptControllers;
75 |
76 | /*! @field m_interruptSpecifiers
77 | @abstract Our array of interrupt specifiers
78 | */
79 | OSArray *m_interruptSpecifiers;
80 |
81 | enum LegacyInterrupts
82 | {
83 | LEGACY_KEYBOARD_IRQ = 1,
84 | LEGACY_MOUSE_IRQ = 12,
85 | };
86 |
87 | public:
88 | bool start(IOService *provider) override;
89 | void stop(IOService *provider) override;
90 |
91 | /*! @method findMouseDevice
92 | @abstract Locates the mouse nub in the IORegistry
93 | */
94 | virtual IOService *findMouseDevice();
95 |
96 | /*! @method mergeInterruptProperties
97 | @abstract Merges the interrupt specifiers and controllers from our two providers
98 | @param pnpProvider The provider nub
99 | @discussion
100 | This is called once for each of our providers. The interrupt controller and interrupt
101 | specifier objects from the provider's arrays are appended to our arrays.
102 | */
103 | virtual void mergeInterruptProperties(IOService *pnpProvider, long source);
104 |
105 | /*! @method registerInterrupt
106 | @abstract Overriden to translate the legacy interrupt numbers to ours
107 | @discussion
108 | The legacy interrupts are 1 for the keyboard and 12 (0xc) for the mouse.
109 | However, the base class code works off of the controller and specifier
110 | objects in our IOInterruptControllers and IOInterruptSpecifiers keys.
111 | Therefore, we must translate the keyboard interrupt (1) to the index
112 | into our array (0) and the mouse interrupt (12) to the index into
113 | our array (1).
114 |
115 | This has to be done for every *Interrupt* method
116 | */
117 | IOReturn registerInterrupt(int source, OSObject *target,
118 | IOInterruptAction handler,
119 | void *refCon = 0) override;
120 | IOReturn unregisterInterrupt(int source) override;
121 | IOReturn getInterruptType(int source, int *interruptType) override;
122 | IOReturn enableInterrupt(int source) override;
123 | IOReturn disableInterrupt(int source) override;
124 |
125 | /*! @method compareName
126 | @abstract Overridden to call the IOPlatformExpert compareNubName method
127 | @discussion
128 | I have no idea why this is done, but the Apple code did it, so this
129 | code does too.
130 | */
131 | bool compareName( OSString * name, OSString ** matched = 0 ) const override;
132 |
133 | /*! @method getResources
134 | @abstract Overridden to call the IOPlatformExpert getNubResources method
135 | @discussion
136 | I have no idea why this is done, but the Apple code did it, so this
137 | code does too.
138 | */
139 | IOReturn getResources( void ) override;
140 |
141 | /*! @method message
142 | @abstract Overridden to receive ACPI notifications
143 | @discussion
144 | Allows the notifications to be forwarded to the keyboard device such that
145 | ACPI Notify can be used to push keystrokes. This is used to convert ACPI
146 | keys such that they appear to be PS2 keys.
147 | */
148 | IOReturn message( UInt32 type, IOService* provider, void* argument ) override;
149 | };
150 |
151 | #endif
152 |
--------------------------------------------------------------------------------
/VoodooPS2Controller/ApplePS2Device.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * The contents of this file constitute Original Code as defined in and
7 | * are subject to the Apple Public Source License Version 1.1 (the
8 | * "License"). You may not use this file except in compliance with the
9 | * License. Please obtain a copy of the License at
10 | * http://www.apple.com/publicsource and read it before using this file.
11 | *
12 | * This Original Code and all software distributed under the License are
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 | * License for the specific language governing rights and limitations
18 | * under the License.
19 | *
20 | * @APPLE_LICENSE_HEADER_END@
21 | */
22 |
23 | #include "ApplePS2Device.h"
24 | #include "VoodooPS2Controller.h"
25 |
26 | OSDefineMetaClassAndStructors(ApplePS2Device, IOService);
27 |
28 | // =============================================================================
29 | // ApplePS2Device Class Implementation
30 | //
31 |
32 | bool ApplePS2Device::init(size_t port)
33 | {
34 | _port = port;
35 | return super::init();
36 | }
37 |
38 | bool ApplePS2Device::attach(IOService * provider)
39 | {
40 | if (!super::attach(provider))
41 | return false;
42 |
43 | _workloop = IOWorkLoop::workLoop();
44 | _interruptSource = IOInterruptEventSource::interruptEventSource(this,
45 | OSMemberFunctionCast(IOInterruptEventAction, this, &ApplePS2Device::packetAction));
46 |
47 | if (!_interruptSource || !_workloop)
48 | {
49 | OSSafeReleaseNULL(_workloop);
50 | OSSafeReleaseNULL(_interruptSource);
51 | return false;
52 | }
53 |
54 | if (_workloop->addEventSource(_interruptSource) != kIOReturnSuccess)
55 | {
56 | OSSafeReleaseNULL(_workloop);
57 | OSSafeReleaseNULL(_interruptSource);
58 | return false;
59 | }
60 |
61 | setProperty(kPortKey, _port, 8);
62 |
63 | assert(_controller == 0);
64 | _controller = (ApplePS2Controller*)provider;
65 | _controller->retain();
66 |
67 | return true;
68 | }
69 |
70 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
71 |
72 | void ApplePS2Device::detach( IOService * provider )
73 | {
74 | assert(_controller == provider);
75 | _controller->release();
76 | _controller = 0;
77 |
78 | if (_interruptSource && _workloop)
79 | {
80 | _workloop->removeEventSource(_interruptSource);
81 | }
82 |
83 | OSSafeReleaseNULL(_interruptSource);
84 | OSSafeReleaseNULL(_workloop);
85 |
86 | super::detach(provider);
87 | }
88 |
89 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
90 |
91 | PS2Request * ApplePS2Device::allocateRequest(int max)
92 | {
93 | return _controller->allocateRequest(max);
94 | }
95 |
96 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
97 |
98 | void ApplePS2Device::freeRequest(PS2Request * request)
99 | {
100 | _controller->freeRequest(request);
101 | }
102 |
103 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
104 |
105 | bool ApplePS2Device::submitRequest(PS2Request * request)
106 | {
107 | request->port = _port;
108 | return _controller->submitRequest(request);
109 | }
110 |
111 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
112 |
113 | void ApplePS2Device::submitRequestAndBlock(PS2Request * request)
114 | {
115 | request->port = _port;
116 | _controller->submitRequestAndBlock(request);
117 | }
118 |
119 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
120 |
121 | UInt8 ApplePS2Device::setCommandByte(UInt8 setBits, UInt8 clearBits)
122 | {
123 | return _controller->setCommandByte(setBits, clearBits);
124 | }
125 |
126 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
127 |
128 | void ApplePS2Device::lock()
129 | {
130 | _controller->lock();
131 | }
132 |
133 | void ApplePS2Device::unlock()
134 | {
135 | _controller->unlock();
136 | }
137 |
138 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
139 |
140 | void ApplePS2Device::installInterruptAction(OSObject * target,
141 | PS2InterruptAction interruptAction,
142 | PS2PacketAction packetAction)
143 | {
144 | _client = target;
145 | _controller->installInterruptAction(_port);
146 | _interrupt_action = interruptAction;
147 | _packet_action = packetAction;
148 | }
149 |
150 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
151 |
152 | void ApplePS2Device::uninstallInterruptAction()
153 | {
154 | _controller->uninstallInterruptAction(_port);
155 | _interrupt_action = nullptr;
156 | _packet_action = nullptr;
157 | _client = nullptr;
158 | }
159 |
160 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
161 |
162 | void ApplePS2Device::installPowerControlAction(OSObject * target,
163 | PS2PowerControlAction action)
164 | {
165 | _power_action = action;
166 | }
167 |
168 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
169 |
170 | void ApplePS2Device::uninstallPowerControlAction()
171 | {
172 | _power_action = nullptr;
173 | }
174 |
175 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
176 |
177 | void ApplePS2Device::dispatchMessage(int message, void *data)
178 | {
179 | _controller->dispatchMessage(message, data);
180 | }
181 |
182 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
183 |
184 | IOReturn ApplePS2Device::startSMBusCompanion(OSDictionary *companionData, UInt8 smbusAddr)
185 | {
186 | return _controller->startSMBusCompanion(companionData, smbusAddr);
187 | }
188 |
189 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
190 |
191 | ApplePS2Controller* ApplePS2Device::getController()
192 | {
193 | return _controller;
194 | }
195 |
196 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
197 |
198 | PS2InterruptResult ApplePS2Device::interruptAction(UInt8 data)
199 | {
200 | if (_client == nullptr || _interrupt_action == nullptr)
201 | {
202 | return kPS2IR_packetBuffering;
203 | }
204 |
205 | return (*_interrupt_action)(_client, data);
206 | }
207 |
208 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
209 |
210 | void ApplePS2Device::packetActionInterrupt()
211 | {
212 | _interruptSource->interruptOccurred(0, 0, 0);
213 | }
214 |
215 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
216 |
217 | void ApplePS2Device::powerAction(UInt32 whatToDo)
218 | {
219 | if (_client == nullptr || _power_action == nullptr)
220 | {
221 | return;
222 | }
223 |
224 | (*_power_action)(_client, whatToDo);
225 | }
226 |
227 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
228 |
229 | void ApplePS2Device::packetAction(IOInterruptEventSource *, int)
230 | {
231 | if (_client == nullptr || _packet_action == nullptr)
232 | {
233 | return;
234 | }
235 |
236 | (*_packet_action)(_client);
237 | }
238 |
--------------------------------------------------------------------------------
/VoodooPS2Controller/ApplePS2KeyboardDevice.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * The contents of this file constitute Original Code as defined in and
7 | * are subject to the Apple Public Source License Version 1.1 (the
8 | * "License"). You may not use this file except in compliance with the
9 | * License. Please obtain a copy of the License at
10 | * http://www.apple.com/publicsource and read it before using this file.
11 | *
12 | * This Original Code and all software distributed under the License are
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 | * License for the specific language governing rights and limitations
18 | * under the License.
19 | *
20 | * @APPLE_LICENSE_HEADER_END@
21 | */
22 |
23 | #include "ApplePS2KeyboardDevice.h"
24 | #include "VoodooPS2Controller.h"
25 |
26 | // =============================================================================
27 | // ApplePS2KeyboardDevice Class Implementation
28 | //
29 |
30 | OSDefineMetaClassAndStructors(ApplePS2KeyboardDevice, ApplePS2Device);
31 |
--------------------------------------------------------------------------------
/VoodooPS2Controller/ApplePS2KeyboardDevice.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * The contents of this file constitute Original Code as defined in and
7 | * are subject to the Apple Public Source License Version 1.1 (the
8 | * "License"). You may not use this file except in compliance with the
9 | * License. Please obtain a copy of the License at
10 | * http://www.apple.com/publicsource and read it before using this file.
11 | *
12 | * This Original Code and all software distributed under the License are
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 | * License for the specific language governing rights and limitations
18 | * under the License.
19 | *
20 | * @APPLE_LICENSE_HEADER_END@
21 | */
22 |
23 | #ifndef _APPLEPS2KEYBOARDDEVICE_H
24 | #define _APPLEPS2KEYBOARDDEVICE_H
25 |
26 | #include "ApplePS2Device.h"
27 |
28 | class ApplePS2Controller;
29 |
30 | class EXPORT ApplePS2KeyboardDevice : public ApplePS2Device
31 | {
32 | typedef ApplePS2Device super;
33 | OSDeclareDefaultStructors(ApplePS2KeyboardDevice);
34 | };
35 |
36 | #endif /* !_APPLEPS2KEYBOARDDEVICE_H */
37 |
--------------------------------------------------------------------------------
/VoodooPS2Controller/ApplePS2MouseDevice.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * The contents of this file constitute Original Code as defined in and
7 | * are subject to the Apple Public Source License Version 1.1 (the
8 | * "License"). You may not use this file except in compliance with the
9 | * License. Please obtain a copy of the License at
10 | * http://www.apple.com/publicsource and read it before using this file.
11 | *
12 | * This Original Code and all software distributed under the License are
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 | * License for the specific language governing rights and limitations
18 | * under the License.
19 | *
20 | * @APPLE_LICENSE_HEADER_END@
21 | */
22 |
23 | #include "ApplePS2MouseDevice.h"
24 | #include "VoodooPS2Controller.h"
25 |
26 | // =============================================================================
27 | // ApplePS2MouseDevice Class Implementation
28 | //
29 |
30 | OSDefineMetaClassAndStructors(ApplePS2MouseDevice, ApplePS2Device);
31 |
--------------------------------------------------------------------------------
/VoodooPS2Controller/ApplePS2MouseDevice.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * The contents of this file constitute Original Code as defined in and
7 | * are subject to the Apple Public Source License Version 1.1 (the
8 | * "License"). You may not use this file except in compliance with the
9 | * License. Please obtain a copy of the License at
10 | * http://www.apple.com/publicsource and read it before using this file.
11 | *
12 | * This Original Code and all software distributed under the License are
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 | * License for the specific language governing rights and limitations
18 | * under the License.
19 | *
20 | * @APPLE_LICENSE_HEADER_END@
21 | */
22 |
23 | #ifndef _APPLEPS2MOUSEDEVICE_H
24 | #define _APPLEPS2MOUSEDEVICE_H
25 |
26 | #include "ApplePS2Device.h"
27 |
28 | class ApplePS2Controller;
29 |
30 | class EXPORT ApplePS2MouseDevice : public ApplePS2Device
31 | {
32 | typedef ApplePS2Device super;
33 | OSDeclareDefaultStructors(ApplePS2MouseDevice);
34 | };
35 |
36 | #endif /* !_APPLEPS2MOUSEDEVICE_H */
37 |
--------------------------------------------------------------------------------
/VoodooPS2Controller/VoodooPS2Controller-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleExecutable
6 | VoodooPS2Controller
7 | CFBundleGetInfoString
8 | ${MODULE_VERSION}, Copyright Apple Computer, Inc. 2000-2003, David Elliot 2007, RehabMan 2012-2013
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | Voodoo PS/2 Controller
15 | CFBundlePackageType
16 | KEXT
17 | CFBundleShortVersionString
18 | ${MODULE_VERSION}
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${MODULE_VERSION}
23 | IOKitPersonalities
24 |
25 | ACPI PS/2 Nub
26 |
27 | CFBundleIdentifier
28 | as.acidanthera.voodoo.driver.PS2Controller
29 | FindMouseDelay
30 | 100
31 | IOClass
32 | AppleACPIPS2Nub
33 | IONameMatch
34 |
35 | PNP0303
36 | PNP030B
37 | PNP0320
38 |
39 | IOProviderClass
40 | IOACPIPlatformDevice
41 | MouseNameMatch
42 |
43 | PNP0F03
44 | PNP0F0B
45 | PNP0F0E
46 | PNP0F13
47 |
48 |
49 | ApplePS2Controller
50 |
51 | CFBundleIdentifier
52 | as.acidanthera.voodoo.driver.PS2Controller
53 | IOClass
54 | ApplePS2Controller
55 | IONameMatch
56 | ps2controller
57 | IOProviderClass
58 | IOPlatformDevice
59 | Platform Profile
60 |
61 | Default
62 |
63 | MouseWakeFirst
64 |
65 | WakeDelay
66 | 10
67 |
68 | HPQOEM
69 |
70 | 1411
71 | ProBook
72 | 1619
73 | ProBook
74 | 161C
75 | ProBook
76 | 164F
77 | ProBook
78 | 167C
79 | ProBook
80 | 167E
81 | ProBook
82 | 1680
83 | ProBook
84 | 179B
85 | ProBook
86 | 179C
87 | ProBook
88 | 17A9
89 | ProBook
90 | 17F0
91 | ProBook
92 | 17F3
93 | ProBook
94 | 17F6
95 | ProBook
96 | 1942
97 | ProBook
98 | 1949
99 | ProBook
100 | 198F
101 | ProBook
102 | ProBook
103 |
104 | WakeDelay
105 | 0
106 |
107 | ProBook-102
108 | ProBook
109 | ProBook-87
110 | ProBook
111 |
112 |
113 | RM,deliverNotifications
114 |
115 |
116 |
117 | OSBundleCompatibleVersion
118 | ${MODULE_VERSION}
119 | OSBundleLibraries
120 |
121 | com.apple.iokit.IOACPIFamily
122 | 1.0.0d1
123 | com.apple.kpi.bsd
124 | 8.0.0
125 | com.apple.kpi.iokit
126 | 8.0.0
127 | com.apple.kpi.libkern
128 | 8.0.0
129 | com.apple.kpi.mach
130 | 8.0.0
131 | com.apple.kpi.unsupported
132 | 8.0.0
133 |
134 | OSBundleRequired
135 | Console
136 |
137 |
138 |
--------------------------------------------------------------------------------
/VoodooPS2Controller/VoodooPS2Controller.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * The contents of this file constitute Original Code as defined in and
7 | * are subject to the Apple Public Source License Version 1.1 (the
8 | * "License"). You may not use this file except in compliance with the
9 | * License. Please obtain a copy of the License at
10 | * http://www.apple.com/publicsource and read it before using this file.
11 | *
12 | * This Original Code and all software distributed under the License are
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 | * License for the specific language governing rights and limitations
18 | * under the License.
19 | *
20 | * @APPLE_LICENSE_HEADER_END@
21 | */
22 |
23 | #ifndef _APPLEPS2CONTROLLER_H
24 | #define _APPLEPS2CONTROLLER_H
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include "ApplePS2Device.h"
31 |
32 | class ApplePS2KeyboardDevice;
33 | class ApplePS2MouseDevice;
34 |
35 | //
36 | // This section describes the problem with the PS/2 controller design and what
37 | // we are doing about it (OUT_OF_ORDER_DATA_CORRECTION_FEATURE).
38 | //
39 | // While the controller processes requests sent by the client drivers, at some
40 | // point in most requests, a read needs to be made from the data port to check
41 | // an acknowledge or receive some sort of data. We illustrate this issue with
42 | // an example -- a write LEDs request to the keyboard:
43 | //
44 | // 1. Write Write LED command.
45 | // 2. Read 0xFA Verify the acknowledge (0xFA).
46 | // 3. Write Write LED state.
47 | // 4. Read 0xFA Verify the acknowledge (0xFA).
48 | //
49 | // The problem is that the keyboard (when it is enabled) can send key events
50 | // to the controller at any time, including when the controller is expecting
51 | // to read an acknowledge next. What ends up happening is this sequence:
52 | //
53 | // a. Write Write LED command.
54 | // b. Read 0x21 Keyboard reports [F] key was depressed, not realizing that
55 | // we're still expecting a response to the command we JUST
56 | // sent the keyboard. We receive 0x21 as a response to our
57 | // command, and figure the command failed.
58 | // c. Get 0xFA Keyboard NOW decides to respond to the command with an
59 | // acknowledge. We're not waiting to read anything, so
60 | // this byte gets dispatched to the driver's interrupt
61 | // handler, which spews out an error message saying it
62 | // wasn't expecting an acknowledge.
63 | //
64 | // What can we do about this? In the above case, we can take note of the fact
65 | // that we are specifically looking for the 0xFA acknowledgement byte (through
66 | // the information passed in the kPS2C_ReadAndCompare primitive). If we don't
67 | // receive this byte next on the input data stream, we put the byte we did get
68 | // aside for a moment, and give the keyboard (or mouse) a second chance to
69 | // respond correctly.
70 | //
71 | // If we receive the 0xFA acknowledgement byte on the second read, that we
72 | // assume that situation described above just happened. We transparently
73 | // dispatch the first byte to the driver's interrupt handler, where it was
74 | // meant to go, and return the second correct byte to the read-and-compare
75 | // logic, where it was meant to go. Everyone wins.
76 | //
77 | // The only situation this feature cannot help is where a kPS2C_ReadDataPort
78 | // primitive is issued in place of a kPS2C_ReadDataPortAndCompare primitive.
79 | // This is necessary in some requests because the driver does not know what
80 | // it is going to receive. This can be illustrated in the mouse get info
81 | // command.
82 | //
83 | // 1. Write Prepare to write to mouse.
84 | // 2. Write Write information command.
85 | // 3. Read 0xFA Verify the acknowledge (0xFA). __-> mouse can report mouse
86 | // 4. Read Get first information byte. __-> packet bytes in between
87 | // 5. Read Get second information byte. __-> these reads
88 | // 6. Rrad Get third information byte.
89 | //
90 | // Controller cannot build any defenses against this. It is suggested that the
91 | // driver writer disable the mouse first, then send any dangerous commands, and
92 | // re-enable the mouse when the command completes.
93 | //
94 | // Note that the OUT_OF_ORDER_DATA_CORRECTION_FEATURE can be turned off at
95 | // compile time. Please see the readDataPort:expecting: method for more
96 | // information about the assumptions necessary for this feature.
97 | //
98 |
99 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
100 | // Definitions
101 | //
102 |
103 | // Enable debugger support (eg. mini-monitor).
104 |
105 | #define DEBUGGER_SUPPORT 0
106 |
107 | // Enable dynamic "second chance" re-ordering of input stream data if a
108 | // command response fails to match the expected byte.
109 |
110 | #define OUT_OF_ORDER_DATA_CORRECTION_FEATURE 1
111 |
112 | // Enable handling of interrupt data in workloop instead of at interrupt
113 | // time. This way is easier to debug. For production use, this should
114 | // be zero, such that PS2 data is buffered at real interrupt time, and handled
115 | // as packets later in the workloop.
116 |
117 | #define HANDLE_INTERRUPT_DATA_LATER 0
118 | #define WATCHDOG_TIMER 0
119 |
120 | // Interrupt definitions.
121 |
122 | #define kIRQ_Keyboard 1
123 | #define kIRQ_Mouse 12
124 | #define kIPL_Keyboard 6
125 | #define kIPL_Mouse 3
126 |
127 | // Port timings.
128 |
129 | #define kDataDelay 7 // usec to delay before data is valid
130 |
131 | // Ports used to control the PS/2 keyboard/mouse and read data from it.
132 |
133 | #define kDataPort 0x60 // keyboard data & cmds (read/write)
134 | #define kCommandPort 0x64 // keybd status (read), command (write)
135 |
136 | // Bit definitions for kCommandPort read values (status).
137 |
138 | #define kOutputReady 0x01 // output (from keybd) buffer full
139 | #define kInputBusy 0x02 // input (to keybd) buffer full
140 | #define kSystemFlag 0x04 // "System Flag"
141 | #define kCommandLastSent 0x08 // 1 = cmd, 0 = data last sent
142 | #define kKeyboardInhibited 0x10 // 0 if keyboard inhibited
143 | #define kMouseData 0x20 // mouse data available
144 |
145 | // Watchdog timer definitions
146 |
147 | #define kWatchdogTimerInterval 100
148 |
149 | // Enable Mux commands
150 | // Constants are from Linux
151 | // https://github.com/torvalds/linux/blob/c2d7ed9d680fd14aa5486518bd0d0fa5963c6403/drivers/input/serio/i8042.c#L685-L693
152 |
153 | #define kDP_MuxCmd 0xF0
154 | #define kDP_EnableMuxCmd1 0x56
155 | #define kDP_GetMuxVersion 0xA4
156 | #define kDP_DisableMuxCmd1 0xF6
157 | #define kDP_DisableMuxCmd2 0xA5
158 |
159 | #if DEBUGGER_SUPPORT
160 | // Definitions for our internal keyboard queue (holds keys processed by the
161 | // interrupt-time mini-monitor-key-sequence detection code).
162 |
163 | #define kKeyboardQueueSize 32 // number of KeyboardQueueElements
164 |
165 | typedef struct KeyboardQueueElement KeyboardQueueElement;
166 | struct KeyboardQueueElement
167 | {
168 | queue_chain_t chain;
169 | UInt8 data;
170 | };
171 | #endif //DEBUGGER_SUPPORT
172 |
173 | // Info.plist definitions
174 |
175 | #define kDisableDevice "DisableDevice"
176 | #define kPlatformProfile "Platform Profile"
177 |
178 | #ifdef DEBUG
179 | #define kMergedConfiguration "Merged Configuration"
180 | #endif
181 |
182 | // ps2rst flags
183 | #define RESET_CONTROLLER_ON_BOOT 1
184 | #define RESET_CONTROLLER_ON_WAKEUP 2
185 |
186 | class IOACPIPlatformDevice;
187 |
188 | enum {
189 | kPS2PowerStateSleep = 0,
190 | kPS2PowerStateDoze = 1,
191 | kPS2PowerStateNormal = 2,
192 | kPS2PowerStateCount
193 | };
194 |
195 | // i8042 Mux indexes
196 | #define PS2_MUX_PORTS 4
197 |
198 | #define PS2_STA_MUX_MASK 0x03
199 | #define PS2_STA_MUX_SHIFT 0x06
200 |
201 | // Normally, the i8042 controller has 2 ports. With the mux active,
202 | // there are 5 ports. 1 Keyboard port and 4 mux ports. All the muxed ports
203 | // share the same IRQ. When the controller is in a multiplexed mode, 3
204 | // additional ports are added.
205 |
206 | enum {
207 | kPS2KbdIdx = 0,
208 | kPS2AuxIdx = 1,
209 | kPS2AuxMaxIdx = 2,
210 | kPS2MuxMaxIdx = PS2_MUX_PORTS + 1
211 | };
212 |
213 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
214 | // ApplePS2Controller Class Declaration
215 | //
216 |
217 | class EXPORT ApplePS2Controller : public IOService
218 | {
219 | typedef IOService super;
220 | OSDeclareDefaultStructors(ApplePS2Controller);
221 |
222 | public:
223 | // interrupt-time variables and functions
224 | #if HANDLE_INTERRUPT_DATA_LATER
225 | IOInterruptEventSource * _interruptSourceMouse {nullptr};
226 | IOInterruptEventSource * _interruptSourceKeyboard {nullptr};
227 | #endif
228 | IOInterruptEventSource * _interruptSourceQueue {nullptr};
229 |
230 | #if DEBUGGER_SUPPORT
231 | bool _debuggingEnabled {false};
232 |
233 | void lockController(int * state);
234 | void unlockController(int state);
235 |
236 | bool doEscape(UInt8 key);
237 | bool dequeueKeyboardData(UInt8 * key);
238 | void enqueueKeyboardData(UInt8 key);
239 | #endif //DEBUGGER_SUPPORT
240 |
241 | private:
242 | IOWorkLoop * _workLoop {nullptr};
243 | queue_head_t _requestQueue {nullptr};
244 | IOLock* _requestQueueLock {nullptr};
245 | IOLock* _cmdbyteLock {nullptr};
246 |
247 | bool _interruptInstalledKeyboard {false};
248 | int _interruptInstalledMouse {0};
249 |
250 | int _ignoreInterrupts {0};
251 | int _ignoreOutOfOrder {0};
252 |
253 | ApplePS2Device * _devices [kPS2MuxMaxIdx] {nullptr};
254 |
255 | IONotifier* _publishNotify {nullptr};
256 | IONotifier* _terminateNotify {nullptr};
257 |
258 | OSSet* _notificationServices {nullptr};
259 |
260 | #if DEBUGGER_SUPPORT
261 | IOSimpleLock * _controllerLock {nullptr}; // mach simple spin lock
262 |
263 | KeyboardQueueElement * _keyboardQueueAlloc {nullptr}; // queues' allocation space
264 | queue_head_t _keyboardQueue {nullptr}; // queue of available keys
265 | queue_head_t _keyboardQueueUnused {nullptr}; // queue of unused entries
266 |
267 | bool _extendedState {false};
268 | UInt16 _modifierState {0};
269 | #endif //DEBUGGER_SUPPORT
270 |
271 | thread_call_t _powerChangeThreadCall {0};
272 | UInt32 _currentPowerState {kPS2PowerStateNormal};
273 | bool _hardwareOffline {false};
274 | bool _suppressTimeout {false};
275 | int _wakedelay {10};
276 | bool _mouseWakeFirst {false};
277 | bool _muxPresent {false};
278 | size_t _nubsCount {0};
279 | IOCommandGate* _cmdGate {nullptr};
280 | #if WATCHDOG_TIMER
281 | IOTimerEventSource* _watchdogTimer {nullptr};
282 | #endif
283 | OSDictionary* _rmcfCache {nullptr};
284 | const OSSymbol* _deliverNotification {nullptr};
285 | const OSSymbol* _smbusCompanion {nullptr};
286 |
287 | int _resetControllerFlag {RESET_CONTROLLER_ON_BOOT | RESET_CONTROLLER_ON_WAKEUP};
288 | bool _kbdOnly {0};
289 |
290 | virtual PS2InterruptResult _dispatchDriverInterrupt(size_t port, UInt8 data);
291 | virtual void dispatchDriverInterrupt(size_t port, UInt8 data);
292 | #if HANDLE_INTERRUPT_DATA_LATER
293 | virtual void interruptOccurred(IOInterruptEventSource *, int);
294 | #endif
295 | void handleInterrupt(bool watchdog = false);
296 | #if WATCHDOG_TIMER
297 | void onWatchdogTimer();
298 | #endif
299 | virtual void processRequest(PS2Request * request);
300 | virtual void processRequestQueue(IOInterruptEventSource *, int);
301 |
302 | #if OUT_OF_ORDER_DATA_CORRECTION_FEATURE
303 | virtual UInt8 readDataPort(size_t port, UInt8 expectedByte);
304 | #endif
305 |
306 | virtual UInt8 readDataPort(size_t port);
307 | virtual void writeCommandPort(UInt8 byte);
308 | virtual void writeDataPort(UInt8 byte);
309 | void resetController(void);
310 | bool setMuxMode(bool);
311 | void flushDataPort(void);
312 | void resetDevices(void);
313 |
314 | static void interruptHandlerMouse(OSObject*, void* refCon, IOService*, int);
315 | static void interruptHandlerKeyboard(OSObject*, void* refCon, IOService*, int);
316 |
317 | void notificationHandlerPublishGated(IOService * newService, IONotifier * notifier);
318 | bool notificationHandlerPublish(void * refCon, IOService * newService, IONotifier * notifier);
319 |
320 | void notificationHandlerTerminateGated(IOService * newService, IONotifier * notifier);
321 | bool notificationHandlerTerminate(void * refCon, IOService * newService, IONotifier * notifier);
322 |
323 | void dispatchMessageGated(int* message, void* data);
324 |
325 | static void setPowerStateCallout(thread_call_param_t param0,
326 | thread_call_param_t param1);
327 |
328 | static IOReturn setPowerStateAction(OSObject * target,
329 | void * arg0, void * arg1,
330 | void * arg2, void * arg3);
331 |
332 | virtual void setPowerStateGated(UInt32 newPowerState);
333 |
334 | virtual void dispatchDriverPowerControl(UInt32 whatToDo, size_t port);
335 | void free(void) override;
336 | IOReturn setPropertiesGated(OSObject* props);
337 | void submitRequestAndBlockGated(PS2Request* request);
338 |
339 | size_t getPortFromStatus(UInt8 status);
340 |
341 | public:
342 | bool init(OSDictionary * properties) override;
343 | ApplePS2Controller* probe(IOService* provider, SInt32* score) override;
344 | bool start(IOService * provider) override;
345 | void stop(IOService * provider) override;
346 |
347 | IOWorkLoop * getWorkLoop() const override;
348 |
349 | void enableMuxPorts();
350 | virtual void installInterruptAction(size_t port);
351 | virtual void uninstallInterruptAction(size_t port);
352 |
353 | virtual PS2Request* allocateRequest(int max = kMaxCommands);
354 | virtual void freeRequest(PS2Request * request);
355 | virtual bool submitRequest(PS2Request * request);
356 | virtual void submitRequestAndBlock(PS2Request * request);
357 | virtual UInt8 setCommandByte(UInt8 setBits, UInt8 clearBits);
358 | void setCommandByteGated(PS2Request* request);
359 |
360 | IOReturn setPowerState(unsigned long powerStateOrdinal,
361 | IOService * policyMaker) override;
362 |
363 | virtual void dispatchMessage(int message, void* data);
364 |
365 | IOReturn setProperties(OSObject* props) override;
366 | virtual void lock();
367 | virtual void unlock();
368 |
369 | static OSDictionary* getConfigurationNode(IORegistryEntry* entry, OSDictionary* list);
370 | virtual OSDictionary* makeConfigurationNode(OSDictionary* list, const char* section);
371 |
372 | OSDictionary* getConfigurationOverride(IOACPIPlatformDevice* acpi, const char* method);
373 | OSObject* translateArray(OSArray* array);
374 | OSObject* translateEntry(OSObject* obj);
375 |
376 | IOReturn startSMBusCompanion(OSDictionary *companionData, UInt8 smbusAddr);
377 | };
378 |
379 | #endif /* _APPLEPS2CONTROLLER_H */
380 |
--------------------------------------------------------------------------------
/VoodooPS2Controller/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
--------------------------------------------------------------------------------
/VoodooPS2Keyboard/VoodooPS2Keyboard-Breakless-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleGetInfoString
6 | ${MODULE_VERSION}, Copyright Apple Computer, Inc. 2000-2003, RehabMan 2012-2013
7 | CFBundleExecutable
8 | VoodooPS2Keyboard
9 | CFBundleIdentifier
10 | as.acidanthera.voodoo.driver.PS2Keyboard
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | Voodoo PS/2 Keyboard
15 | CFBundlePackageType
16 | KEXT
17 | CFBundleShortVersionString
18 | ${MODULE_VERSION}
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${MODULE_VERSION}
23 | IOKitPersonalities
24 |
25 | ApplePS2Keyboard
26 |
27 | CFBundleIdentifier
28 | as.acidanthera.voodoo.driver.PS2Keyboard
29 | IOClass
30 | ApplePS2Keyboard
31 | IOProviderClass
32 | ApplePS2KeyboardDevice
33 | Platform Profile
34 |
35 | Default
36 |
37 | Make Application key into Apple Fn key
38 |
39 | Make Application key into right windows
40 |
41 | Make right modifier keys into Hangul and Hanja
42 |
43 | Swap capslock and left control
44 |
45 | Swap command and option
46 |
47 | Use ISO layout keyboard
48 |
49 | alt_handler_id
50 | 3
51 | SleepPressTime
52 | 3000
53 | Breakless PS2
54 |
55 | ;Items must be strings in the form of breaklessscan (in hex)
56 | e05f
57 | e012
58 | e017
59 | e06e
60 | e00a
61 | e009
62 | e020
63 | e02e
64 | e030
65 | e010
66 | e022
67 | e019
68 |
69 | Function Keys Standard
70 |
71 | ;Items must be strings in the form of scanfrom=scanto (in hex)
72 | ;The following 12 items map Fn+fkeys to Fn+fkeys
73 | e05f=e05f
74 | e012=e012
75 | e017=e017
76 | e06e=e06e
77 | e00a=e00a
78 | e009=e009
79 | e020=e020
80 | e02e=e02e
81 | e030=e030
82 | e010=e010
83 | e022=e022
84 | e019=e019
85 | ;The following 12 items map fkeys to fkeys
86 | 3b=3b
87 | 3c=3c
88 | 3d=3d
89 | 3e=3e
90 | 3f=3f
91 | 40=40
92 | 41=41
93 | 42=42
94 | 43=43
95 | 44=44
96 | 57=57
97 | 58=58
98 |
99 | Function Keys Special
100 |
101 | ;Items must be strings in the form of scanfrom=scanto (in hex)
102 | ;The following 12 items map Fn+fkeys to fkeys
103 | e05f=3b
104 | e012=3c
105 | e017=3d
106 | e06e=3e
107 | e00a=3f
108 | e009=40
109 | e020=41
110 | e02e=42
111 | e030=43
112 | e010=44
113 | e022=57
114 | e019=58
115 | ;The following 12 items map fkeys to Fn+fkeys
116 | 3b=e05f
117 | 3c=e012
118 | 3d=e017
119 | 3e=e06e
120 | 3f=e00a
121 | 40=e009
122 | 41=e020
123 | 42=e02e
124 | 43=e030
125 | 44=e010
126 | 57=e022
127 | 58=e019
128 |
129 | Custom PS2 Map
130 |
131 | ;Items must be strings in the form of scanfrom=scanto (in hex)
132 |
133 | Custom ADB Map
134 |
135 | ;Items must be strings in the form of scanfrom=adbto (in hex)
136 |
137 | LogScanCodes
138 | 0
139 |
140 |
141 |
142 |
143 | OSBundleLibraries
144 |
145 | com.apple.iokit.IOHIDFamily
146 | 1.0.0b1
147 | com.apple.kpi.bsd
148 | 8.0.0
149 | com.apple.kpi.iokit
150 | 8.0.0
151 | com.apple.kpi.libkern
152 | 8.0.0
153 | com.apple.kpi.mach
154 | 8.0.0
155 | com.apple.kpi.unsupported
156 | 8.0.0
157 | as.acidanthera.voodoo.driver.PS2Controller
158 | ${MODULE_VERSION}
159 |
160 | OSBundleRequired
161 | Console
162 |
163 |
164 |
--------------------------------------------------------------------------------
/VoodooPS2Keyboard/VoodooPS2Keyboard-RemapFN-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleGetInfoString
6 | ${MODULE_VERSION}, Copyright Apple Computer, Inc. 2000-2003, RehabMan 2012-2013
7 | CFBundleExecutable
8 | VoodooPS2Keyboard
9 | CFBundleIdentifier
10 | as.acidanthera.voodoo.driver.PS2Keyboard
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | Voodoo PS/2 Keyboard
15 | CFBundlePackageType
16 | KEXT
17 | CFBundleShortVersionString
18 | ${MODULE_VERSION}
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${MODULE_VERSION}
23 | IOKitPersonalities
24 |
25 | ApplePS2Keyboard
26 |
27 | CFBundleIdentifier
28 | as.acidanthera.voodoo.driver.PS2Keyboard
29 | IOClass
30 | ApplePS2Keyboard
31 | IOProviderClass
32 | ApplePS2KeyboardDevice
33 | Platform Profile
34 |
35 | Default
36 |
37 | Make Application key into Apple Fn key
38 |
39 | Make Application key into right windows
40 |
41 | Make right modifier keys into Hangul and Hanja
42 |
43 | Swap capslock and left control
44 |
45 | Swap command and option
46 |
47 | Use ISO layout keyboard
48 |
49 | alt_handler_id
50 | 3
51 | SleepPressTime
52 | 3000
53 | Breakless PS2
54 |
55 | ;Items must be strings in the form of breaklessscan (in hex)
56 |
57 | Function Keys Standard
58 |
59 | ;Items must be strings in the form of scanfrom=scanto (in hex)
60 | ;The following 12 items map Fn+fkeys to Fn+fkeys
61 | e05f=e05f
62 | e012=e012
63 | e017=e017
64 | e06e=e06e
65 | e00a=e00a
66 | e009=e009
67 | e020=e020
68 | e02e=e02e
69 | e030=e030
70 | e010=e010
71 | e022=e022
72 | e019=e019
73 | ;The following 12 items map fkeys to fkeys
74 | 3b=3b
75 | 3c=3c
76 | 3d=3d
77 | 3e=3e
78 | 3f=3f
79 | 40=40
80 | 41=41
81 | 42=42
82 | 43=43
83 | 44=44
84 | 57=57
85 | 58=58
86 |
87 | Function Keys Special
88 |
89 | ;Items must be strings in the form of scanfrom=scanto (in hex)
90 | ;The following 12 items map Fn+fkeys to fkeys
91 | e05f=3b
92 | e012=3c
93 | e017=3d
94 | e06e=3e
95 | e00a=3f
96 | e009=40
97 | e020=41
98 | e02e=42
99 | e030=43
100 | e010=44
101 | e022=57
102 | e019=58
103 | ;The following 12 items map fkeys to Fn+fkeys
104 | 3b=e05f
105 | 3c=e012
106 | 3d=e017
107 | 3e=e06e
108 | 3f=e00a
109 | 40=e009
110 | 41=e020
111 | 42=e02e
112 | 43=e030
113 | 44=e010
114 | 57=e022
115 | 58=e019
116 |
117 | Custom PS2 Map
118 |
119 | ;Items must be strings in the form of scanfrom=scanto (in hex)
120 |
121 | Custom ADB Map
122 |
123 | ;Items must be strings in the form of scanfrom=adbto (in hex)
124 |
125 | LogScanCodes
126 | 0
127 |
128 |
129 |
130 |
131 | OSBundleLibraries
132 |
133 | com.apple.iokit.IOHIDFamily
134 | 1.0.0b1
135 | com.apple.kpi.bsd
136 | 8.0.0
137 | com.apple.kpi.iokit
138 | 8.0.0
139 | com.apple.kpi.libkern
140 | 8.0.0
141 | com.apple.kpi.mach
142 | 8.0.0
143 | com.apple.kpi.unsupported
144 | 8.0.0
145 | as.acidanthera.voodoo.driver.PS2Controller
146 | ${MODULE_VERSION}
147 |
148 | OSBundleRequired
149 | Console
150 |
151 |
152 |
--------------------------------------------------------------------------------
/VoodooPS2Keyboard/VoodooPS2Keyboard.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/acidanthera/VoodooPS2/b6713c37b9919bd95c3b7f4d484bd049371bcfc1/VoodooPS2Keyboard/VoodooPS2Keyboard.cpp
--------------------------------------------------------------------------------
/VoodooPS2Keyboard/VoodooPS2Keyboard.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * The contents of this file constitute Original Code as defined in and
7 | * are subject to the Apple Public Source License Version 1.1 (the
8 | * "License"). You may not use this file except in compliance with the
9 | * License. Please obtain a copy of the License at
10 | * http://www.apple.com/publicsource and read it before using this file.
11 | *
12 | * This Original Code and all software distributed under the License are
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 | * License for the specific language governing rights and limitations
18 | * under the License.
19 | *
20 | * @APPLE_LICENSE_HEADER_END@
21 | */
22 |
23 | #ifndef _APPLEPS2KEYBOARD_H
24 | #define _APPLEPS2KEYBOARD_H
25 |
26 | #include
27 | #include "../VoodooPS2Controller/ApplePS2KeyboardDevice.h"
28 | #include
29 |
30 | #include
31 |
32 | #include
33 |
34 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
35 | // Definitions used to keep track of key state. Key up/down state is tracked
36 | // in a bit list. Bits are set for key-down, and cleared for key-up. The bit
37 | // vector and macros for it's manipulation are defined here.
38 | //
39 |
40 | #define KBV_NUM_KEYCODES 512 // related with ADB_CONVERTER_LEN
41 | #define KBV_BITS_PER_UNIT 32 // for UInt32
42 | #define KBV_BITS_MASK 31
43 | #define KBV_BITS_SHIFT 5 // 1<<5 == 32, for cheap divide
44 | #define KBV_NUNITS ((KBV_NUM_KEYCODES + \
45 | (KBV_BITS_PER_UNIT-1))/KBV_BITS_PER_UNIT)
46 |
47 | #define KBV_KEYDOWN(n) \
48 | (_keyBitVector)[((n)>>KBV_BITS_SHIFT)] |= (1U << ((n) & KBV_BITS_MASK))
49 |
50 | #define KBV_KEYUP(n) \
51 | (_keyBitVector)[((n)>>KBV_BITS_SHIFT)] &= ~(1U << ((n) & KBV_BITS_MASK))
52 |
53 | #define KBV_IS_KEYDOWN(n) \
54 | (((_keyBitVector)[((n)>>KBV_BITS_SHIFT)] & (1U << ((n) & KBV_BITS_MASK))) != 0)
55 |
56 | #define KBV_NUM_SCANCODES 256
57 |
58 | // Special bits for _PS2ToPS2Map
59 |
60 | #define kBreaklessKey 0x01 // keys with this flag don't generate break codes
61 |
62 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
63 | // ApplePS2Keyboard Class Declaration
64 | //
65 |
66 | #define kPacketLength (2+6+8) // 2 bytes for key data, 6-bytes not used, 8 bytes for timestamp
67 | #define kPacketKeyOffset 0
68 | #define kPacketTimeOffset 8
69 | #define kPacketKeyDataLength 2
70 |
71 | class EXPORT ApplePS2Keyboard : public IOHIKeyboard
72 | {
73 | typedef IOHIKeyboard super;
74 | OSDeclareDefaultStructors(ApplePS2Keyboard);
75 |
76 | private:
77 | ApplePS2KeyboardDevice * _device;
78 | UInt32 _keyBitVector[KBV_NUNITS];
79 | UInt8 _extendCount;
80 | RingBuffer _ringBuffer;
81 | UInt8 _lastdata;
82 | bool _interruptHandlerInstalled;
83 | bool _powerControlHandlerInstalled;
84 | UInt8 _ledState;
85 | IOCommandGate* _cmdGate;
86 |
87 | // for keyboard remapping
88 | UInt16 _PS2modifierState;
89 | UInt16 _PS2ToPS2Map[KBV_NUM_SCANCODES*2];
90 | UInt16 _PS2flags[KBV_NUM_SCANCODES*2];
91 | UInt8 _PS2ToADBMap[ADB_CONVERTER_LEN];
92 | UInt8 _PS2ToADBMapMapped[ADB_CONVERTER_LEN];
93 | UInt32 _fkeymode;
94 | bool _fkeymodesupported;
95 | OSArray* _keysStandard;
96 | OSArray* _keysSpecial;
97 | bool _swapcommandoption;
98 | int _logscancodes;
99 | UInt32 _f12ejectdelay;
100 | enum { kTimerSleep, kTimerEject } _timerFunc;
101 | bool _remapPrntScr;
102 | bool _numLockSupport;
103 | bool _numLockOnAtBoot;
104 |
105 | // dealing with sleep key delay
106 | IOTimerEventSource* _sleepEjectTimer;
107 | UInt32 _maxsleeppresstime;
108 |
109 | // ACPI support for keyboard backlight
110 | IOACPIPlatformDevice * _provider;
111 | int * _backlightLevels;
112 | int _backlightCount;
113 |
114 | // special hack for Envy brightness access, while retaining F2/F3 functionality
115 | bool _brightnessHack;
116 |
117 | // Toggle keyboard input along with touchpad when Windows+printscreen is pressed
118 | bool _disableInput;
119 |
120 | // macro processing
121 | OSData** _macroTranslation;
122 | OSData** _macroInversion;
123 | UInt8* _macroBuffer;
124 | int _macroMax;
125 | int _macroCurrent;
126 | uint64_t _macroMaxTime;
127 | IOTimerEventSource* _macroTimer;
128 |
129 | // fix caps lock led
130 | bool _ignoreCapsLedChange;
131 |
132 | virtual bool dispatchKeyboardEventWithPacket(const UInt8* packet);
133 | virtual void setLEDs(UInt8 ledState);
134 | virtual void setKeyboardEnable(bool enable);
135 | virtual void initKeyboard();
136 | virtual void setDevicePowerState(UInt32 whatToDo);
137 | void modifyKeyboardBacklight(int adbKeyCode, bool goingDown);
138 | void modifyScreenBrightness(int adbKeyCode, bool goingDown);
139 | inline bool checkModifierState(UInt16 mask)
140 | { return mask == (_PS2modifierState & mask); }
141 | inline bool checkModifierStateAny(UInt16 mask)
142 | { return (_PS2modifierState & mask); }
143 |
144 | void loadCustomPS2Map(OSArray* pArray);
145 | void loadBreaklessPS2(OSDictionary* dict, const char* name);
146 | void loadCustomADBMap(OSDictionary* dict, const char* name);
147 | void setParamPropertiesGated(OSDictionary* dict);
148 | void onSleepEjectTimer(void);
149 |
150 | static OSData** loadMacroData(OSDictionary* dict, const char* name);
151 | static void freeMacroData(OSData** data);
152 | void onMacroTimer(void);
153 | bool invertMacros(const UInt8* packet);
154 | void dispatchInvertBuffer();
155 | static bool compareMacro(const UInt8* packet, const UInt8* data, int count);
156 |
157 | protected:
158 | const unsigned char * defaultKeymapOfLength(UInt32 * length) override;
159 | void setAlphaLockFeedback(bool locked) override;
160 | void setNumLockFeedback(bool locked) override;
161 | UInt32 maxKeyCodes() override;
162 | inline void dispatchKeyboardEventX(unsigned int keyCode, bool goingDown, uint64_t time)
163 | { dispatchKeyboardEvent(keyCode, goingDown, *(AbsoluteTime*)&time); }
164 | inline void setTimerTimeout(IOTimerEventSource* timer, uint64_t time)
165 | { timer->setTimeout(*(AbsoluteTime*)&time); }
166 | inline void cancelTimer(IOTimerEventSource* timer)
167 | { timer->cancelTimeout(); }
168 |
169 | public:
170 | bool init(OSDictionary * dict) override;
171 | ApplePS2Keyboard * probe(IOService * provider, SInt32 * score) override;
172 |
173 | bool start(IOService * provider) override;
174 | void stop(IOService * provider) override;
175 |
176 | virtual PS2InterruptResult interruptOccurred(UInt8 scanCode);
177 | virtual void packetReady();
178 |
179 | UInt32 deviceType() override;
180 | UInt32 interfaceID() override;
181 |
182 | IOReturn setParamProperties(OSDictionary* dict) override;
183 | IOReturn setProperties (OSObject *props) override;
184 |
185 | IOReturn message(UInt32 type, IOService* provider, void* argument) override;
186 | };
187 |
188 | #endif /* _APPLEPS2KEYBOARD_H */
189 |
--------------------------------------------------------------------------------
/VoodooPS2Keyboard/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
--------------------------------------------------------------------------------
/VoodooPS2Mouse/VoodooPS2Mouse-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleExecutable
6 | VoodooPS2Mouse
7 | CFBundleGetInfoString
8 | ${MODULE_VERSION}, Copyright Apple Computer, Inc. 2000-2004, Slice 2010, RehabMan 2012-2013
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | Voodoo PS/2 Mouse
15 | CFBundlePackageType
16 | KEXT
17 | CFBundleShortVersionString
18 | ${MODULE_VERSION}
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${MODULE_VERSION}
23 | IOKitPersonalities
24 |
25 | ApplePS2Mouse
26 |
27 | CFBundleIdentifier
28 | as.acidanthera.voodoo.driver.PS2Mouse
29 | IOClass
30 | ApplePS2Mouse
31 | IOProviderClass
32 | ApplePS2MouseDevice
33 | Platform Profile
34 |
35 | Default
36 |
37 | ButtonCount
38 | 3
39 | DefaultResolution
40 | 240
41 | DisableDevice
42 |
43 | FakeMiddleButton
44 |
45 | ForceDefaultResolution
46 |
47 | ForceSetResolution
48 |
49 | MiddleClickTime
50 | 100000000
51 | MouseCount
52 | 0
53 | MouseYInverter
54 | 1
55 | ResolutionMode
56 | 3
57 | ScrollResolution
58 | 5
59 | ScrollYInverter
60 | 1
61 | WakeDelay
62 | 1000
63 |
64 |
65 |
66 |
67 | OSBundleLibraries
68 |
69 | com.apple.iokit.IOHIDFamily
70 | 1.0.0b1
71 | com.apple.kpi.iokit
72 | 9.0.0
73 | com.apple.kpi.libkern
74 | 9.0.0
75 | com.apple.kpi.mach
76 | 9.0.0
77 | as.acidanthera.voodoo.driver.PS2Controller
78 | ${MODULE_VERSION}
79 |
80 | OSBundleRequired
81 | Console
82 |
83 |
84 |
--------------------------------------------------------------------------------
/VoodooPS2Mouse/VoodooPS2Mouse.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * The contents of this file constitute Original Code as defined in and
7 | * are subject to the Apple Public Source License Version 1.1 (the
8 | * "License"). You may not use this file except in compliance with the
9 | * License. Please obtain a copy of the License at
10 | * http://www.apple.com/publicsource and read it before using this file.
11 | *
12 | * This Original Code and all software distributed under the License are
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 | * License for the specific language governing rights and limitations
18 | * under the License.
19 | *
20 | * @APPLE_LICENSE_HEADER_END@
21 | */
22 |
23 | #ifndef _APPLEPS2MOUSE_H
24 | #define _APPLEPS2MOUSE_H
25 |
26 | #include "../VoodooPS2Controller/ApplePS2MouseDevice.h"
27 | #include
28 |
29 | #include
30 | #include
31 |
32 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
33 | // Local Declarations
34 | //
35 |
36 | #define kPacketLengthMax 4
37 | #define kPacketLengthStandard 3
38 | #define kPacketLengthIntellimouse 4
39 |
40 | typedef enum
41 | {
42 | kMouseTypeStandard = 0x00,
43 | kMouseTypeIntellimouse = 0x03,
44 | kMouseTypeIntellimouseExplorer = 0x04
45 | } PS2MouseId;
46 |
47 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
48 | // ApplePS2Mouse Class Declaration
49 | //
50 |
51 | class EXPORT ApplePS2Mouse : public IOHIPointing
52 | {
53 | typedef IOHIPointing super;
54 | OSDeclareDefaultStructors(ApplePS2Mouse);
55 |
56 | private:
57 | ApplePS2MouseDevice * _device;
58 | bool _interruptHandlerInstalled;
59 | bool _powerControlHandlerInstalled;
60 | RingBuffer _ringBuffer;
61 | UInt32 _packetByteCount;
62 | UInt8 _lastdata;
63 | UInt32 _packetLength;
64 | IOFixed _resolution; // (dots per inch)
65 | PS2MouseId _type;
66 | int _buttonCount;
67 | UInt32 _mouseInfoBytes;
68 | UInt32 _mouseResetCount;
69 | IOCommandGate* _cmdGate;
70 | int defres;
71 | int forceres;
72 | int mouseyinverter;
73 | int scrollyinverter;
74 | int forcesetres;
75 | int32_t resmode;
76 | int32_t scrollres;
77 | int wakedelay;
78 |
79 | // for middle button simulation
80 | enum mbuttonstate
81 | {
82 | STATE_NOBUTTONS,
83 | STATE_MIDDLE,
84 | STATE_WAIT4TWO,
85 | STATE_WAIT4NONE,
86 | STATE_NOOP,
87 | } _mbuttonstate;
88 |
89 | UInt32 lastbuttons;
90 | UInt32 _pendingbuttons;
91 | uint64_t _buttontime;
92 | IOTimerEventSource* _buttonTimer;
93 | uint64_t _maxmiddleclicktime;
94 | int _fakemiddlebutton;
95 |
96 | void onButtonTimer(void);
97 | enum MBComingFrom { fromTimer, fromMouse };
98 | UInt32 middleButton(UInt32 butttons, uint64_t now, MBComingFrom from);
99 |
100 | virtual void dispatchRelativePointerEventWithPacket(UInt8 * packet,
101 | UInt32 packetSize);
102 | virtual UInt8 getMouseID();
103 | virtual UInt32 getMouseInformation();
104 | virtual PS2MouseId setIntellimouseMode();
105 | virtual void setMouseEnable(bool enable);
106 | virtual void setMouseSampleRate(UInt8 sampleRate);
107 | virtual void setMouseResolution(UInt8 resolution);
108 | virtual void initMouse();
109 | virtual void resetMouse();
110 | virtual void setDevicePowerState(UInt32 whatToDo);
111 |
112 | void setParamPropertiesGated(OSDictionary * dict);
113 |
114 | protected:
115 | IOItemCount buttonCount() override;
116 | IOFixed resolution() override;
117 | inline void dispatchRelativePointerEventX(int dx, int dy, UInt32 buttonState, uint64_t now)
118 | { dispatchRelativePointerEvent(dx, dy, buttonState, *(AbsoluteTime*)&now); }
119 | inline void dispatchScrollWheelEventX(short deltaAxis1, short deltaAxis2, short deltaAxis3, uint64_t now)
120 | { dispatchScrollWheelEvent(deltaAxis1, deltaAxis2, deltaAxis3, *(AbsoluteTime*)&now); }
121 | inline void setTimerTimeout(IOTimerEventSource* timer, uint64_t time)
122 | { timer->setTimeout(*(AbsoluteTime*)&time); }
123 | inline void cancelTimer(IOTimerEventSource* timer)
124 | { timer->cancelTimeout(); }
125 | public:
126 | bool init(OSDictionary * properties) override;
127 | ApplePS2Mouse * probe(IOService * provider, SInt32 * score) override;
128 |
129 | bool start(IOService * provider) override;
130 | void stop(IOService * provider) override;
131 |
132 | virtual PS2InterruptResult interruptOccurred(UInt8 data);
133 | virtual void packetReady();
134 |
135 | UInt32 deviceType() override;
136 | UInt32 interfaceID() override;
137 |
138 | IOReturn setParamProperties(OSDictionary * dict) override;
139 | IOReturn setProperties (OSObject *props) override;
140 | };
141 |
142 | #endif /* _APPLEPS2MOUSE_H */
143 |
--------------------------------------------------------------------------------
/VoodooPS2Mouse/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
--------------------------------------------------------------------------------
/VoodooPS2Trackpad/VoodooPS2ALPSGlidePoint.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * The contents of this file constitute Original Code as defined in and
7 | * are subject to the Apple Public Source License Version 1.2 (the
8 | * "License"). You may not use this file except in compliance with the
9 | * License. Please obtain a copy of the License at
10 | * http://www.apple.com/publicsource and read it before using this file.
11 | *
12 | * This Original Code and all software distributed under the License are
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 | * License for the specific language governing rights and limitations
18 | * under the License.
19 | *
20 | * @APPLE_LICENSE_HEADER_END@
21 | */
22 |
23 | #ifndef _APPLEPS2ALPSTOUCHPAD_H
24 | #define _APPLEPS2ALPSTOUCHPAD_H
25 |
26 | #include "ApplePS2MouseDevice.h"
27 | #include
28 | #include
29 | #include "VoodooInputMultitouch/VoodooInputEvent.h"
30 | #include "VoodooPS2TrackpadCommon.h"
31 |
32 | #define ALPS_PROTO_V1 0x100
33 | #define ALPS_PROTO_V2 0x200
34 | #define ALPS_PROTO_V3 0x300
35 | #define ALPS_PROTO_V3_RUSHMORE 0x310
36 | #define ALPS_PROTO_V4 0x400
37 | #define ALPS_PROTO_V5 0x500
38 | #define ALPS_PROTO_V6 0x600
39 | #define ALPS_PROTO_V7 0x700 /* t3btl t4s */
40 | #define ALPS_PROTO_V8 0x800 /* SS4btl SS4s */
41 | #define ALPS_PROTO_V9 0x900 /* ss3btl */
42 |
43 | #define MAX_TOUCHES 5
44 |
45 | #define DOLPHIN_COUNT_PER_ELECTRODE 64
46 | #define DOLPHIN_PROFILE_XOFFSET 8 /* x-electrode offset */
47 | #define DOLPHIN_PROFILE_YOFFSET 1 /* y-electrode offset */
48 |
49 | struct alps_virtual_finger_state {
50 | UInt32 x;
51 | UInt32 y;
52 | uint8_t pressure;
53 | bool touch;
54 | bool button;
55 | MT2FingerType fingerType;
56 | };
57 |
58 | /*
59 | * enum SS4_PACKET_ID - defines the packet type for V8
60 | * SS4_PACKET_ID_IDLE: There's no finger and no button activity.
61 | * SS4_PACKET_ID_ONE: There's one finger on touchpad
62 | * or there's button activities.
63 | * SS4_PACKET_ID_TWO: There's two or more fingers on touchpad
64 | * SS4_PACKET_ID_MULTI: There's three or more fingers on touchpad
65 | * SS4_PACKET_ID_STICK: A stick pointer packet
66 | */
67 | enum SS4_PACKET_ID {
68 | SS4_PACKET_ID_IDLE = 0,
69 | SS4_PACKET_ID_ONE,
70 | SS4_PACKET_ID_TWO,
71 | SS4_PACKET_ID_MULTI,
72 | SS4_PACKET_ID_STICK,
73 | };
74 |
75 | #define SS4_COUNT_PER_ELECTRODE 256
76 | #define SS4_NUMSENSOR_XOFFSET 7
77 | #define SS4_NUMSENSOR_YOFFSET 7
78 | #define SS4_MIN_PITCH_MM 50
79 |
80 | #define SS4_MASK_NORMAL_BUTTONS 0x07
81 |
82 | #define SS4PLUS_COUNT_PER_ELECTRODE 128
83 | #define SS4PLUS_NUMSENSOR_XOFFSET 16
84 | #define SS4PLUS_NUMSENSOR_YOFFSET 5
85 | #define SS4PLUS_MIN_PITCH_MM 37
86 |
87 | #define IS_SS4PLUS_DEV(_b) (((_b[0]) == 0x73) && \
88 | ((_b[1]) == 0x03) && \
89 | ((_b[2]) == 0x28) \
90 | )
91 |
92 | #define SS4_IS_IDLE_V2(_b) (((_b[0]) == 0x18) && \
93 | ((_b[1]) == 0x10) && \
94 | ((_b[2]) == 0x00) && \
95 | ((_b[3] & 0x88) == 0x08) && \
96 | ((_b[4]) == 0x10) && \
97 | ((_b[5]) == 0x00) \
98 | )
99 |
100 | #define SS4_1F_X_V2(_b) (((_b[0]) & 0x0007) | \
101 | ((_b[1] << 3) & 0x0078) | \
102 | ((_b[1] << 2) & 0x0380) | \
103 | ((_b[2] << 5) & 0x1C00) \
104 | )
105 |
106 | #define SS4_1F_Y_V2(_b) (((_b[2]) & 0x000F) | \
107 | ((_b[3] >> 2) & 0x0030) | \
108 | ((_b[4] << 6) & 0x03C0) | \
109 | ((_b[4] << 5) & 0x0C00) \
110 | )
111 |
112 | #define SS4_1F_Z_V2(_b) (((_b[5]) & 0x0F) | \
113 | ((_b[5] >> 1) & 0x70) | \
114 | ((_b[4]) & 0x80) \
115 | )
116 |
117 | #define SS4_1F_LFB_V2(_b) (((_b[2] >> 4) & 0x01) == 0x01)
118 |
119 | #define SS4_MF_LF_V2(_b, _i) ((_b[1 + (_i) * 3] & 0x0004) == 0x0004)
120 |
121 | #define SS4_BTN_V2(_b) ((_b[0] >> 5) & SS4_MASK_NORMAL_BUTTONS)
122 |
123 | #define SS4_STD_MF_X_V2(_b, _i) (((_b[0 + (_i) * 3] << 5) & 0x00E0) | \
124 | ((_b[1 + _i * 3] << 5) & 0x1F00) \
125 | )
126 |
127 | #define SS4_PLUS_STD_MF_X_V2(_b, _i) (((_b[0 + (_i) * 3] << 4) & 0x0070) | \
128 | ((_b[1 + (_i) * 3] << 4) & 0x0F80) \
129 | )
130 |
131 | #define SS4_STD_MF_Y_V2(_b, _i) (((_b[1 + (_i) * 3] << 3) & 0x0010) | \
132 | ((_b[2 + (_i) * 3] << 5) & 0x01E0) | \
133 | ((_b[2 + (_i) * 3] << 4) & 0x0E00) \
134 | )
135 |
136 | #define SS4_BTL_MF_X_V2(_b, _i) (SS4_STD_MF_X_V2(_b, _i) | \
137 | ((_b[0 + (_i) * 3] >> 3) & 0x0010) \
138 | )
139 |
140 | #define SS4_PLUS_BTL_MF_X_V2(_b, _i) (SS4_PLUS_STD_MF_X_V2(_b, _i) | \
141 | ((_b[0 + (_i) * 3] >> 4) & 0x0008) \
142 | )
143 |
144 | #define SS4_BTL_MF_Y_V2(_b, _i) (SS4_STD_MF_Y_V2(_b, _i) | \
145 | ((_b[0 + (_i) * 3] >> 3) & 0x0008) \
146 | )
147 |
148 | #define SS4_MF_Z_V2(_b, _i) (((_b[1 + (_i) * 3]) & 0x0001) | \
149 | ((_b[1 + (_i) * 3] >> 1) & 0x0002) \
150 | )
151 |
152 | #define SS4_IS_MF_CONTINUE(_b) ((_b[2] & 0x10) == 0x10)
153 | #define SS4_IS_5F_DETECTED(_b) ((_b[2] & 0x10) == 0x10)
154 |
155 | #define SS4_MFPACKET_NO_AX 8160 /* X-Coordinate value */
156 | #define SS4_MFPACKET_NO_AY 4080 /* Y-Coordinate value */
157 | #define SS4_MFPACKET_NO_AX_BL 8176 /* Buttonless X-Coord value */
158 | #define SS4_MFPACKET_NO_AY_BL 4088 /* Buttonless Y-Coord value */
159 | #define SS4_PLUS_MFPACKET_NO_AX 4080 /* SS4 PLUS, X */
160 | #define SS4_PLUS_MFPACKET_NO_AX_BL 4088 /* Buttonless SS4 PLUS, X */
161 |
162 | /*
163 | * enum V7_PACKET_ID - defines the packet type for V7
164 | * V7_PACKET_ID_IDLE: There's no finger and no button activity.
165 | * V7_PACKET_ID_TWO: There's one or two non-resting fingers on touchpad
166 | * or there's button activities.
167 | * V7_PACKET_ID_MULTI: There are at least three non-resting fingers.
168 | * V7_PACKET_ID_NEW: The finger position in slot is not continues from
169 | * previous packet.
170 | */
171 | enum V7_PACKET_ID {
172 | V7_PACKET_ID_IDLE,
173 | V7_PACKET_ID_TWO,
174 | V7_PACKET_ID_MULTI,
175 | V7_PACKET_ID_NEW,
176 | V7_PACKET_ID_UNKNOWN,
177 | };
178 |
179 | /**
180 | * struct alps_protocol_info - information about protocol used by a device
181 | * @version: Indicates V1/V2/V3/...
182 | * @byte0: Helps figure out whether a position report packet matches the
183 | * known format for this model. The first byte of the report, ANDed with
184 | * mask0, should match byte0.
185 | * @mask0: The mask used to check the first byte of the report.
186 | * @flags: Additional device capabilities (passthrough port, trackstick, etc.).
187 | */
188 | struct alps_protocol_info {
189 | UInt16 version;
190 | UInt8 byte0, mask0;
191 | unsigned int flags;
192 | };
193 |
194 | /**
195 | * struct alps_model_info - touchpad ID table
196 | * @signature: E7 response string to match.
197 | * @protocol_info: information about protocol used by the device.
198 | *
199 | * Many (but not all) ALPS touchpads can be identified by looking at the
200 | * values returned in the "E7 report" and/or the "EC report." This table
201 | * lists a number of such touchpads.
202 | */
203 | struct alps_model_info {
204 | UInt8 signature[3];
205 | struct alps_protocol_info protocol_info;
206 | };
207 |
208 | /**
209 | * struct alps_nibble_commands - encodings for register accesses
210 | * @command: PS/2 command used for the nibble
211 | * @data: Data supplied as an argument to the PS/2 command, if applicable
212 | *
213 | * The ALPS protocol uses magic sequences to transmit binary data to the
214 | * touchpad, as it is generally not OK to send arbitrary bytes out the
215 | * PS/2 port. Each of the sequences in this table sends one nibble of the
216 | * register address or (write) data. Different versions of the ALPS protocol
217 | * use slightly different encodings.
218 | */
219 | struct alps_nibble_commands {
220 | SInt32 command;
221 | UInt8 data;
222 | };
223 |
224 | struct alps_bitmap_point {
225 | int start_bit;
226 | int num_bits;
227 | };
228 |
229 | struct input_mt_pos {
230 | UInt32 x;
231 | UInt32 y;
232 | };
233 |
234 | /**
235 | * struct alps_fields - decoded version of the report packet
236 | * @x_map: Bitmap of active X positions for MT.
237 | * @y_map: Bitmap of active Y positions for MT.
238 | * @fingers: Number of fingers for MT.
239 | * @pressure: Pressure.
240 | * @st: position for ST.
241 | * @mt: position for MT.
242 | * @first_mp: Packet is the first of a multi-packet report.
243 | * @is_mp: Packet is part of a multi-packet report.
244 | * @left: Left touchpad button is active.
245 | * @right: Right touchpad button is active.
246 | * @middle: Middle touchpad button is active.
247 | * @ts_left: Left trackstick button is active.
248 | * @ts_right: Right trackstick button is active.
249 | * @ts_middle: Middle trackstick button is active.
250 | */
251 | struct alps_fields {
252 | unsigned int x_map;
253 | unsigned int y_map;
254 | unsigned int fingers;
255 |
256 | int pressure;
257 | struct input_mt_pos st;
258 | struct input_mt_pos mt[MAX_TOUCHES];
259 |
260 | unsigned int first_mp:1;
261 | unsigned int is_mp:1;
262 |
263 | unsigned int left:1;
264 | unsigned int right:1;
265 | unsigned int middle:1;
266 |
267 | unsigned int ts_left:1;
268 | unsigned int ts_right:1;
269 | unsigned int ts_middle:1;
270 | };
271 |
272 | class ApplePS2ALPSGlidePoint;
273 |
274 | /**
275 | * struct alps_data - private data structure for the ALPS driver
276 | * @nibble_commands: Command mapping used for touchpad register accesses.
277 | * @addr_command: Command used to tell the touchpad that a register address
278 | * follows.
279 | * @proto_version: Indicates V1/V2/V3/...
280 | * @byte0: Helps figure out whether a position report packet matches the
281 | * known format for this model. The first byte of the report, ANDed with
282 | * mask0, should match byte0.
283 | * @mask0: The mask used to check the first byte of the report.
284 | * @fw_ver: cached copy of firmware version (EC report)
285 | * @flags: Additional device capabilities (passthrough port, trackstick, etc.).
286 | * @x_max: Largest possible X position value.
287 | * @y_max: Largest possible Y position value.
288 | * @x_bits: Number of X bits in the MT bitmap.
289 | * @y_bits: Number of Y bits in the MT bitmap.
290 | * @prev_fin: Finger bit from previous packet.
291 | * @multi_packet: Multi-packet data in progress.
292 | * @multi_data: Saved multi-packet data.
293 | * @f: Decoded packet data fields.
294 | * @quirks: Bitmap of ALPS_QUIRK_*.
295 | */
296 | struct alps_data {
297 | /* these are autodetected when the device is identified */
298 | const struct alps_nibble_commands *nibble_commands;
299 | SInt32 addr_command;
300 | UInt16 proto_version;
301 | UInt8 byte0, mask0;
302 | UInt8 dev_id[3];
303 | UInt8 fw_ver[3];
304 | int flags;
305 | SInt32 x_max;
306 | SInt32 y_max;
307 | SInt32 x_bits;
308 | SInt32 y_bits;
309 | unsigned int x_res;
310 | unsigned int y_res;
311 |
312 | SInt32 prev_fin;
313 | SInt32 multi_packet;
314 | int second_touch;
315 | UInt8 multi_data[6];
316 | struct alps_fields f;
317 | UInt8 quirks;
318 | bool PSMOUSE_BAD_DATA;
319 |
320 | int pktsize = 6;
321 | };
322 |
323 | // Pulled out of alps_data, now saved as vars on class
324 | // makes invoking a little easier
325 | typedef bool (ApplePS2ALPSGlidePoint::*hw_init)();
326 | typedef bool (ApplePS2ALPSGlidePoint::*decode_fields)(struct alps_fields *f, UInt8 *p);
327 | typedef void (ApplePS2ALPSGlidePoint::*process_packet)(UInt8 *packet);
328 | //typedef void (ALPS::*set_abs_params)();
329 |
330 | #define ALPS_QUIRK_TRACKSTICK_BUTTONS 1 /* trakcstick buttons in trackstick packet */
331 |
332 | //
333 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
334 | // ApplePS2ALPSGlidePoint Class Declaration
335 | //
336 |
337 | typedef struct ALPSStatus {
338 | UInt8 bytes[3];
339 | } ALPSStatus_t;
340 |
341 | #define XMIN 0
342 | #define XMAX 6143
343 | #define YMIN 0
344 | #define YMAX 6143
345 | #define XMIN_NOMINAL 1472
346 | #define XMAX_NOMINAL 5472
347 | #define YMIN_NOMINAL 1408
348 | #define YMAX_NOMINAL 4448
349 |
350 | #define ABS_POS_BITS 13
351 | #define X_MAX_POSITIVE 8176
352 | #define Y_MAX_POSITIVE 8176
353 |
354 | #define kPacketLength 6
355 | #define kDP_CommandNibble10 0xf2
356 |
357 | // predeclure stuff
358 | struct alps_data;
359 |
360 | class EXPORT ApplePS2ALPSGlidePoint : public IOService {
361 | OSDeclareDefaultStructors( ApplePS2ALPSGlidePoint );
362 |
363 | private:
364 | IOService *voodooInputInstance {nullptr};
365 | ApplePS2MouseDevice * _device {nullptr};
366 | bool _interruptHandlerInstalled {false};
367 | bool _powerControlHandlerInstalled {false};
368 | RingBuffer _ringBuffer {};
369 | UInt32 _packetByteCount {0};
370 |
371 | IOCommandGate* _cmdGate {nullptr};
372 |
373 | VoodooInputEvent inputEvent {};
374 |
375 | // buttons and scroll wheel
376 | unsigned int clicked:1;
377 | unsigned int left:1;
378 | unsigned int right:1;
379 | unsigned int middle:1;
380 |
381 | unsigned int left_ts:1;
382 |
383 | // VoodooInput
384 | int margin_size_x {0};
385 |
386 | uint32_t logical_max_x {0};
387 | uint32_t logical_max_y {0};
388 |
389 | uint32_t physical_max_x {0};
390 | uint32_t physical_max_y {0};
391 |
392 | alps_virtual_finger_state virtualFingerStates[MAX_TOUCHES] {};
393 |
394 | int clampedFingerCount {0};
395 | int lastFingerCount;
396 | bool reportVoodooInput;
397 |
398 | int minXOverride {-1}, minYOverride {-1}, maxXOverride {-1}, maxYOverride {-1};
399 |
400 | ForceTouchMode _forceTouchMode {FORCE_TOUCH_DISABLED};
401 | int _forceTouchPressureThreshold {100};
402 |
403 | int _forceTouchCustomDownThreshold {90};
404 | int _forceTouchCustomUpThreshold {20};
405 | int _forceTouchCustomPower {8};
406 |
407 | // normal state
408 | UInt32 lastbuttons {0};
409 | UInt32 lastTrackStickButtons, lastTouchpadButtons;
410 | uint64_t keytime {0};
411 | bool ignoreall {false};
412 | int z_finger {45};
413 | uint64_t maxaftertyping {100000000};
414 | int wakedelay {1000};
415 | // HID Notification
416 | bool usb_mouse_stops_trackpad {true};
417 |
418 | int _processusbmouse {true};
419 | int _processbluetoothmouse {true};
420 |
421 | OSSet* attachedHIDPointerDevices {nullptr};
422 |
423 | IONotifier* usb_hid_publish_notify {nullptr}; // Notification when an USB mouse HID device is connected
424 | IONotifier* usb_hid_terminate_notify {nullptr}; // Notification when an USB mouse HID device is disconnected
425 |
426 | IONotifier* bluetooth_hid_publish_notify {nullptr}; // Notification when a bluetooth HID device is connected
427 | IONotifier* bluetooth_hid_terminate_notify {nullptr}; // Notification when a bluetooth HID device is disconnected
428 |
429 | int _modifierdown {0}; // state of left+right control keys
430 |
431 | // for scaling x/y values
432 | int xupmm {50}, yupmm {50}; // 50 is just arbitrary, but same
433 |
434 | alps_data priv;
435 | hw_init hw_init;
436 | decode_fields decode_fields;
437 | process_packet process_packet;
438 | // set_abs_params set_abs_params;
439 |
440 | void injectVersionDependentProperties(OSDictionary* dict);
441 | bool resetMouse();
442 | bool handleOpen(IOService *forClient, IOOptionBits options, void *arg) override;
443 | void handleClose(IOService *forClient, IOOptionBits options) override;
444 | bool handleIsOpen(const IOService *forClient) const override;
445 | PS2InterruptResult interruptOccurred(UInt8 data);
446 | void packetReady();
447 | virtual bool deviceSpecificInit();
448 |
449 | void alps_process_packet_v1_v2(UInt8 *packet);
450 | int alps_process_bitmap(struct alps_data *priv, struct alps_fields *f);
451 | void alps_process_trackstick_packet_v3(UInt8 * packet);
452 | bool alps_decode_buttons_v3(struct alps_fields *f, UInt8 *p);
453 | bool alps_decode_pinnacle(struct alps_fields *f, UInt8 *p);
454 | bool alps_decode_rushmore(struct alps_fields *f, UInt8 *p);
455 | bool alps_decode_dolphin(struct alps_fields *f, UInt8 *p);
456 | void alps_process_touchpad_packet_v3_v5(UInt8 * packet);
457 | void alps_process_packet_v3(UInt8 *packet);
458 | void alps_process_packet_v6(UInt8 *packet);
459 | void alps_process_packet_v4(UInt8 *packet);
460 | unsigned char alps_get_packet_id_v7(UInt8 *byte);
461 | void alps_get_finger_coordinate_v7(struct input_mt_pos *mt, UInt8 *pkt, UInt8 pkt_id);
462 | int alps_get_mt_count(struct input_mt_pos *mt);
463 | bool alps_decode_packet_v7(struct alps_fields *f, UInt8 *p);
464 | void alps_process_trackstick_packet_v7(UInt8 *packet);
465 | void alps_process_touchpad_packet_v7(UInt8 *packet);
466 | void alps_process_packet_v7(UInt8 *packet);
467 | unsigned char alps_get_pkt_id_ss4_v2(UInt8 *byte);
468 | bool alps_decode_ss4_v2(struct alps_fields *f, UInt8 *p);
469 | void alps_process_packet_ss4_v2(UInt8 *packet);
470 | bool alps_command_mode_send_nibble(int value);
471 | bool alps_command_mode_set_addr(int addr);
472 | int alps_command_mode_read_reg(int addr);
473 | bool alps_command_mode_write_reg(int addr, UInt8 value);
474 | bool alps_command_mode_write_reg(UInt8 value);
475 | bool alps_rpt_cmd(SInt32 init_command, SInt32 init_arg, SInt32 repeated_command, ALPSStatus_t *report);
476 | bool alps_enter_command_mode();
477 | bool alps_exit_command_mode();
478 | bool alps_passthrough_mode_v2(bool enable);
479 | bool alps_absolute_mode_v1_v2();
480 | int alps_monitor_mode_send_word(int word);
481 | int alps_monitor_mode_write_reg(int addr, int value);
482 | int alps_monitor_mode(bool enable);
483 | void alps_absolute_mode_v6();
484 | bool alps_get_status(ALPSStatus_t *status);
485 | bool alps_tap_mode(bool enable);
486 | bool alps_hw_init_v1_v2();
487 | bool alps_hw_init_v6();
488 | bool alps_passthrough_mode_v3(int regBase, bool enable);
489 | bool alps_absolute_mode_v3();
490 | IOReturn alps_probe_trackstick_v3_v7(int regBase);
491 | IOReturn alps_setup_trackstick_v3(int regBase);
492 | bool alps_hw_init_v3();
493 | bool alps_get_v3_v7_resolution(int reg_pitch);
494 | bool alps_hw_init_rushmore_v3();
495 | bool alps_absolute_mode_v4();
496 | bool alps_hw_init_v4();
497 | void alps_get_otp_values_ss4_v2(unsigned char index, unsigned char otp[]);
498 | void alps_update_device_area_ss4_v2(unsigned char otp[][4], struct alps_data *priv);
499 | void alps_update_btn_info_ss4_v2(unsigned char otp[][4], struct alps_data *priv);
500 | void alps_update_dual_info_ss4_v2(unsigned char otp[][4], struct alps_data *priv);
501 | void alps_set_defaults_ss4_v2(struct alps_data *priv);
502 | int alps_dolphin_get_device_area(struct alps_data *priv);
503 | bool alps_hw_init_dolphin_v1();
504 | bool alps_hw_init_v7();
505 | bool alps_hw_init_ss4_v2();
506 | void set_protocol();
507 | bool matchTable(ALPSStatus_t *e7, ALPSStatus_t *ec);
508 | IOReturn identify();
509 | void setTouchPadEnable(bool enable);
510 | void ps2_command(unsigned char value, UInt8 command);
511 | void ps2_command_short(UInt8 command);
512 | int abs(int x);
513 | void set_resolution();
514 | void voodooTrackpoint(UInt32 type, SInt8 x, SInt8 y, int buttons);
515 | void alps_buttons(struct alps_fields &f);
516 |
517 | void prepareVoodooInput(struct alps_fields &f, int fingers);
518 | void sendTouchData();
519 |
520 | virtual void initTouchPad();
521 | virtual void setParamPropertiesGated(OSDictionary* dict);
522 | virtual void setDevicePowerState(UInt32 whatToDo);
523 |
524 | void registerHIDPointerNotifications();
525 | void unregisterHIDPointerNotifications();
526 |
527 | void notificationHIDAttachedHandlerGated(IOService * newService, IONotifier * notifier);
528 | bool notificationHIDAttachedHandler(void * refCon, IOService * newService, IONotifier * notifier);
529 |
530 | public:
531 | bool init(OSDictionary * dict) override;
532 | ApplePS2ALPSGlidePoint * probe(IOService *provider, SInt32 *score) override;
533 |
534 | bool start(IOService *provider) override;
535 | void stop(IOService *provider) override;
536 |
537 | IOReturn setProperties(OSObject *props) override;
538 |
539 | IOReturn message(UInt32 type, IOService* provider, void* argument) override;
540 | };
541 |
542 | #endif /* _APPLEPS2ALPSTOUCHPAD_H */
543 |
--------------------------------------------------------------------------------
/VoodooPS2Trackpad/VoodooPS2Elan.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Elan PS2 touchpad integration
3 | *
4 | * Mostly contains code ported from Linux
5 | * https://github.com/torvalds/linux/blob/master/drivers/input/mouse/elantech.c
6 | *
7 | * Created by Bartosz Korczyński (@bandysc), Hiep Bao Le (@hieplpvip)
8 | * Special thanks to Kishor Prins (@kprinssu), EMlyDinEsHMG and whole VoodooInput team
9 | */
10 |
11 | #ifndef _APPLEPS2ELAN_H
12 | #define _APPLEPS2ELAN_H
13 |
14 | #include "../VoodooPS2Controller/ApplePS2MouseDevice.h"
15 | #include
16 | #include
17 | #include
18 |
19 | #include "VoodooInputMultitouch/VoodooInputEvent.h"
20 | #include "VoodooPS2TrackpadCommon.h"
21 |
22 | struct elan_virtual_finger_state {
23 | TouchCoordinates prev;
24 | TouchCoordinates now;
25 | uint8_t pressure;
26 | uint8_t width;
27 | bool touch;
28 | bool button;
29 | MT2FingerType fingerType;
30 | };
31 |
32 | #define kPacketLengthMax 6
33 |
34 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
35 | //
36 | // FROM LINUX ELANTECH.C
37 |
38 | /*
39 | * Command values for Synaptics style queries
40 | */
41 | #define ETP_FW_ID_QUERY 0x00
42 | #define ETP_FW_VERSION_QUERY 0x01
43 | #define ETP_CAPABILITIES_QUERY 0x02
44 | #define ETP_SAMPLE_QUERY 0x03
45 | #define ETP_RESOLUTION_QUERY 0x04
46 |
47 | /*
48 | * Command values for register reading or writing
49 | */
50 | #define ETP_REGISTER_READ 0x10
51 | #define ETP_REGISTER_WRITE 0x11
52 | #define ETP_REGISTER_READWRITE 0x00
53 |
54 | /*
55 | * Hardware version 2 custom PS/2 command value
56 | */
57 | #define ETP_PS2_CUSTOM_COMMAND 0xf8
58 |
59 | /*
60 | * Times to retry a ps2_command and millisecond delay between tries
61 | */
62 | #define ETP_PS2_COMMAND_TRIES 3
63 | #define ETP_PS2_COMMAND_DELAY 500
64 |
65 | /*
66 | * Times to try to read back a register and millisecond delay between tries
67 | */
68 | #define ETP_READ_BACK_TRIES 5
69 | #define ETP_READ_BACK_DELAY 2000
70 |
71 | /*
72 | * Register bitmasks for hardware version 1
73 | */
74 | #define ETP_R10_ABSOLUTE_MODE 0x04
75 | #define ETP_R11_4_BYTE_MODE 0x02
76 |
77 | /*
78 | * Capability bitmasks
79 | */
80 | #define ETP_CAP_HAS_ROCKER 0x04
81 |
82 | /*
83 | * One hard to find application note states that X axis range is 0 to 576
84 | * and Y axis range is 0 to 384 for harware version 1.
85 | * Edge fuzz might be necessary because of bezel around the touchpad
86 | */
87 | #define ETP_EDGE_FUZZ_V1 32
88 |
89 | #define ETP_XMIN_V1 ( 0 + ETP_EDGE_FUZZ_V1)
90 | #define ETP_XMAX_V1 (576 - ETP_EDGE_FUZZ_V1)
91 | #define ETP_YMIN_V1 ( 0 + ETP_EDGE_FUZZ_V1)
92 | #define ETP_YMAX_V1 (384 - ETP_EDGE_FUZZ_V1)
93 |
94 | /*
95 | * The resolution for older v2 hardware doubled.
96 | * (newer v2's firmware provides command so we can query)
97 | */
98 | #define ETP_XMIN_V2 0
99 | #define ETP_XMAX_V2 1152
100 | #define ETP_YMIN_V2 0
101 | #define ETP_YMAX_V2 768
102 |
103 | // Preasure min-max
104 | #define ETP_PMIN_V2 0
105 | #define ETP_PMAX_V2 255
106 |
107 | // Width min-max
108 | #define ETP_WMIN_V2 0
109 | #define ETP_WMAX_V2 15
110 |
111 | /*
112 | * v3 hardware has 2 kinds of packet types,
113 | * v4 hardware has 3.
114 | */
115 | #define PACKET_UNKNOWN 0x01
116 | #define PACKET_DEBOUNCE 0x02
117 | #define PACKET_V3_HEAD 0x03
118 | #define PACKET_V3_TAIL 0x04
119 | #define PACKET_V4_HEAD 0x05
120 | #define PACKET_V4_MOTION 0x06
121 | #define PACKET_V4_STATUS 0x07
122 | #define PACKET_TRACKPOINT 0x08
123 |
124 | /*
125 | * track up to 5 fingers for v4 hardware
126 | */
127 | #define ETP_MAX_FINGERS 5
128 |
129 | /*
130 | * weight value for v4 hardware
131 | */
132 | #define ETP_WEIGHT_VALUE 5
133 |
134 | /*
135 | * Bus information on 3rd byte of query ETP_RESOLUTION_QUERY(0x04)
136 | */
137 | #define ETP_BUS_PS2_ONLY 0
138 | #define ETP_BUS_SMB_ALERT_ONLY 1
139 | #define ETP_BUS_SMB_HST_NTFY_ONLY 2
140 | #define ETP_BUS_PS2_SMB_ALERT 3
141 | #define ETP_BUS_PS2_SMB_HST_NTFY 4
142 |
143 | /*
144 | * New ICs are either using SMBus Host Notify or just plain PS2.
145 | *
146 | * ETP_FW_VERSION_QUERY is:
147 | * Byte 1:
148 | * - bit 0..3: IC BODY
149 | * Byte 2:
150 | * - bit 4: HiddenButton
151 | * - bit 5: PS2_SMBUS_NOTIFY
152 | * - bit 6: PS2CRCCheck
153 | */
154 | #define ETP_NEW_IC_SMBUS_HOST_NOTIFY(fw_version) \
155 | ((((fw_version) & 0x0f2000) == 0x0f2000) && \
156 | ((fw_version) & 0x0000ff) > 0)
157 |
158 | /*
159 | * The base position for one finger, v4 hardware
160 | */
161 | struct finger_pos {
162 | unsigned int x;
163 | unsigned int y;
164 | };
165 |
166 | struct elantech_device_info {
167 | unsigned char capabilities[3];
168 | unsigned char samples[3];
169 | unsigned char debug;
170 | unsigned char hw_version;
171 | unsigned int fw_version;
172 | unsigned int x_min;
173 | unsigned int y_min;
174 | unsigned int x_max;
175 | unsigned int y_max;
176 | unsigned int x_res;
177 | unsigned int y_res;
178 | unsigned int x_traces;
179 | unsigned int y_traces;
180 | unsigned int width;
181 | unsigned int bus;
182 | bool paritycheck;
183 | bool jumpy_cursor;
184 | bool reports_pressure;
185 | bool crc_enabled;
186 | bool set_hw_resolution;
187 | bool is_buttonpad;
188 | bool has_trackpoint;
189 | bool has_middle_button;
190 | };
191 |
192 | struct elantech_data {
193 | unsigned char reg_07;
194 | unsigned char reg_10;
195 | unsigned char reg_11;
196 | unsigned char reg_20;
197 | unsigned char reg_21;
198 | unsigned char reg_22;
199 | unsigned char reg_23;
200 | unsigned char reg_24;
201 | unsigned char reg_25;
202 | unsigned char reg_26;
203 | unsigned int single_finger_reports;
204 | struct finger_pos mt[ETP_MAX_FINGERS];
205 | unsigned char parity[256];
206 | };
207 |
208 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
209 | // ApplePS2Elan Class Declaration
210 | //
211 |
212 | class EXPORT ApplePS2Elan : public IOService {
213 | typedef IOService super;
214 | OSDeclareDefaultStructors(ApplePS2Elan);
215 |
216 | private:
217 | IOService* voodooInputInstance {nullptr};
218 | ApplePS2MouseDevice* _device {nullptr};
219 | bool _interruptHandlerInstalled {false};
220 | bool _powerControlHandlerInstalled {false};
221 | UInt32 _packetByteCount {0};
222 | UInt32 _packetLength {0};
223 | RingBuffer _ringBuffer {};
224 |
225 | IOCommandGate* _cmdGate {nullptr};
226 |
227 | VoodooInputEvent inputEvent {};
228 | TrackpointReport trackpointReport {};
229 |
230 | // when trackpad has physical button
231 | UInt32 leftButton = 0;
232 | UInt32 rightButton = 0;
233 | UInt32 lastLeftButton = 0;
234 | UInt32 lastRightButton = 0;
235 |
236 | const float sin30deg = 0.5f;
237 | const float cos30deg = 0.86602540378f;
238 | UInt32 lastFingers = 0;
239 |
240 | int heldFingers = 0;
241 | int headPacketsCount = 0;
242 | elan_virtual_finger_state virtualFinger[ETP_MAX_FINGERS] {};
243 |
244 | static_assert(ETP_MAX_FINGERS <= kMT2FingerTypeLittleFinger, "Too many fingers for one hand");
245 |
246 | ForceTouchMode _forceTouchMode {FORCE_TOUCH_BUTTON};
247 |
248 | int wakedelay {1000};
249 | int _trackpointDeadzone {1};
250 | int _trackpointMultiplierX {120};
251 | int _trackpointMultiplierY {120};
252 | int _trackpointDividerX {120};
253 | int _trackpointDividerY {120};
254 | int _trackpointScrollMultiplierX {120};
255 | int _trackpointScrollMultiplierY {120};
256 | int _trackpointScrollDividerX {120};
257 | int _trackpointScrollDividerY {120};
258 |
259 | int _mouseResolution {0x3};
260 | int _mouseSampleRate {200};
261 |
262 | bool _set_hw_resolution {false};
263 |
264 | bool ignoreall {false};
265 | bool usb_mouse_stops_trackpad {true};
266 |
267 | bool _processusbmouse {true};
268 | bool _processbluetoothmouse {true};
269 |
270 | uint64_t keytime {0};
271 | uint64_t maxaftertyping {500000000};
272 |
273 | OSSet *attachedHIDPointerDevices {nullptr};
274 |
275 | IONotifier *usb_hid_publish_notify {nullptr}; // Notification when an USB mouse HID device is connected
276 | IONotifier *usb_hid_terminate_notify {nullptr}; // Notification when an USB mouse HID device is disconnected
277 |
278 | IONotifier *bluetooth_hid_publish_notify {nullptr}; // Notification when a bluetooth HID device is connected
279 | IONotifier *bluetooth_hid_terminate_notify {nullptr}; // Notification when a bluetooth HID device is disconnected
280 |
281 | virtual PS2InterruptResult interruptOccurred(UInt8 data);
282 | virtual void packetReady();
283 | virtual void setDevicePowerState(UInt32 whatToDo);
284 |
285 | bool handleOpen(IOService *forClient, IOOptionBits options, void *arg) override;
286 | void handleClose(IOService *forClient, IOOptionBits options) override;
287 | bool handleIsOpen(const IOService *forClient) const override;
288 |
289 | void setParamPropertiesGated(OSDictionary *dict);
290 | void injectVersionDependentProperties(OSDictionary *dict);
291 | void setTrackpointProperties();
292 |
293 | void registerHIDPointerNotifications();
294 | void unregisterHIDPointerNotifications();
295 |
296 | void notificationHIDAttachedHandlerGated(IOService *newService, IONotifier *notifier);
297 | bool notificationHIDAttachedHandler(void *refCon, IOService *newService, IONotifier *notifier);
298 |
299 | elantech_data etd {};
300 | elantech_device_info info {};
301 | int elantechDetect();
302 | int elantechQueryInfo();
303 | int elantechSetProperties();
304 | int elantechSetAbsoluteMode();
305 | int elantechSetInputParams();
306 | int elantechSetupPS2();
307 | int elantechReadReg(unsigned char reg, unsigned char *val);
308 | int elantechWriteReg(unsigned char reg, unsigned char val);
309 | int elantechDebounceCheckV2();
310 | int elantechPacketCheckV1();
311 | int elantechPacketCheckV2();
312 | int elantechPacketCheckV3();
313 | int elantechPacketCheckV4();
314 | void elantechRescale(unsigned int x, unsigned int y);
315 | void elantechReportAbsoluteV1();
316 | void elantechReportAbsoluteV2();
317 | void elantechReportAbsoluteV3(int packetType);
318 | void elantechReportAbsoluteV4(int packetType);
319 | void elantechReportTrackpoint();
320 | void processPacketStatusV4();
321 | void processPacketHeadV4();
322 | void processPacketMotionV4();
323 | void sendTouchData();
324 | void resetMouse();
325 | void setTouchPadEnable(bool enable);
326 |
327 | static MT2FingerType GetBestFingerType(int i);
328 |
329 | template
330 | int ps2_command(UInt8* params, unsigned int command);
331 | template
332 | int elantech_ps2_command(unsigned char *param, int command);
333 | int ps2_sliced_command(UInt8 command);
334 | template
335 | int synaptics_send_cmd(unsigned char c, unsigned char *param);
336 | template
337 | int elantech_send_cmd(unsigned char c, unsigned char *param);
338 | template
339 | int send_cmd(unsigned char c, unsigned char *param);
340 |
341 | bool elantech_is_signature_valid(const unsigned char *param);
342 | static unsigned int elantech_convert_res(unsigned int val);
343 | int elantech_get_resolution_v4(unsigned int *x_res, unsigned int *y_res, unsigned int *bus);
344 |
345 | public:
346 | bool init(OSDictionary *properties) override;
347 | ApplePS2Elan *probe(IOService *provider, SInt32 *score) override;
348 | bool start(IOService *provider) override;
349 | void stop(IOService *provider) override;
350 |
351 | IOReturn setProperties(OSObject *props) override;
352 |
353 | IOReturn message(UInt32 type, IOService* provider, void* argument) override;
354 | };
355 |
356 | #endif /* _ApplePS2Elan_H */
357 |
--------------------------------------------------------------------------------
/VoodooPS2Trackpad/VoodooPS2SMBusDevice.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // VoodooPS2SMBusDevice.cpp
3 | // VoodooPS2Trackpad
4 | //
5 | // Created by Avery Black on 9/13/24.
6 | // Copyright © 2024 Acidanthera. All rights reserved.
7 | //
8 |
9 | #include "VoodooPS2SMBusDevice.h"
10 |
11 | // =============================================================================
12 | // ApplePS2SmbusDevice Class Implementation
13 | //
14 |
15 | OSDefineMetaClassAndStructors(ApplePS2SmbusDevice, IOService);
16 |
17 | ApplePS2SmbusDevice *ApplePS2SmbusDevice::withReset(bool resetNeeded, OSDictionary *data, uint8_t addr) {
18 | ApplePS2SmbusDevice *dev = OSTypeAlloc(ApplePS2SmbusDevice);
19 |
20 | if (dev == nullptr) {
21 | return nullptr;
22 | }
23 |
24 | if (!dev->init()) {
25 | OSSafeReleaseNULL(dev);
26 | return nullptr;
27 | }
28 |
29 | dev->_resetNeeded = resetNeeded;
30 | dev->_data = data;
31 | dev->_data->retain();
32 | dev->_addr = addr;
33 | return dev;
34 | }
35 |
36 | bool ApplePS2SmbusDevice::start(IOService *provider) {
37 | if (!super::start(provider))
38 | return false;
39 |
40 | _nub = OSDynamicCast(ApplePS2MouseDevice, provider);
41 | if (_nub == nullptr)
42 | return false;
43 |
44 | if (_resetNeeded)
45 | resetDevice();
46 |
47 | if (_nub->startSMBusCompanion(_data, _addr) != kIOReturnSuccess) {
48 | return false;
49 | }
50 |
51 | _nub->installPowerControlAction(this,
52 | OSMemberFunctionCast(PS2PowerControlAction, this, &ApplePS2SmbusDevice::powerAction));
53 | return true;
54 | }
55 |
56 | void ApplePS2SmbusDevice::stop(IOService *provider) {
57 | _nub->uninstallPowerControlAction();
58 | resetDevice();
59 | super::stop(provider);
60 | }
61 |
62 | void ApplePS2SmbusDevice::free() {
63 | OSSafeReleaseNULL(_data);
64 | super::free();
65 | }
66 |
67 | void ApplePS2SmbusDevice::powerAction(uint32_t ordinal) {
68 | if (ordinal == kPS2C_EnableDevice && _resetNeeded) {
69 | (void) resetDevice();
70 | }
71 | }
72 |
73 | IOReturn ApplePS2SmbusDevice::resetDevice() {
74 | TPS2Request<> request;
75 | request.commands[0].command = kPS2C_SendCommandAndCompareAck;
76 | request.commands[0].inOrOut = kDP_SetDefaultsAndDisable; // F5
77 | request.commandsCount = 1;
78 | _nub->submitRequestAndBlock(&request);
79 |
80 | if (request.commandsCount == 1) {
81 | DEBUG_LOG("VoodooPS2Trackpad: sending $FF failed: %d\n", request.commandsCount);
82 | return kIOReturnError;
83 | }
84 |
85 | return kIOReturnSuccess;
86 | }
87 |
88 |
--------------------------------------------------------------------------------
/VoodooPS2Trackpad/VoodooPS2SMBusDevice.h:
--------------------------------------------------------------------------------
1 | //
2 | // VoodooPS2SMBusDevice.hpp
3 | // VoodooPS2Trackpad
4 | //
5 | // Created by Avery Black on 9/13/24.
6 | // Copyright © 2024 Acidanthera. All rights reserved.
7 | //
8 |
9 | #ifndef VoodooPS2SMBusDevice_hpp
10 | #define VoodooPS2SMBusDevice_hpp
11 |
12 |
13 | #include "../VoodooPS2Controller/ApplePS2MouseDevice.h"
14 | #include
15 |
16 | #include "VoodooPS2TrackpadCommon.h"
17 |
18 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
19 | // ApplePS2SmbusDevice Class Declaration
20 | // Synaptics and Elans devices still need resets over PS2. This acts as a
21 | // PS/2 stub driver that attaches in lieu of the full touchpad driver to reset
22 | // on wakeups and sleep. This also prevents other devices attaching and using
23 | // the otherwise unused PS/2 interface
24 | //
25 |
26 | class EXPORT ApplePS2SmbusDevice : public IOService {
27 | typedef IOService super;
28 | OSDeclareDefaultStructors(ApplePS2SmbusDevice);
29 | public:
30 | static ApplePS2SmbusDevice *withReset(bool resetNeeded, OSDictionary *data, uint8_t addr);
31 |
32 | bool start(IOService *provider) override;
33 | void stop(IOService *provider) override;
34 | void free() override;
35 |
36 | private:
37 | ApplePS2MouseDevice *_nub {nullptr};
38 | bool _resetNeeded {false};
39 | OSDictionary *_data {nullptr};
40 | uint8_t _addr{0};
41 |
42 | IOReturn resetDevice();
43 | void powerAction(uint32_t ordinal);
44 | };
45 |
46 | #endif /* VoodooPS2SMBusDevice_hpp */
47 |
--------------------------------------------------------------------------------
/VoodooPS2Trackpad/VoodooPS2SentelicFSP.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * The contents of this file constitute Original Code as defined in and
7 | * are subject to the Apple Public Source License Version 1.2 (the
8 | * "License"). You may not use this file except in compliance with the
9 | * License. Please obtain a copy of the License at
10 | * http://www.apple.com/publicsource and read it before using this file.
11 | *
12 | * This Original Code and all software distributed under the License are
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 | * License for the specific language governing rights and limitations
18 | * under the License.
19 | *
20 | * @APPLE_LICENSE_HEADER_END@
21 | */
22 |
23 | #ifndef _APPLEPS2SENTILICSFSP_H
24 | #define _APPLEPS2SENTILICSFSP_H
25 |
26 | #include "../VoodooPS2Controller/ApplePS2MouseDevice.h"
27 |
28 | #include
29 |
30 | #define kPacketLengthMax 4
31 | #define kPacketLengthStandard 3
32 | #define kPacketLengthLarge 4
33 |
34 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
35 | // ApplePS2SentelicFSP Class Declaration
36 | //
37 |
38 | class EXPORT ApplePS2SentelicFSP : public IOHIPointing
39 | {
40 | typedef IOHIPointing super;
41 | OSDeclareDefaultStructors( ApplePS2SentelicFSP );
42 |
43 | private:
44 | ApplePS2MouseDevice * _device;
45 | bool _interruptHandlerInstalled;
46 | bool _powerControlHandlerInstalled;
47 | RingBuffer _ringBuffer;
48 | UInt32 _packetByteCount;
49 | UInt8 _packetSize;
50 | IOFixed _resolution;
51 | UInt16 _touchPadVersion;
52 | UInt8 _touchPadModeByte;
53 |
54 | virtual void dispatchRelativePointerEventWithPacket( UInt8 * packet, UInt32 packetSize );
55 |
56 | virtual void setTouchPadEnable( bool enable );
57 | virtual UInt32 getTouchPadData( UInt8 dataSelector );
58 | virtual bool setTouchPadModeByte( UInt8 modeByteValue,
59 | bool enableStreamMode = false );
60 |
61 | virtual PS2InterruptResult interruptOccurred(UInt8 data);
62 | virtual void packetReady();
63 | virtual void setDevicePowerState(UInt32 whatToDo);
64 |
65 | protected:
66 | IOItemCount buttonCount() override;
67 | IOFixed resolution() override;
68 |
69 | inline void dispatchRelativePointerEventX(int dx, int dy, UInt32 buttonState, uint64_t now)
70 | { dispatchRelativePointerEvent(dx, dy, buttonState, *(AbsoluteTime*)&now); }
71 | inline void dispatchScrollWheelEventX(short deltaAxis1, short deltaAxis2, short deltaAxis3, uint64_t now)
72 | { dispatchScrollWheelEvent(deltaAxis1, deltaAxis2, deltaAxis3, *(AbsoluteTime*)&now); }
73 |
74 |
75 | public:
76 | bool init( OSDictionary * properties ) override;
77 | ApplePS2SentelicFSP * probe( IOService * provider,
78 | SInt32 * score ) override;
79 |
80 | bool start( IOService * provider ) override;
81 | void stop( IOService * provider ) override;
82 |
83 | UInt32 deviceType() override;
84 | UInt32 interfaceID() override;
85 |
86 | IOReturn setParamProperties( OSDictionary * dict ) override;
87 | };
88 |
89 | #endif /* _APPLEPS2SENTILICSFSP_H */
90 |
--------------------------------------------------------------------------------
/VoodooPS2Trackpad/VoodooPS2SynapticsTouchPad.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * The contents of this file constitute Original Code as defined in and
7 | * are subject to the Apple Public Source License Version 1.2 (the
8 | * "License"). You may not use this file except in compliance with the
9 | * License. Please obtain a copy of the License at
10 | * http://www.apple.com/publicsource and read it before using this file.
11 | *
12 | * This Original Code and all software distributed under the License are
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 | * License for the specific language governing rights and limitations
18 | * under the License.
19 | *
20 | * @APPLE_LICENSE_HEADER_END@
21 | */
22 |
23 | #ifndef _APPLEPS2SYNAPTICSTOUCHPAD_H
24 | #define _APPLEPS2SYNAPTICSTOUCHPAD_H
25 |
26 | #include "../VoodooPS2Controller/ApplePS2MouseDevice.h"
27 | #include
28 | #include
29 | #include "VoodooInputMultitouch/VoodooInputEvent.h"
30 | #include "VoodooPS2TrackpadCommon.h"
31 |
32 | struct synaptics_hw_state {
33 | int x;
34 | int y;
35 | int z;
36 | int w;
37 | int virtualFingerIndex;
38 | };
39 |
40 | /*
41 | Если touch = false, то палец игнорируется.
42 | Соответствие физических и виртуальных пальцев - динамическое.
43 | transducers заполняются каждый раз с номером виртуального пальца столько, сколько надо.
44 | Будут ли при этом отжиматься отпущенные пальцы?
45 | */
46 | struct synaptics_virtual_finger_state {
47 | SimpleAverage x_avg;
48 | SimpleAverage y_avg;
49 | uint8_t pressure;
50 | uint8_t width;
51 | bool touch;
52 | bool button;
53 | MT2FingerType fingerType;
54 | };
55 |
56 | #pragma pack(push)
57 | #pragma pack(1)
58 |
59 | #define SYNAPTICS_IDENTIFY_QUERY 0x00
60 | struct synaptics_identify_trackpad {
61 | uint8_t minor_ver;
62 | uint8_t synaptics_const;
63 | uint8_t major_ver : 4;
64 | uint8_t model_code : 4; // Unused field
65 | };
66 | static_assert(sizeof(synaptics_identify_trackpad) == 3, "Invalid Identity packet size");
67 |
68 | #define SYNA_MODEL_QUERY 0x01
69 | struct synaptics_model {
70 | uint8_t guest_present: 1;
71 | uint8_t more_extended_caps: 1;
72 | uint16_t model_number: 14;
73 | uint8_t mode_byte;
74 | };
75 | static_assert(sizeof(synaptics_model) == 3, "Invalid Model packet size");
76 |
77 | #define SYNA_CAPABILITIES_QUERY 0x02
78 | struct synaptics_capabilities {
79 | // Byte 0
80 | uint8_t _reserved0: 2;
81 | uint8_t middle_btn: 1;
82 | uint8_t _reserved1: 1;
83 | uint8_t extended_queries: 3;
84 | uint8_t has_extended_queries: 1;
85 | // Byte 1
86 | uint8_t model_sub_num;
87 | // Byte 2
88 | uint8_t palm_detect: 1;
89 | uint8_t multi_finger: 1;
90 | uint8_t ballistics: 1;
91 | uint8_t sleep: 1;
92 | uint8_t four_buttons: 1; // Currently unsupported
93 | uint8_t extended_w_supported: 1;
94 | uint8_t low_power: 1;
95 | uint8_t passthrough: 1;
96 | };
97 | static_assert(sizeof(synaptics_capabilities) == 3, "Invalid Capabilities packet size");
98 |
99 | #define SYNA_SCALE_QUERY 0x08
100 | struct synaptics_scale {
101 | uint8_t xupmm;
102 | uint8_t reserved;
103 | uint8_t yupmm;
104 | };
105 | static_assert(sizeof(synaptics_scale) == 3, "Invalid Scale packet size");
106 |
107 | #define SYNA_EXTENDED_ID_QUERY 0x09
108 | struct synaptics_extended_id {
109 | // Byte 0
110 | uint8_t vert_scroll_zone: 1;
111 | uint8_t horiz_scroll_zone: 1;
112 | uint8_t extended_w_supported: 1;
113 | uint8_t vertical_wheel: 1;
114 | uint8_t transparent_passthru: 1;
115 | uint8_t peak_detection: 1;
116 | uint8_t has_leds: 1;
117 | uint8_t reserved0: 1;
118 | // Byte 1
119 | uint8_t reserved1: 2;
120 | uint8_t info_sensor: 2;
121 | uint8_t extended_btns: 4;
122 | // Byte 2
123 | uint8_t product_id;
124 | };
125 | static_assert(sizeof(synaptics_extended_id) == 3, "Invalid Extended ID packet size");
126 |
127 | #define SYNA_CONT_CAPS_QUERY 0x0C
128 | struct synaptics_cont_capabilities {
129 | // Byte 0
130 | uint8_t adj_button_threshold: 1;
131 | uint8_t reports_max: 1;
132 | uint8_t is_clearpad: 1;
133 | uint8_t advanced_gestures: 1;
134 | uint8_t one_btn_clickpad: 1;
135 | uint8_t multifinger_mode: 2;
136 | uint8_t covered_pad_gesture: 1;
137 | // Byte 1
138 | uint8_t two_btn_clickpad: 1;
139 | uint8_t deluxe_leds: 1;
140 | uint8_t no_abs_pos_filter: 1;
141 | uint8_t reports_v: 1;
142 | uint8_t uniform_clickpad: 1;
143 | uint8_t reports_min: 1;
144 | uint8_t intertouch: 1;
145 | uint8_t reserved: 1;
146 | // Byte 2
147 | uint8_t intertouch_addr;
148 | };
149 | static_assert(sizeof(synaptics_cont_capabilities) == 3, "Invalid continued capabilities packet size");
150 |
151 | #define SYNA_LOGIC_MAX_QUERY 0x0D
152 | #define SYNA_LOGIC_MIN_QUERY 0x0F
153 | #define SYNA_LOGIC_X(x) ((x.x_high << 5) | (x.x_low << 1))
154 | #define SYNA_LOGIC_Y(x) (x.y << 1)
155 | struct synaptics_logic_min_max {
156 | uint8_t x_high;
157 | uint8_t x_low: 4;
158 | uint16_t y: 12;
159 | };
160 | static_assert(sizeof(synaptics_logic_min_max) == 3, "Invalid logic packet size");
161 |
162 | #define SYNA_SECUREPAD_QUERY 0x10
163 | struct synaptics_securepad_id {
164 | uint8_t trackstick_btns: 1;
165 | uint8_t is_securepad: 1;
166 | uint8_t unused: 6;
167 | uint8_t securepad_width;
168 | uint8_t securepad_height;
169 | };
170 | static_assert(sizeof(synaptics_securepad_id) == 3, "Invalid securepad packet size");
171 |
172 | #define SYNA_MODE_ABSOLUTE 0x80
173 | #define SYNA_MODE_HIGH_RATE 0x40
174 | #define SYNA_MODE_SLEEP 0x08
175 | #define SYNA_MODE_EXT_W 0x04
176 | #define SYNA_MODE_W_MODE 0x01
177 |
178 | // W Values for packet types
179 | #define SYNA_W_EXTENDED 0x02
180 | #define SYNA_W_PASSTHRU 0x03
181 |
182 | #pragma pack(pop)
183 |
184 | #define SYNAPTICS_MAX_EXT_BTNS 8
185 | #define SYNAPTICS_MAX_FINGERS 5
186 |
187 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
188 | // ApplePS2SynapticsTouchPad Class Declaration
189 | //
190 |
191 | #define XMIN 0
192 | #define XMAX 6143
193 | #define YMIN 0
194 | #define YMAX 6143
195 | #define XMIN_NOMINAL 1472
196 | #define XMAX_NOMINAL 5472
197 | #define YMIN_NOMINAL 1408
198 | #define YMAX_NOMINAL 4448
199 |
200 | #define ABS_POS_BITS 13
201 | #define X_MAX_POSITIVE 8176
202 | #define Y_MAX_POSITIVE 8176
203 |
204 |
205 | #define kPacketLength 6
206 |
207 | class EXPORT ApplePS2SynapticsTouchPad : public IOService
208 | {
209 | typedef IOService super;
210 | OSDeclareDefaultStructors(ApplePS2SynapticsTouchPad);
211 |
212 | private:
213 | IOService *voodooInputInstance {nullptr};
214 | ApplePS2MouseDevice * _device {nullptr};
215 | bool _interruptHandlerInstalled {false};
216 | bool _powerControlHandlerInstalled {false};
217 | RingBuffer _ringBuffer {};
218 | UInt32 _packetByteCount {0};
219 | UInt8 _lastdata {0};
220 |
221 | synaptics_identify_trackpad _identity {0};
222 | synaptics_capabilities _capabilities {0};
223 | synaptics_extended_id _extended_id {0};
224 | synaptics_securepad_id _securepad {0};
225 | synaptics_scale _scale {0};
226 | synaptics_cont_capabilities _cont_caps {0};
227 |
228 | IOCommandGate* _cmdGate {nullptr};
229 | IOACPIPlatformDevice*_provider {nullptr};
230 |
231 | VoodooInputEvent inputEvent {};
232 | TrackpointReport trackpointReport {};
233 |
234 | // buttons and scroll wheel
235 | bool _clickpad_pressed { false };
236 |
237 | int margin_size_x {0}, margin_size_y {0};
238 | uint32_t logical_max_x {0};
239 | uint32_t logical_max_y {0};
240 | uint32_t logical_min_x {0};
241 | uint32_t logical_min_y {0};
242 |
243 | uint32_t physical_max_x {0};
244 | uint32_t physical_max_y {0};
245 |
246 | synaptics_hw_state fingerStates[SYNAPTICS_MAX_FINGERS] {};
247 | synaptics_virtual_finger_state virtualFingerStates[SYNAPTICS_MAX_FINGERS] {};
248 | bool freeFingerTypes[kMT2FingerTypeCount];
249 |
250 | bool disableDeepSleep {false};
251 |
252 | static_assert(SYNAPTICS_MAX_FINGERS <= kMT2FingerTypeLittleFinger, "Too many fingers for one hand");
253 |
254 | void assignVirtualFinger(int physicalFinger);
255 | void assignFingerType(synaptics_virtual_finger_state &vf);
256 | int lastFingerCount;
257 | int lastSentFingerCount;
258 | bool hadLiftFinger;
259 | int upperFingerIndex() const;
260 | const synaptics_hw_state& upperFinger() const;
261 | void swapFingers(int dst, int src);
262 |
263 | void synaptics_parse_normal_packet(const UInt8 buf[], const int w);
264 | void synaptics_parse_agm_packet(const UInt8 buf[]);
265 | void synaptics_parse_passthru(const UInt8 buf[], const UInt32 buttons);
266 | int synaptics_parse_ext_btns(const UInt8 buf[], const int w);
267 | void synaptics_parse_hw_state(const UInt8 buf[]);
268 |
269 | /// Translates physical fingers into virtual fingers so that host software doesn't see 'jumps' and has coordinates for all fingers.
270 | /// @return True if is ready to send finger state to host interface
271 | bool renumberFingers();
272 | void sendTouchData();
273 | void freeAndMarkVirtualFingers();
274 | int dist(int physicalFinger, int virtualFinger);
275 |
276 | ForceTouchMode _forceTouchMode {FORCE_TOUCH_BUTTON};
277 | int _forceTouchPressureThreshold {100};
278 |
279 | int _forceTouchCustomDownThreshold {90};
280 | int _forceTouchCustomUpThreshold {20};
281 | int _forceTouchCustomPower {8};
282 |
283 | int clampedFingerCount {0};
284 | int agmFingerCount {0};
285 | bool wasSkipped {false};
286 | int z_finger {45};
287 | int zlimit {0};
288 | int noled {0};
289 | uint64_t maxaftertyping {500000000};
290 | uint64_t maxafterspecialtyping {0};
291 | int specialKey {0x80};
292 | int wakedelay {1000};
293 | int hwresetonstart {0};
294 | int diszl {0}, diszr {0}, diszt {0}, diszb {0};
295 | int minXOverride {-1}, minYOverride {-1}, maxXOverride {-1}, maxYOverride {-1};
296 |
297 | int _lastExtendedButtons {0};
298 | int _lastPassthruButtons {0};
299 |
300 | // Trackpoint information
301 | int _scrollMultiplierX {1};
302 | int _scrollMultiplierY {1};
303 | int _scrollDivisorX {1};
304 | int _scrollDivisorY {1};
305 | int _mouseMultiplierX {1};
306 | int _mouseMultiplierY {1};
307 | int _mouseDivisorX {1};
308 | int _mouseDivisorY {1};
309 | int _deadzone {1};
310 |
311 | // state related to secondary packets/extendedwmode
312 | bool tracksecondary {false};
313 |
314 | // normal state
315 | uint64_t keytime {0};
316 | UInt16 keycode {0};
317 | bool ignoreall {false};
318 | #ifdef SIMULATE_PASSTHRU
319 | UInt32 trackbuttons {0};
320 | #endif
321 | bool usb_mouse_stops_trackpad {true};
322 |
323 | int _processusbmouse {true};
324 | int _processbluetoothmouse {true};
325 |
326 | const OSSymbol* _smbusCompanion {nullptr};
327 |
328 | OSSet* attachedHIDPointerDevices {nullptr};
329 |
330 | IONotifier* usb_hid_publish_notify {nullptr}; // Notification when an USB mouse HID device is connected
331 | IONotifier* usb_hid_terminate_notify {nullptr}; // Notification when an USB mouse HID device is disconnected
332 |
333 | IONotifier* bluetooth_hid_publish_notify {nullptr}; // Notification when a bluetooth HID device is connected
334 | IONotifier* bluetooth_hid_terminate_notify {nullptr}; // Notification when a bluetooth HID device is disconnected
335 |
336 | int _modifierdown {0}; // state of left+right control keys
337 |
338 | inline bool isInDisableZone(int x, int y)
339 | { return x > diszl && x < diszr && y > diszb && y < diszt; }
340 |
341 | // Sony: coordinates captured from single touch event
342 | // Don't know what is the exact value of x and y on edge of touchpad
343 | // the best would be { return x > xmax/2 && y < ymax/4; }
344 |
345 | virtual void setTouchPadEnable( bool enable );
346 | virtual bool getTouchPadData( UInt8 dataSelector, UInt8 buf3[] );
347 | virtual bool getTouchPadStatus( UInt8 buf3[] );
348 | virtual PS2InterruptResult interruptOccurred(UInt8 data);
349 | virtual void packetReady();
350 | virtual void setDevicePowerState(UInt32 whatToDo);
351 |
352 | void updateTouchpadLED();
353 | bool setTouchpadLED(UInt8 touchLED);
354 | void initTouchPad();
355 | bool enterAdvancedGestureMode();
356 | bool setModeByte(bool sleep);
357 |
358 | inline bool isFingerTouch(int z) { return z>z_finger && z
2 |
3 |
4 |
5 | CFBundleExecutable
6 | VoodooPS2Trackpad
7 | CFBundleGetInfoString
8 | ${MODULE_VERSION}, Copyright Apple Computer, Inc. 2002-2003, mackerintel 2008, RehabMan 2012-2013
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | Voodoo PS/2 Trackpad
15 | CFBundlePackageType
16 | KEXT
17 | CFBundleShortVersionString
18 | ${MODULE_VERSION}
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${MODULE_VERSION}
23 | IOKitPersonalities
24 |
25 | ALPS GlidePoint
26 |
27 | CFBundleIdentifier
28 | as.acidanthera.voodoo.driver.PS2Trackpad
29 | IOClass
30 | ApplePS2ALPSGlidePoint
31 | IOProbeScore
32 | 1500
33 | IOProviderClass
34 | ApplePS2MouseDevice
35 | Platform Profile
36 |
37 | Default
38 |
39 | Darwin 16+
40 |
41 | ApplePreferenceCapability
42 |
43 | ApplePreferenceIdentifier
44 | com.apple.AppleMultitouchTrackpad
45 | MT Built-in
46 |
47 | MTHIDDevice
48 |
49 | SupportsGestureScrolling
50 |
51 | TrackpadEmbedded
52 |
53 | TrackpadFourFingerGestures
54 |
55 | TrackpadSecondaryClickCorners
56 |
57 | TrackpadThreeFingerDrag
58 |
59 |
60 | DisableDevice
61 |
62 | DragLockTempMask
63 | 1048592
64 | FingerZ
65 | 1
66 | ForceTouchCustomDownThreshold
67 | 90
68 | ForceTouchCustomPower
69 | 8
70 | ForceTouchCustomUpThreshold
71 | 20
72 | ForceTouchMode
73 | 0
74 | ForceTouchPressureThreshold
75 | 100
76 | ProcessBluetoothMouseStopsTrackpad
77 |
78 | ProcessUSBMouseStopsTrackpad
79 |
80 | QuietTimeAfterTyping
81 | 100000000
82 | USBMouseStopsTrackpad
83 | 0
84 | UnitsPerMMX
85 | 50
86 | UnitsPerMMY
87 | 50
88 | WakeDelay
89 | 1000
90 |
91 | HPQOEM
92 |
93 | 1411
94 | ProBook
95 | 1619
96 | ProBook
97 | 161C
98 | ProBook
99 | 164F
100 | ProBook
101 | 167C
102 | ProBook
103 | 167E
104 | ProBook
105 | 1680
106 | ProBook
107 | 179B
108 | ProBook
109 | 179C
110 | ProBook
111 | 17A9
112 | ProBook
113 | 17F0
114 | ProBook
115 | 17F3
116 | ProBook
117 | 17F6
118 | ProBook
119 | 1942
120 | ProBook
121 | 1949
122 | ProBook
123 | 198F
124 | ProBook
125 | ProBook
126 |
127 | DisableDevice
128 |
129 |
130 | ProBook-102
131 | ProBook
132 | ProBook-87
133 | ProBook
134 |
135 |
136 | ProductID
137 | 547
138 | RM,deliverNotifications
139 |
140 | VendorID
141 | 1452
142 |
143 | Elantech TouchPad
144 |
145 | IOProbeScore
146 | 7000
147 | IOProviderClass
148 | ApplePS2MouseDevice
149 | IOClass
150 | ApplePS2Elan
151 | CFBundleIdentifier
152 | as.acidanthera.voodoo.driver.PS2Trackpad
153 | Platform Profile
154 |
155 | Default
156 |
157 | ButtonCount
158 | 3
159 | Darwin 16+
160 |
161 | ApplePreferenceCapability
162 |
163 | ApplePreferenceIdentifier
164 | com.apple.AppleMultitouchTrackpad
165 | MT Built-in
166 |
167 | MTHIDDevice
168 |
169 | SupportsGestureScrolling
170 |
171 | TrackpadEmbedded
172 |
173 | TrackpadFourFingerGestures
174 |
175 | TrackpadSecondaryClickCorners
176 |
177 | TrackpadThreeFingerDrag
178 |
179 |
180 | DisableDevice
181 |
182 | ForceTouchMode
183 | 1
184 | MouseResolution
185 | 3
186 | MouseSampleRate
187 | 200
188 | ProcessBluetoothMouseStopsTrackpad
189 |
190 | ProcessUSBMouseStopsTrackpad
191 |
192 | QuietTimeAfterTyping
193 | 500000000
194 | ScrollResolution
195 | 400
196 | SetHwResolution
197 |
198 | TrackpointDividerX
199 | 120
200 | TrackpointDividerY
201 | 120
202 | TrackpointMultiplierX
203 | 120
204 | TrackpointMultiplierY
205 | 120
206 | USBMouseStopsTrackpad
207 | 0
208 | UseHighRate
209 |
210 | WakeDelay
211 | 1000
212 |
213 |
214 | RM,deliverNotifications
215 |
216 |
217 | Native Multitouch Engine
218 |
219 | CFBundleIdentifier
220 | as.acidanthera.voodoo.driver.PS2Trackpad
221 | IOClass
222 | VoodooPS2NativeEngine
223 | IOMatchCategory
224 | VoodooPS2NativeEngine
225 | IOProviderClass
226 | VoodooPS2MultitouchInterface
227 |
228 | Sentelic FSP
229 |
230 | CFBundleIdentifier
231 | as.acidanthera.voodoo.driver.PS2Trackpad
232 | IOClass
233 | ApplePS2SentelicFSP
234 | IOProbeScore
235 | 5500
236 | IOProviderClass
237 | ApplePS2MouseDevice
238 | Platform Profile
239 |
240 | Default
241 |
242 | DisableDevice
243 |
244 |
245 | HPQOEM
246 |
247 | 1411
248 | ProBook
249 | 1619
250 | ProBook
251 | 161C
252 | ProBook
253 | 164F
254 | ProBook
255 | 167C
256 | ProBook
257 | 167E
258 | ProBook
259 | 1680
260 | ProBook
261 | 179B
262 | ProBook
263 | 179C
264 | ProBook
265 | 17A9
266 | ProBook
267 | 17F0
268 | ProBook
269 | 17F3
270 | ProBook
271 | 17F6
272 | ProBook
273 | 1942
274 | ProBook
275 | 1949
276 | ProBook
277 | 198F
278 | ProBook
279 | ProBook
280 |
281 | DisableDevice
282 |
283 |
284 | ProBook-102
285 | ProBook
286 | ProBook-87
287 | ProBook
288 |
289 |
290 |
291 | Synaptics TouchPad
292 |
293 | CFBundleIdentifier
294 | as.acidanthera.voodoo.driver.PS2Trackpad
295 | IOClass
296 | ApplePS2SynapticsTouchPad
297 | IOProbeScore
298 | 6000
299 | IOProviderClass
300 | ApplePS2MouseDevice
301 | Platform Profile
302 |
303 | Default
304 |
305 | DisableDevice
306 |
307 | DisableLEDUpdating
308 |
309 | TrackpointDeadzone
310 | 1
311 | ForceTouchPressureThreshold
312 | 100
313 | ForceTouchCustomDownThreshold
314 | 90
315 | ForceTouchCustomUpThreshold
316 | 20
317 | ForceTouchCustomPower
318 | 8
319 | ProcessBluetoothMouseStopsTrackpad
320 |
321 | ProcessUSBMouseStopsTrackpad
322 |
323 | QuietTimeAfterTyping
324 | 500000000
325 | SkipPassThrough
326 |
327 | USBMouseStopsTrackpad
328 | 0
329 | WakeDelay
330 | 1000
331 |
332 | HPQOEM
333 |
334 | 1411
335 | ProBook
336 | 1619
337 | ProBook
338 | 161C
339 | ProBook
340 | 164F
341 | ProBook
342 | 167C
343 | ProBook
344 | 167E
345 | ProBook
346 | 1680
347 | ProBook
348 | 179B
349 | ProBook
350 | 179C
351 | ProBook
352 | 17A9
353 | ProBook
354 | 17F0
355 | ProBook
356 | 17F3
357 | ProBook
358 | 17F6
359 | ProBook
360 | 1942
361 | ProBook
362 | 1949
363 | ProBook
364 | 198F
365 | ProBook
366 | ProBook
367 |
368 | FingerZ
369 | 40
370 |
371 | ProBook-102
372 | ProBook
373 | ProBook-87
374 | ProBook
375 |
376 | LENOVO
377 |
378 | T420
379 | Thinkpad_TrackPad
380 | T460
381 | Thinkpad_ClickPad
382 | T560
383 | Thinkpad_ClickPad
384 | Thinkpad_ClickPad
385 |
386 | FingerZ
387 | 30
388 | HWResetOnStart
389 |
390 | TrackpointMultiplierX
391 | 2
392 | TrackpointMultiplierY
393 | 2
394 | TrackpointScrollMultiplierX
395 | 2
396 | TrackpointScrollMultiplierY
397 | 2
398 |
399 | Thinkpad_TrackPad
400 |
401 | FingerZ
402 | 47
403 | HWResetOnStart
404 |
405 |
406 | X1CG3
407 | Thinkpad_ClickPad
408 |
409 |
410 | ProductID
411 | 547
412 | RM,deliverNotifications
413 |
414 | VendorID
415 | 1452
416 |
417 |
418 | OSBundleLibraries
419 |
420 | com.apple.iokit.IOHIDFamily
421 | 1.0.0b1
422 | com.apple.kpi.iokit
423 | 9.0.0
424 | com.apple.kpi.libkern
425 | 9.0.0
426 | com.apple.kpi.mach
427 | 9.0.0
428 | as.acidanthera.voodoo.driver.PS2Controller
429 | ${MODULE_VERSION}
430 |
431 | OSBundleRequired
432 | Console
433 |
434 |
435 |
--------------------------------------------------------------------------------
/VoodooPS2Trackpad/VoodooPS2TrackpadCommon.h:
--------------------------------------------------------------------------------
1 | //
2 | // VoodooPS2TrackpadCommon.h
3 | // VoodooPS2Trackpad
4 | //
5 | // Created by Le Bao Hiep on 27/09/2020.
6 | // Copyright © 2020 Acidanthera. All rights reserved.
7 | //
8 |
9 | #ifndef VoodooPS2TrackpadCommon_h
10 | #define VoodooPS2TrackpadCommon_h
11 |
12 | #define TEST_BIT(x, y) ((x >> y) & 0x1)
13 |
14 | void inline PS2DictSetNumber(OSDictionary *dict, const char *key, unsigned int num) {
15 | OSNumber *val = OSNumber::withNumber(num, 32);
16 | if (val != nullptr) {
17 | dict->setObject(key, val);
18 | val->release();
19 | }
20 | }
21 |
22 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
23 | // SimpleAverage Class Declaration
24 | //
25 |
26 | template
27 | class SimpleAverage
28 | {
29 | private:
30 | T m_buffer[N];
31 | int m_count;
32 | int m_sum;
33 | int m_index;
34 |
35 | public:
36 | inline SimpleAverage() { reset(); }
37 | T filter(T data)
38 | {
39 | // add new entry to sum
40 | m_sum += data;
41 | // if full buffer, then we are overwriting, so subtract old from sum
42 | if (m_count == N)
43 | m_sum -= m_buffer[m_index];
44 | // new entry into buffer
45 | m_buffer[m_index] = data;
46 | // move index to next position with wrap around
47 | if (++m_index >= N)
48 | m_index = 0;
49 | // keep count moving until buffer is full
50 | if (m_count < N)
51 | ++m_count;
52 | // return average of current items
53 | return m_sum / m_count;
54 | }
55 | inline void reset()
56 | {
57 | m_count = 0;
58 | m_sum = 0;
59 | m_index = 0;
60 | }
61 | inline int count() const { return m_count; }
62 | inline int sum() const { return m_sum; }
63 | T oldest() const
64 | {
65 | // undefined if nothing in here, return zero
66 | if (m_count == 0)
67 | return 0;
68 | // if it is not full, oldest is at index 0
69 | // if full, it is right where the next one goes
70 | if (m_count < N)
71 | return m_buffer[0];
72 | else
73 | return m_buffer[m_index];
74 | }
75 | T newest() const
76 | {
77 | // undefined if nothing in here, return zero
78 | if (m_count == 0)
79 | return 0;
80 | // newest is index - 1, with wrap
81 | int index = m_index;
82 | if (--index < 0)
83 | index = m_count-1;
84 | return m_buffer[index];
85 | }
86 | T average() const
87 | {
88 | if (m_count == 0)
89 | return 0;
90 | return m_sum / m_count;
91 | }
92 | };
93 |
94 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
95 | // DecayingAverage Class Declaration
96 | //
97 |
98 | template
99 | class DecayingAverage
100 | {
101 | private:
102 | T m_last;
103 | bool m_lastvalid;
104 |
105 | public:
106 | inline DecayingAverage() { reset(); }
107 | T filter(T data, int fingers)
108 | {
109 | TT result = data;
110 | TT last = m_last;
111 | if (m_lastvalid)
112 | result = (result * N1) / D + (last * N2) / D;
113 | m_lastvalid = true;
114 | m_last = (T)result;
115 | return m_last;
116 | }
117 | inline void reset()
118 | {
119 | m_lastvalid = false;
120 | }
121 | };
122 |
123 | template
124 | class UndecayAverage
125 | {
126 | private:
127 | T m_last;
128 | bool m_lastvalid;
129 |
130 | public:
131 | inline UndecayAverage() { reset(); }
132 | T filter(T data)
133 | {
134 | TT result = data;
135 | TT last = m_last;
136 | if (m_lastvalid)
137 | result = (result * D) / N1 - (last * N2) / N1;
138 | m_lastvalid = true;
139 | m_last = (T)data;
140 | return (T)result;
141 | }
142 | inline void reset()
143 | {
144 | m_lastvalid = false;
145 | }
146 | };
147 |
148 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
149 | // Force Touch Modes
150 | //
151 |
152 | typedef enum {
153 | FORCE_TOUCH_DISABLED = 0,
154 | FORCE_TOUCH_BUTTON = 1,
155 | FORCE_TOUCH_THRESHOLD = 2,
156 | FORCE_TOUCH_VALUE = 3,
157 | FORCE_TOUCH_CUSTOM = 4
158 | } ForceTouchMode;
159 |
160 | #endif /* VoodooPS2TrackpadCommon_h */
161 |
--------------------------------------------------------------------------------
/VoodooPS2Trackpad/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
--------------------------------------------------------------------------------