Die MacOS -Treiber von Wacom für Bambus-, Graphire-, Intuos 1-, 2 & 3- und Cintiq 1st -Gen -Tablets enthalten Fehler, die dazu führen, dass sie nicht mit macOS 10.15 Catalina und späteren Versionen (einschließlich 11 Big Sur und 12 Monterey) nicht beginnen. Dies gilt nicht für den Windows -Treiber oder für die Treiber für ihre neueren Tablets.
Wenn Sie versuchen, den Wacom Preference -Bereich mit einem Bambus -Tablet zu öffnen, erhalten Sie eine Fehlermeldung mit der Aufschrift "Warten auf die Synchronisation". Dann gibt es schließlich ein Problem mit Ihrem Tablet -Treiber. Bitte starten Sie Ihr System neu. Wenn das Problem bestehen bleibt oder aktualisieren Sie den Treiber ". Für ein Tablet für Inuos 3 oder Cintiq 1. General wird das Präferenzbereich geöffnet. Wenn Sie jedoch auf irgendetwas klicken, stürzt es mit der Nachricht zum Absturz "Es gab einen Fehler in den Vorlieben der Wacom -Tablet". Für Graphire und Intuos 1 & 2 Tablets konnte der Installateur des Fahrers nicht einmal auf Catalina laufen.
Zum Glück konnte ich die Probleme aufspüren und habe die Treiber gepatcht, um sie zu beheben!
Mein fester Bambusfahrer (V5.3.7-6) unterstützt diese Tablets:
Mein fester Graphire 1 & 2 und Intuos 1 & 2 Treiber (V6.1.6-4) unterstützt diese Tablets:
Mein fester Graphire 3- Treiber (V5.2.6-5) unterstützt diese Tablets:
Mein fester Graphire 4- Treiber (V5.3.0-3) unterstützt diese Tablets:
Und mein fester Inuos 3- und Cintiq -Treiber (v6.3.15-3) unterstützt diese Tablets:
Für Inuos 4 ist mein Fix nicht benötigt. Sie können stattdessen Wacoms offizielles Fahrer V6.3.41-2 verwenden.
? Vereinfachte englische Anweisungen
? / ?? Instruções em Português
? 日本語で表示
? A
? Anweisungen en español
? Instrukcja Po Polsku
? Anweisungen und Français
Laden Sie hier den richtigen Installateur für Ihr Tablet herunter und doppelklicken Sie darauf, um es auszuführen. Dadurch wird meine feste Version des Wacom -Treibers installiert:
Wenn Sie eine Fehlermeldung erhalten, dass Ihr Mac nur über Apps im App Store installiert werden kann, klicken Sie mit der rechten Maustaste darauf und klicken Sie stattdessen auf "Öffnen".
Befolgen Sie nach der Installation die Anweisungen im nächsten Abschnitt, um die Berechtigungen des Tablets zu reparieren.
Berühren Sie Ihren Stifttipp mit Ihrem Tablet und sollten Sie die Systemeinstellungen> Sicherheit und Privatsphäre> Registerkarte Datenschutz auffordern, um die Tablet -Berechtigungen zu erteilen.
Klicken Sie auf der Seite "Barrierefreiheit" auf das Vorhängeschloss, um die Seite zu entsperren. Ermitteln und ankreuzen Sie einen PenTabletDriver
, WacomTabletDriver
TabletDriver
oder WacomTabletSpringboard
-Einträge, die Sie in der Liste sehen. Tun Sie dasselbe auf der Seite Eingabeüberwachung.
Wenn Ihr Tablet Touch unterstützt, berühren Sie das Tablet mit dem Finger, sollten Sie erneut Berechtigungen erteilen. Ticken Sie auf der Seite "Barrierefreiheit" den Eintrag ConsumerTouchDriver
oder WacomTouchDriver
.
Mit einigen Tablets wird der Treiber möglicherweise nur auf der Eingabeüberwachungsseite angezeigt, und Sie müssen möglicherweise auch ein zweites Mal neu starten, damit er auch auf der Seite "Barrierefreiheit" angezeigt wird.
Sie hatten wahrscheinlich Berechtigungen, die vom vorherigen Tablet -Treiber übrig geblieben sind, und diese abgestandenen Einträge müssen alle wie SO entfernt werden:
Finden Sie auf der "Barrierefreiheit" -Seite von Sicherheit und Privatsphäre alles, was mit Wacom in der Liste zu tun hat (z. B. PenTabletDriver
, WacomTabletDriver
, TabletDriver
, ConsumerTouchDriver
, WacomTabletSpringboard
, WacomTouchDriver
), wählen Sie sie aus und klicken Sie auf die Taste der Minus, um sie zu entfernen. Gehen Sie zur "Eingabeüberwachungsseite" und tun Sie dort dasselbe.
Starten Sie jetzt entweder Ihren Computer neu oder führen Sie diese beiden Befehle im Terminal aus, um den Tablet -Treiber neu zu laden. Für Bambus und Graphire 3 & 4 Tablets:
launchctl unload /Library/LaunchAgents/com.wacom.pentablet.plist
launchctl load -w /Library/LaunchAgents/com.wacom.pentablet.plist
Für Graphire 1 & 2, Intuos und Cintiq -Tablets:
launchctl unload /Library/LaunchAgents/com.wacom.wacomtablet.plist
launchctl load -w /Library/LaunchAgents/com.wacom.wacomtablet.plist
Dies sollte die Eingabeaufforderungen wiederherstellen, um Sie aufzufordern, Berechtigungen hinzuzufügen. Beginnen Sie nun die Anweisungen in diesem Abschnitt erneut.
Für eine Handvoll Menschen erscheint der Wacom -Treiber nie in der Eingangsüberwachungsliste für sie. Um dies zu beheben, öffnen Sie zunächst die "Terminal" -App und fügen Sie diese Zeile ein und drücken Sie die Eingabetaste, um sicherzustellen, dass der Wacom -Dienst aktiviert ist:
Für Bambus und Graphire 3 & 4 Tablets:
launchctl load -w /Library/LaunchAgents/com.wacom.pentablet.plist
Für Graphire 1 & 2, Intuos und Cintiq -Tablets:
launchctl load -w /Library/LaunchAgents/com.wacom.wacomtablet.plist
Wenn dies nicht ausgelöst wird, um Sie aufzufordern, die Berechtigungen für Eingabeüberwachungen hinzuzufügen, wenn Sie versuchen, das Tablet zu verwenden, können Sie es stattdessen manuell hinzufügen.
Klicken Sie im Finder klicken Sie auf Go -> Gehen Sie in den Ordner und fügen Sie diesen Pfad dort ein und klicken Sie auf OK:
/Library/Application Support/Tablet/
Dort sollten Sie eine "PentabletDriver" -Datei (Bamboo), "Pentabletspringboard" (Graphire 3 & 4) oder "WacomTabletspringboard" (Graphire 1 & 2, Intuos, Cintiq) sehen.
Entsperren Sie die Seite Eingabeüberwachung und ziehen Sie dann die Datei PentabletDriver / PentabletRingboard / WacomTabletRingboard darauf, um sie der Liste hinzuzufügen, und stellen Sie sicher, dass sie angekreuzt wird. Starten Sie nun Ihren Computer neu und wenn Sie versuchen, das Tablet zu verwenden, sollten Sie es auch auf der Seite "Barrierefreiheit" auffordern. Danach sollte es arbeiten.
Stellen Sie sicher, dass Sie den neuesten Treiber von Wacom noch nicht installiert haben. Verwenden Sie "Wacom Utility"/ "Tablet Utility", um alle Treiber von Wacom vollständig zu deinstallieren (anstatt sie nur in den Müll zu ziehen) und dann meinen Treiber erneut installieren.
Durch korrupte Vorlieben können die Dinge funktionieren, insbesondere wenn Sie eine Reihe verschiedener Treiberversionen installiert haben, während Sie versuchen, die Dinge zum Laufen zu bringen. Verwenden Sie das Wacom -Dienstprogramm, um Ihre Einstellungen zurückzusetzen, neu zu starten und das Tablet erneut zu verwenden.
Wenn Sie es genossen haben, Ihr Tablet wieder in Aktion zu haben, schicken Sie mir bitte einen Tipp!
Dies wird helfen, mich zu finanzieren und diese festen Treiber weiter zu entwickeln.
PentabletDriver startet zwei Unterbinder, um die Arbeit dafür zu erledigen, ConsumertouchDriver und TabletDriver. Um diese Treiber in seinem Ressourcenordner zu finden, ruft diese Funktion schließlich auf, um einen Pfad aus einer URL zu extrahieren:
CFString * MacPaths::PathFromURL (CFURL *url)
{
CFString *path;
path = _objc_retainAutoreleasedReturnValue (url-> path ());
_objc_release (path); /* Whoops, path is destroyed here! */
return path; /* Now returning a free'd path */
}
Verzeihen Sie mir, dass ich den ursprünglichen objektiven C -Code als C ++ umschrieben habe. Ich spreche nicht objc!
Wenn CFURL den Pfad erstellt, beginnt seine Referenzzahl bei 1. Es stellt die Referenzzahl nach dem Aufrufen von autorelease()
darauf an und gibt ihn dann an den Wacom -Treiber zurück. Dieser Anruf bei autorelease
kombiniert mit Wacoms retainAutoreleasedReturnValue()
-Anruf und so und verlässt die Referenzzahl des Pfades unberührt bei 1.
Aber jetzt ruft der Wacom -Treiber _objc_release()
auf dem Pfad auf. Dies verringert seine Referenzzahl auf 0 und der Weg wird sofort befreit!
Dieser befreite Pfad wird beim Starten des Unterfahrts verwendet, der einen SEGFAULT in ProcessUtils::LaunchApplicationWithBundleID()
auslösen kann. Dies tötet den Fahrer.
Das Fix ist eine Einzelbyte-Änderung, die den Aufruf an _objc_release()
in PathFromURL
zu einem Aufruf an _objc_retain()
ersetzt. Dies verhindert, dass der Pfad befreit wird, bevor er verwendet wird, was den Segfault heilt.
Der ConsumerTouchDriver enthält auch denselben Fehler, und der Patch ist dort derselbe.
Sowohl der Stiftfahrer als auch der Touch-Treiber benötigen Korrekturen, um sie daran zu hindern, zu stürzen, wenn eine Multi-Touch-Geste ausgeführt wird, oder mit dem Scroll-Ring wird zum Zoomen verwendet.
Wenn eine Geste durchgeführt wird, ist die Funktion CMacHIDGestureEventOSX1010::PostGesture
für das Senden dieser Geste an das Betriebssystem verantwortlich:
void CMacHIDGestureEventOSX1010::PostGesture (EIOHIDEventType gestureType_I, int32_t eventDirAmount)
{
__CFDataOSX1010 *eventStructure;
if (gestureType_I == 61 /* kCGHIDEventTypeGestureStarted */ ) {
this -> eventPhase = 1 /* kCGSGesturePhaseBegan */ ;
} else {
this -> eventPhase = 4 /* kCGSGesturePhaseEnded */ ;
(**(code **)(*( long *) this + 0x18 ))( 0 , this ,( uint32_t ) eventDirAmount);
}
eventStructure = (__CFDataOSX1010 *) _CGEventCreate ( 0 ); // Dubious
_CGEventSetType (eventStructure, 29 /* kCGSEventGesture */ );
eventStructure-> eventSubType = gestureType_I; // Relies on the exact memory layout of CGEvent (!)
eventStructure-> eventDirAmount = eventDirAmount; // Ditto
_CGEventPost ( 0 , eventStructure);
_CFRelease (eventStructure);
}
Beachten Sie, wie das Ergebnis von cgeventcreate in eine Struktur gegossen wird? CGEvent soll ein undurchsichtiger Typ sein, Programme eventDirAmount
nicht wissen oder auf sein Layout verlassen, da seine Struktur von eventSubType
zu Betriebssystemversion ändert, aber hier wird es in eine Struktur gegossen direkt zugewiesen werden. Diese beiden Schreibungen verursachen eine Haufen Korruption auf Catalina und lösen einen Absturz, da sich das Layout von CGEvent
seit Sierra geändert hat!
Die richtige Möglichkeit, Werte in ein Ereignis zu speichern, besteht darin, die CGEVentsSetintergerValuefield -API zu verwenden, mit der Sie sich anstelle ihrer Position im Speicher auf Felder von CGEvent beziehen können. Was sind die äquivalenten Feld -IDs für die beiden, die der Wacom -Treiber machen muss?
Ich habe das Skylicht -Framework von MacOS Sierra zerlegt, das die Implementierung für CGEventSetIntegerValueField
enthält, um zu sehen, was die IDs für diese Felder hätten gewesen sein sollen. Es scheint, dass der eventSubType
von Field ID 110 geschrieben werden kann und der eventDirAmount
durch ID 115 geschrieben werden kann. Diese Feld -IDs sind jedoch nirgends in Apples Dokumentation zu finden, was erklärt, warum Wacom sie nicht verwenden konnte!
Ich habe ein paar Googeln gemacht und festgestellt, dass diese Felder nicht dokumentiert sind, weil sie Teil der privaten API von Apple sind. Dieser Webkit -Header enthüllt ihre Namen:
kCGEventGestureHIDType = 110
kCGEventGestureSwipeValue = 115
kCGEventGesturePhase = 132
Und diese privaten API -Felder sind von Sierra bis nach Big Sur stabil! Nachdem wir dies wissen, können die beiden Aufträge zur Ereignisstruktur durch diese Anrufe ersetzt werden, und der Treiberstürze wird beseitigt:
_CGEventSetIntegerValueField (eventStructure, 110 /* kCGEventGestureHIDType */ , gestureType_I);
_CGEventSetIntegerValueField (eventStructure, 115 /* kCGEventGestureSwipeValue */ , eventDirAmount);
Die Gleitkomma-Version von Postgesture hat das gleiche Problem:
void CMacHIDGestureEventOSX1010::PostGesture (EIOHIDEventType eventSubType, float dirAmount)
{
__CFDataOSX1010 *eventStructure;
eventStructure = (__CFDataOSX1010 *) _CGEventCreate ( 0 );
_CGEventSetType (eventStructure, 29 /* kCGSEventGesture */ );
eventStructure-> eventSubType = eventSubType; // !
eventStructure-> eventDirAmount = reinterpret_cast < int32_t &>(dirAmount); // !
eventStructure-> eventState = this -> eventPhase ; // !
if ( this -> eventPhase == 1 /* kCGSGesturePhaseBegan */ ) {
this -> eventPhase = 2 /* kCGSGesturePhaseChanged */ ;
}
_CGEventSetLocation (eventStructure, GetMouseLocationInScreenCoordinates ());
_CGEventPost ( 0 , eventStructure);
_CFRelease (eventStructure);
}
Und wir können es so patchen:
_CGEventSetIntegerValueField (eventStructure, 110 /* kCGEventGestureHIDType */ , gestureType_I);
_CGEventSetIntegerValueField (eventStructure, 115 /* kCGEventGestureSwipeValue */ , reinterpret_cast < int32_t &>(dirAmount));
_CGEventSetIntegerValueField (eventStructure, 132 /* kCGEventGesturePhase */ , this ->eventPhase);
In Wacoms Präferenzbereich fällt Wacom zum Opfer von Apple Bug 8746551. Da MacOS Catalina das Präferenzbereich effektiv den Betrieb von NSApp->mainWindow
durchbricht, indem ein Fenstertyp zum aktiven Fenster werden kann, sogar Blätter, was in früheren Versionen von nicht unmöglich war MacOS und in eigenständigen Apps (in früheren Versionen werden nur das Fenster der tatsächlichen Haupteinstellungen zum mainWindow
).
Wenn ein Modalblatt geöffnet ist und der Benutzer ein neues Blatt öffnen möchte, muss das Originalblatt zuerst geschlossen werden. Der Fehler von Apple führt jedoch zu Wacoms Überprüfung, um festzustellen, ob derzeit ein Blatt geöffnet ist, da es beim Überprüfen der Überprüfung, ob ein Blatt an den mainWindow
angeschlossen ist Werden Sie der mainWindow
. Dies löst einen Absturz aus (z. B. in den Pen -Mapping -Einstellungen).
Ich habe die Zugriffe mainWindow
mainWindow
so gepatcht PenTablet.prefpane.newcode.asm
dass der erste Wert, der gelesen wird PenTablet.prefpane.newcode.asm
).
Der Treiber von Intuos 3 und Cintiq enthält einen Fehler im Präferenzbereich, der es zum Absturz bringt, sobald ein Element angeklickt wird.
Eine der Hauptmerkmale der Benutzeroberfläche des Präferenzbereichs sind die Listen der Symbole, die die Tablets, Tools und Anwendungen darstellen, die Sie konfigurieren können. Mit dieser Icon List Control wird eine Funktion wie diese verwendet, um Ereignisse (z. B. Klicks) an seine Kinder zu versenden:
void WTCCPLIconList::action:(ID event, SEL param_2, ID param_3) {
int selectedIndex;
ID target;
ID action;
target = _objc_retainAutoreleasedReturnValue (event-> target ());
action = event-> action ();
selectedIndex = event-> selectedIndex ();
event-> scrollIndexToVisible (selectedIndex);
if ((target != 0 ) && (action != 0 )) {
code* handler = target-> methodForSelector (action);
Object *result = handler (target, action, event);
result = _objc_retainAutoreleasedReturnValue (result); // (!)
_objc_release (result); // (!)
}
event-> updateButtonStates ();
_objc_release (target);
}
Das Problem mit diesem Code ist, dass die Funktion des Ereignisses handler()
ein Objekt zurückgibt, das es dann nutzlos beibehält () und veröffentlicht (). Aber eine der Handlerfunktionen, die aufgerufen werden, ist OEventDispatcher_Professional::listClickAction()
, und diese Funktion ist eine void
-Funktion (ohne genau definierten Rückgabewert)!
Also action:()
ruft retain()
und release()
auf einem Müllzeiger auf, der einen Segfault verursacht.
Der Patch hier ist einfach - das nutzlose Paar von retain()
und release()
wird gelöscht. Der gleiche Fehler gibt es in ONumberTextField::textDidChange:
mit demselben Fix.
Es gibt ein weiteres Problem mit diesem Fahrer. Wenn Sie beim Versuch, Ihr Tablet zum Laufen zu bringen, versehentlich den neuesten Wacom-Treiber installieren (das Intuos 3 nicht unterstützt), schreibt es eine neuere Format-Präferenzdatei, die der alte Intuos 3-Treiber beim Lesen stürzt. Und diese Situation löst sich nicht selbst, der Benutzer muss das Wacom -Dienstprogramm manuell verwenden, um die Tablet -Einstellungen zu löschen, um es zu beheben.
Dies ist seltsam, da die Präferenzdatei eine Versionsnummer enthält, die genau diese Situation vermeiden soll. Der alte Treiber verwendet Version 5, und der neueste Treiber verwendet Version 6:
< ImportFileVersion type = " integer " >6</ ImportFileVersion >
Und der Treibercode prüft explizit auf diese Versionsnummer und sollte abbrechen, wenn er zu neu ist:
CTabletDriver::ReadSettings (basic_string settingsFilename, ...)
{
basic_string settingsFileContent;
CSettingsMap settingsMap;
...
ReadFromXMLFile (settingsMap, settingsFilename, settingsFileContent);
SettingsMigration *migration = SettingsMigration::MigratePen (settingsMap);
if (migration != nullptr ) {
int fileVersion = settingsMap. IntegerForKeyWithDefault ( " ImportFileVersion " , - 1 )
if (fileVersion < 1 ) {
// Report error
} else if (fileVersion <= this -> supportedVersion ) {
// Accept the loaded settings
} else {
// Report error: Settings are too new
}
}
...
}
Aber der Fahrer bricht nie ab, stattdessen stürzt er ab, während er versucht, die Einstellungen zu laden. Also, was läuft hier schief? Das Geheimnis liegt in der Funktion MigratePen()
. Diese Funktion wurde entwickelt, um ältere Einstellungsdateien auf die aktuelle Version zu aktualisieren, aber leider überschreibt sie die ImportFileVersion
mit der aktuellen Version (5) bedingungslos. Dies lässt CTabletDriver::ReadSettings()
nicht feststellen, dass die Einstellungen zu neu sind, um analysiert zu werden.
Um dies zu lösen, habe ich den ungültigen Versionserkennungscode von MigratePen()
verstärkt:
if (settingsVersion < 1 ) {
// Report invalid settings version and return NULL
}
Um es zu machen:
if (settingsVersion < 1 || settingsVersion > 5 ) {
// Report invalid settings version and return NULL
}
Wenn die Einstellungen nun zu neu sind, wird MigratePen()
nicht versuchen, sie zu aktualisieren, und ReadSettings()
überspringt das Laden der Einstellungen sauber. Dies führt dazu, dass die Vorlieben an ihren Standardeinstellungen bleiben. Wenn der Benutzer die Einstellungen mit dem Präferenzbereich bearbeitet, sollten die Einstellungen sauber überschrieben werden.
Die Installateure für die Graphire -Treiber sind ein altes Format, das Catalina nicht mehr unterstützt, daher musste ich sie vollständig wieder aufbauen.
Die Präferenzfenster von Graphire stützte sich fälschlicherweise auf private Symbole aus der MacOS -Standardbibliothek, die nicht mehr in Catalina vorhanden sind, sodass sie nicht mehr beginnen konnten.
Zum Beispiel wird die NSnibwakingOverride :: AwakeFromnib () -Funktion von Wacom während der GUI -Deserialisierung aufgerufen und fügt die geladene GUI -Steuerung einer Karte hinzu, damit sie später durch sein Tag zugegriffen werden kann:
void NSNibWakingOverride::awakeFromNib (NSControl * this ) {
OMasterDictionaryPtr-> addObject :withTag:( this , this -> _tag ));
}
Dies beruht jedoch darauf, NSControl._Tag zu lesen, ein privates Feld. In macOS 10.9 funktionierte das, weil NSControl so definiert wurde:
@interface NSControl : NSView
{
/* All instance variables are private */
NSInteger _tag;
id _cell;
struct __conFlags {
...
} _conFlags;
}
In MacOS 10.10 wurde NSControl jedoch neu gestaltet, um das Feld _TAG in ein neues Feld zu verschieben, was es unzugänglich macht:
@interface NSControl : NSView
{
/* All instance variables are private */
NSControlAuxiliary *_aux;
id _cell;
struct __conFlags {
...
} _conFlags;
}
@property NSInteger tag;
Ich habe wachfromnib gepatcht, damit sie die öffentliche Accessor -Funktion für dieses Feld ordnungsgemäß aufgerufen hat:
void NSNibWakingOverride::awakeFromNib (NSControl * this ) {
OMasterDictionaryPtr-> addObject :withTag:( this , this -> tag ()));
}
In Wacoms OpopupoutlineView :: ReloadData () -Funktion wird das private nstableView._datasource -Feld fälschlicherweise direkt gelesen:
void OPopupOutlineView::reloadData (OPopupOutlineView * this ) {
this -> _dataSource . willReloadDataForOutlineView ( this );
...
}
Also habe ich dies gepatcht, um stattdessen den öffentlichen Accessor zu verwenden:
void OPopupOutlineView::reloadData (OPopupOutlineView * this ) {
this -> dataSource ()-> willReloadDataForOutlineView ( this );
...
}
Diese Treiber haben die gleichen Probleme wie die Graphire 3 & 4 -Treiber sowie das gleiche Problem _dataSource
in ihrer ORadialSubMenuTableView::reloadData() method
mit derselben Lösung.