Драйверы Macos от Wacom для таблеток Bamboo, Graphire, Intuos 1, 2 и 3 и Cintiq 1 -й поколения имеют в них ошибки, которые заставляют их полностью начать с Catalina MacOS 10.15 и более поздних версий (включая 11 Big Sur и 12 Monterey). Это не относится к драйверу Windows или к драйверам для их более новых планшетов.
Когда вы попытаетесь открыть панель предпочтения Wacom с бамбуковым планшетом, вы получите сообщение об ошибке с надписью «ожидание синхронизации», а затем, наконец, «есть проблема с вашим драйвером планшета. Пожалуйста, перезагрузите систему. Если проблема сохраняет переустановку. или обновить драйвер ». Для планшета Intuos 3 или Cintiq 1 -го поколения откроется панель предпочтений, но нажатие на что угодно приведет к сбою с помощью сообщения «В предпочтениях Wacom планшет была ошибка». Для планшетов Graphire и Intuos 1 и 2, установщик драйвера не мог даже работать на Каталине.
К счастью, я смог отследить проблемы, и я исправил драйверов, чтобы исправить их!
Мой фиксированный драйвер бамбука (v5.3.7-6) поддерживает эти планшеты:
My Fixed Graphire 1 & 2 и драйвер Intuos 1 и 2 (V6.1.6-4) поддерживает эти планшеты:
Мой фиксированный драйвер Graphire 3 (v5.2.6-5) поддерживает эти планшеты:
Мой фиксированный драйвер Graphire 4 (v5.3.0-3) поддерживает эти планшеты:
И мой фиксированный драйвер Intuos 3 и Cintiq (V6.3.15-3) поддерживает эти планшеты:
Для Intuos 4 мое исправление не нужно. Вместо этого вы можете использовать официальный водитель Wacom V6.3.41-2.
?? Упрощенные инструкции по английскому языку
?? / Instruções em português
?? 日本語で表示
?? ИНСТРИКИЯ НА РУССКОМ
?? Инструкторы En Español
?? Инструмент Po Polsku
?? Инструкции в Франсеи
Загрузите правильный установщик для вашего планшета здесь и дважды щелкните его, чтобы запустить его, он установит мою фиксированную версию драйвера Wacom:
Если вы получите сообщение об ошибке, что ваш Mac позволяет устанавливать только приложения в магазине приложений, щелкните правой кнопкой мыши и нажмите «Открыть».
После установки следуйте инструкциям в следующем разделе, чтобы исправить разрешения планшета.
Прикоснитесь к своему совету ручки к планшету, и он должен побудить вас посетить системные предпочтения> Безопасность и конфиденциальность> вкладка «Конфиденциальность», чтобы предоставить разрешения на планшет.
На странице доступности нажмите на патрон, чтобы разблокировать страницу, затем найти и отметьте любые записи PenTabletDriver
, WacomTabletDriver
TabletDriver
или WacomTabletSpringboard
которые вы видите в списке. Сделайте то же самое на странице мониторинга ввода.
Если ваш планшет поддерживает касание, коснитесь планшета пальцем, он должен снова побудить вас предоставить разрешения. На странице доступности отметьте вход ConsumerTouchDriver
или WacomTouchDriver
.
С некоторыми планшетами драйвер может появиться только на странице мониторинга ввода, и вам может потребоваться перезагрузить второй раз, чтобы он появился на странице доступности.
Скорее всего, у вас были разрешения, оставшиеся от предыдущего драйвера планшета, и все эти несвежие записи должны быть удалены так:
На странице «Доступность» безопасности и конфиденциальности найдите что -нибудь, связанное с Wacom в списке (например, PenTabletDriver
, WacomTabletDriver
, TabletDriver
, ConsumerTouchDriver
, WacomTabletSpringboard
, WacomTouchDriver
), выберите их и нажмите кнопку Minus, чтобы удалить их. Перейдите на «страницу мониторинга ввода» и сделайте то же самое.
Теперь либо перезагрузите компьютер, либо запустите эти две команды в терминале, чтобы перезагрузить драйвер планшета. Для таблеток Bamboo и Graphire 3 и 4:
launchctl unload /Library/LaunchAgents/com.wacom.pentablet.plist
launchctl load -w /Library/LaunchAgents/com.wacom.pentablet.plist
Для Graphire 1 и 2, интуитов и таблеток Cintiq:
launchctl unload /Library/LaunchAgents/com.wacom.wacomtablet.plist
launchctl load -w /Library/LaunchAgents/com.wacom.wacomtablet.plist
Это должно восстановить подсказки, чтобы попросить вас добавить разрешения, поэтому теперь начните инструкции в этом разделе.
Для нескольких людей драйвер WACOM никогда не появляется в списке мониторинга ввода для них. Чтобы исправить это, сначала откройте приложение «терминала» и вставьте эту линию и нажмите Enter, чтобы убедиться, что служба Wacom включена:
Для таблеток Bamboo и Graphire 3 и 4:
launchctl load -w /Library/LaunchAgents/com.wacom.pentablet.plist
Для Graphire 1 и 2, интуитов и таблеток Cintiq:
launchctl load -w /Library/LaunchAgents/com.wacom.wacomtablet.plist
Если это не запускает его, чтобы попросить вас добавить разрешения на мониторинг ввода при попытке использовать планшет, вы можете добавить его вручную.
В Finder нажмите Go -> Перейдите в папку, вставьте туда этот путь и нажмите OK:
/Library/Application Support/Tablet/
Там вы должны увидеть файл «pentabletdriver» (Bamboo), «Pentabletspringboard» (Graphire 3 и 4) или «Wacomtabletspringboard» (Graphire 1 & 2, Intuos, Cintiq).
Разблокируйте страницу мониторинга ввода, затем перетащите на него файл Pentabletdriver / Pentabletspringboard / Wacomtabletspringboard, чтобы добавить его в список, и убедитесь, что он тикает. Теперь перезагрузите компьютер, и когда вы пытаетесь использовать планшет, он должен побудить вас отметить его на странице доступности, после чего он должен начать работать.
Убедитесь, что у вас все еще нет самого последнего драйвера Wacom. Используйте «Wacom Utility»/ «Утилита планшета», чтобы полностью удалить все драйверы Wacom (а не просто перетаскивать их в мусор), а затем снова установите мой драйвер.
Коррумпированные предпочтения могут предотвратить работу, особенно если вы установили кучу разных версий драйверов, пытаясь заставить вещи работать. Используйте утилиту WACOM, чтобы сбросить свои предпочтения, перезагрузиться и снова использовать планшет.
Если вам понравилось, чтобы ваш планшет вернулся в действие, пожалуйста, подумайте о том, чтобы прислать мне совет!
Это поможет профинансировать меня и дальнейшее развитие этих фиксированных драйверов.
Pentabletdriver запускает два подчинка, чтобы выполнить работу для этого, ConsumerTouchDriver и TabletDriver. Чтобы найти эти драйверы в папке ресурсов, он в конечном итоге называет эту функцию, чтобы извлечь путь из URL:
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 */
}
Простите меня за перефразирование исходной цели C -кода как C ++, я не говорю об objc!
Когда CFURL создает путь, его отсчета начинается с 1. Он очередится с учетом количества ссылок, который будет уменьшен позже, вызывая на него autorelease()
, а затем возвращает его к драйверу Wacom. Этот призыв к autorelease
объединяется с вызовом Wacom retainAutoreleasedReturnValue()
, и так и оставляет отсчет ссылок пути нетронутым в 1.
Но теперь драйвер WACOM вызывает _objc_release()
на пути. Это уменьшает количество ссылок до 0, и путь немедленно освобожден!
Этот освободительный путь используется при запуске подворота, который может запустить Segfault в ProcessUtils::LaunchApplicationWithBundleID()
. Это убивает водителя.
Исправление-это изменение с одним байтом, которое заменяет вызов на _objc_release()
в PathFromURL
к вызову _objc_retain()
. Это предотвращает освобождение пути до его использования, который лечит Segfault.
ConsumperTouchDriver также содержит эту же ошибку, и патч там такая же.
И водителю ручки, и водителю касания нуждаются в исправлениях, чтобы они не сбились с ударом, когда выполняется мультитач жест, или кольцо прокрутки используется для масштабирования.
При выполнении жеста, функция CMacHIDGestureEventOSX1010::PostGesture
отвечает за отправку этого жеста в операционную систему:
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);
}
Обратите внимание, как результат CGEVENTCREATE отбрасывается в структуру? Предполагается, что CGEVEV - это непрозрачный тип, программы не должны знать и не полагаться на свой макет, поскольку его структура изменяется от версии ОС на версию ОС, но здесь он поднимается в структуру, чтобы его поля eventSubType
и eventDirAmount
могут быть назначенным напрямую. Эти два записи вызывают коррупцию кучи на Каталине и запускают аварию, потому что макет CGEvent
изменился со Сьерры!
Правильным способом хранения значений в событии является использование API CGEVENTSETINTEGERVALUEFIELD, которое позволяет вам ссылаться на поля CGEVEV с помощью логического идентификатора вместо их позиции в памяти. Итак, каковы эквивалентные идентификаторы поля для двух писаний, которые должен сделать драйвер WACOM?
Я разобрал матрос Сьерра, которая содержит реализацию для CGEventSetIntegerValueField
, чтобы увидеть, какими должны были быть идентификаторы для этих полей. Похоже, что eventSubType
может быть записан с помощью идентификатора поля 110, и eventDirAmount
может быть написан ID 115. Но эти идентификаторы полевых идентификаторов нигде не можно найти в документации Apple, что объясняет, почему Wacom не может их использовать!
Я сделал немного поиска и обнаружил, что эти поля недокументированы, потому что они являются частью частного API Apple. Этот заголовок Webkit раскрывает их имена:
kCGEventGestureHIDType = 110
kCGEventGestureSwipeValue = 115
kCGEventGesturePhase = 132
И эти частные поля API стабильны от Сьерры до Big Sur! Теперь, когда мы знаем это, эти два назначения в Eventtructure могут быть заменены этими вызовами, и сбои драйвера устраняются:
_CGEventSetIntegerValueField (eventStructure, 110 /* kCGEventGestureHIDType */ , gestureType_I);
_CGEventSetIntegerValueField (eventStructure, 115 /* kCGEventGestureSwipeValue */ , eventDirAmount);
В версии PostGesture с плавающей точкой есть такая же проблема:
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);
}
И мы можем исправить это так:
_CGEventSetIntegerValueField (eventStructure, 110 /* kCGEventGestureHIDType */ , gestureType_I);
_CGEventSetIntegerValueField (eventStructure, 115 /* kCGEventGestureSwipeValue */ , reinterpret_cast < int32_t &>(dirAmount));
_CGEventSetIntegerValueField (eventStructure, 132 /* kCGEventGesturePhase */ , this ->eventPhase);
На панели предпочтения Wacom Wacom Falls Falls Apple Bug 8746551. Поскольку MacOS Catalina, панель предпочтений эффективно разрушает работу NSApp->mainWindow
позволяя любому типу окна стать активным окном, даже простыня, которые были невозможно в предыдущих версиях MacOS и в автономных приложениях (в предыдущих версиях только фактическое окно основных предпочтений станет mainWindow
).
Когда модальный лист открыт, и пользователь хочет открыть новый лист, оригинальный лист должен быть сначала закрыт. Но ошибка Apple вызывает проверку Wacom, чтобы увидеть, открыт ли в настоящее время лист для сбоя, поскольку, когда он проверяет, чтобы увидеть, прикреплен ли лист к mainWindow
, он вместо этого в конечном итоге проверяет лист, прикрепленный к текущему листу, который не необъяснимым Станьте mainWindow
. Это вызывает аварию (например, в настройках картирования ручки).
Я исправил доступ к mainWindow
так что первое значение, которое прочитано, кэшируется впоследствии, так что до тех пор, пока начальное значение является разумным, оно не сломается после обновления mainWindow
, чтобы указывать на первое открытое лист (см. PenTablet.prefpane.newcode.asm
).
У драйвера Intuos 3 и Cintiq есть ошибка на панели предпочтения, которая заставляет его сбой, как только нажимается на предмет.
Одной из основных особенностей пользовательского интерфейса Pane Pane является списки значков, представляющих планшеты, инструменты и приложения, которые вы можете настроить. Этот элемент управления списком значков использует такую функцию для отправки событий (таких как клики) своим детям:
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);
}
Проблема с этим кодом заключается в том, что для возврата объекта () функция handler()
для Event Handler (), который он затем бесполезно сохраняет () и выпускает (). Но одна из функций обработчика, которая будет вызвана OEventDispatcher_Professional::listClickAction()
, и эта функция является void
функцией (без четко определенного возвращаемого значения)!
Так что action:()
в конечном итоге вызывает retain()
и release()
на указателе мусора, который вызывает сегфол.
Патч здесь прост - эта бесполезная пара вызовов retain()
и release()
удаляется. Такая же ошибка существует в ONumberTextField::textDidChange:
с тем же исправлением.
Есть еще одна проблема с этим драйвером. Если, пытаясь заставить ваш планшет работать, вы случайно установите последний драйвер WACOM (который не поддерживает Intuos 3), он записывает более новую формату предпочтения, что старый драйвер Intuos 3 будет сбой при попытке прочитать. И эта ситуация не решается, пользователь должен вручную использовать утилиту Wacom для удаления предпочтений планшета, чтобы исправить его.
Это странно, потому что файл предпочтений включает номер версии, который предназначен для того, чтобы избежать этой самой ситуации. Старый драйвер использует версию 5, а последний драйвер использует версию 6:
< ImportFileVersion type = " integer " >6</ ImportFileVersion >
И код драйвера явно проверяет этот номер версии и должен прервать, когда он слишком новый:
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
}
}
...
}
Но водитель никогда не прерывается, вместо этого он вылетает, пытаясь загрузить предпочтения. Так что здесь идет не так? Секрет находится внутри функции MigratePen()
. Эта функция предназначена для обновления более старых настройки файлов до текущей версии, но, к сожалению, в процессе она безоговорочно перезаписывает ImportFileVersion
с текущей версией (5)! Это оставляет CTabletDriver::ReadSettings()
не может определить, что настройки слишком новы, чтобы их проанализировали.
Чтобы решить это, я усилил неверный код обнаружения версий от MigratePen()
:
if (settingsVersion < 1 ) {
// Report invalid settings version and return NULL
}
Сделать это:
if (settingsVersion < 1 || settingsVersion > 5 ) {
// Report invalid settings version and return NULL
}
Так что теперь, если предпочтения слишком новые, MigratePen()
не будет пытаться обновить их, и ReadSettings()
будет чисто пропустить загрузку предпочтений. Это приводит к тому, что предпочтения оставаться в своих значениях по умолчанию, и если пользователь редактирует настройки, используя панель предпочтений, настройки должны быть чистыми.
Установщики для драйверов Graphire - это старый формат, который Каталина больше не поддерживает, поэтому мне пришлось полностью их восстановить.
Панель предпочтения Graphire неправильно полагалась на частные символы из стандартной библиотеки MacOS, которые больше не присутствуют в Каталине, поэтому она больше не может начинаться.
Например, функция Wacom nsnibwakingoverride :: wapefromnib () вызывается во время дезиализации графического интерфейса и добавляет загруженное управление графическим интерфейсом к карте, чтобы к ней можно было получить доступ позже:
void NSNibWakingOverride::awakeFromNib (NSControl * this ) {
OMasterDictionaryPtr-> addObject :withTag:( this , this -> _tag ));
}
Но это зависит от чтения nscontrol._tag, который является частным полем. В MacOS 10.9, который работал, потому что NSControl был определенным образом:
@interface NSControl : NSView
{
/* All instance variables are private */
NSInteger _tag;
id _cell;
struct __conFlags {
...
} _conFlags;
}
Но в MacOS 10.10 NSControl был рефактирован, чтобы переместить поле _tag в новое поле _aux, что делает его недоступным:
@interface NSControl : NSView
{
/* All instance variables are private */
NSControlAuxiliary *_aux;
id _cell;
struct __conFlags {
...
} _conFlags;
}
@property NSInteger tag;
Я исправил AwakeFromnib, чтобы он правильно назвал функцию публичного доклада для этого поля:
void NSNibWakingOverride::awakeFromNib (NSControl * this ) {
OMasterDictionaryPtr-> addObject :withTag:( this , this -> tag ()));
}
В функции Wacom's OpoPupoutlineView :: reloadData (), частное поле nstableView._datasource неправильно читается напрямую:
void OPopupOutlineView::reloadData (OPopupOutlineView * this ) {
this -> _dataSource . willReloadDataForOutlineView ( this );
...
}
Поэтому я исправил это, чтобы использовать общедоступный доход:
void OPopupOutlineView::reloadData (OPopupOutlineView * this ) {
this -> dataSource ()-> willReloadDataForOutlineView ( this );
...
}
Эти драйверы имеют те же проблемы, что и драйверы Graphire 3 и 4, плюс та же самая проблема _dataSource
в их ORadialSubMenuTableView::reloadData() method
с таким же исправлением.