Wacomの竹、グラファイヤ、Intuos 1、2、3、Cintiq 1st GenタブレットのMacosドライバーには、Macos 10.15 Catalinaおよびその後のバージョン(11のBig Surおよび12 Montereyを含む)で完全に開始できないバグが含まれています。これは、Windowsドライバーや、新しいタブレットのドライバーには適用されません。
竹のタブレットでWacom Preferenceペインを開こうとすると、「同期を待っている」というエラーメッセージが表示され、最後に「タブレットドライバーに問題があります。システムを再起動してください。またはドライバーを更新します」。 Intuos 3またはCintiq 1st Genタブレットの場合、優先ペインが開きますが、クリックすると「Wacom Tabletの好みにエラーがありました」というメッセージでクラッシュします。 GraphireおよびIntuos 1および2タブレットの場合、ドライバーのインストーラーはカタリナで走ることさえできませんでした。
ありがたいことに、私は問題を追跡することができ、それらを修正するためにドライバーにパッチを当てました!
私の固定竹の運転手(v5.3.7-6)はこれらのタブレットをサポートしています。
私の固定グラファイヤ1および2およびIntuos 1&2ドライバー(v6.1.6-4)は、これらのタブレットをサポートしています。
私の固定グラファイヤ3ドライバー(v5.2.6-5)はこれらのタブレットをサポートしています。
私の固定グラファイヤ4ドライバー(v5.3.0-3)はこれらのタブレットをサポートしています。
そして、私の固定Intuos 3とCintiqドライバー(v6.3.15-3)がこれらのタブレットをサポートしています。
Intuos 4の場合、私の修正は必要ありません。代わりに、Wacomの公式ドライバーv6.3.41-2を使用できます。
??簡素化された英語の指示
?? / ?? Instruçıesemportuguês
?? 日本語で表示
?? □ƒстрокциянаросско便
?? instrucciones enespañol
?? Instrukcja Po Polsku
?? françaisの指示
ここからタブレットの正しいインストーラーをダウンロードし、それをダブルクリックして実行すると、これによりWacomのドライバーの固定バージョンがインストールされます。
MacがアプリをApp Storeからのみインストールできるというエラーメッセージが表示された場合は、右クリックして[代わりに[開く]をクリックします。
インストール後、次のセクションの指示に従って、タブレットの権限を修正します。
ペンのヒントをタブレットにタッチすると、システムの設定>セキュリティとプライバシー> [プライバシー]タブにアクセスして、タブレットの許可を許可するように求めてください。
アクセシビリティページで、南京錠をクリックしてページのロックを解除し、リストに表示されているPenTabletDriver
、 WacomTabletDriver
TabletDriver
、またはWacomTabletSpringboard
エントリを見つけてチェックします。入力監視ページで同じことをします。
タブレットがタッチをサポートしている場合は、指でタブレットをタッチすると、再度許可を付与するように促す必要があります。アクセシビリティページで、 ConsumerTouchDriver
またはWacomTouchDriver
エントリをチェックします。
一部のタブレットを使用すると、ドライバーは入力監視ページにのみ表示される場合があり、アクセシビリティページにも表示されるまでに再起動する必要があります。
以前のタブレットドライバーから許可が残っている可能性がありますが、これらの古いエントリはすべて削除する必要があります。
セキュリティとプライバシーの「アクセシビリティ」ページで、リスト内のWacomに関連するもの( PenTabletDriver
、 WacomTabletDriver
、 TabletDriver
、 ConsumerTouchDriver
、 WacomTabletSpringboard
、 WacomTouchDriver
)を見つけて、それらを選択して、[マイナス]ボタンをクリックして削除します。 「入力監視ページ」に移動して、そこで同じことをします。
次に、コンピューターを再起動するか、ターミナルでこれら2つのコマンドを実行して、タブレットドライバーをリロードします。竹とグラファイヤの場合は3錠と4錠の場合:
launchctl unload /Library/LaunchAgents/com.wacom.pentablet.plist
launchctl load -w /Library/LaunchAgents/com.wacom.pentablet.plist
Graphire 1&2、Intuos、およびCintiqタブレットの場合:
launchctl unload /Library/LaunchAgents/com.wacom.wacomtablet.plist
launchctl load -w /Library/LaunchAgents/com.wacom.wacomtablet.plist
これにより、プロンプトが復元され、アクセス許可を追加するように要求するため、このセクションの指示を再度開始します。
少数の人々にとって、WACOMドライバーは彼らの入力監視リストに決して現れません。これを修正するには、最初に「ターミナル」アプリを開き、この行を貼り付けてEnterを押して、Wacomサービスが有効になっていることを確認してください。
竹とグラファイヤの場合は3錠と4錠の場合:
launchctl load -w /Library/LaunchAgents/com.wacom.pentablet.plist
Graphire 1&2、Intuos、Cintiqタブレットの場合:
launchctl load -w /Library/LaunchAgents/com.wacom.wacomtablet.plist
タブレットを使用しようとするときに入力監視アクセス許可を追加するように要求するようにトリガーしない場合は、代わりに手動で追加できます。
Finderで、[Go-> [>]フォルダーに移動し、このパスをそこに貼り付けて[OK]をクリックします。
/Library/Application Support/Tablet/
そこには、「Pentabletdriver」ファイル(竹)、「Pentabletspringboard」(グラファイア3&4)、または「wacomtabletspringboard」(Graphire 1&2、Intuos、cintiq)が表示されます。
入力監視ページのロックを解除してから、Pentabletdriver / Pentabletabletspringboard / wacomtabletspringboardファイルをリストに追加して、リストに追加して確認します。コンピューターを再起動すると、タブレットを使用しようとすると、アクセシビリティページにもチェックマークを付けるように求められます。その後、動作を開始する必要があります。
Wacomの最新のドライバーがまだインストールされていないことを確認してください。 「Wacom Utility」/「Tablet Utility」を使用して、すべてのWacomのドライバーを完全にアンインストールし(単にゴミにドラッグするのではなく)、ドライバーを再度インストールします。
腐敗した好みは、特に物事を機能させようとしている間にさまざまなドライバーバージョンの束をインストールした場合、物事が機能するのを防ぐことができます。 Wacomユーティリティを使用して好みをリセットし、再起動し、タブレットを再起動してみてください。
タブレットを動作させるのを楽しんだ場合は、ヒントを送ってください。
これは、私に資金を提供し、これらの固定ドライバーのさらなる開発に役立ちます。
Pentabletdriverは、2つのサブドライバーを起動して、そのための作業を行います。リソースフォルダー内のこれらのドライバーを見つけるために、最終的にこの関数を呼び出して、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 autorelease()
を呼び出すことにより、後で参照カウントをキューに照会し、Wacomのドライバーに返します。 Autorelease To autorelease
のこの呼び出しは、WacomのretainAutoreleasedReturnValue()
コールとペアを組み合わせて、1でパスの参照カウントを触れられないままにします。
しかし、現在、Wacomドライバーはパスで_objc_release()
を呼び出します。これにより、参照カウントが0に減少し、パスはすぐに解放されます!
この解放されたパスは、サブドライバーの起動中に使用されます。これにより、 ProcessUtils::LaunchApplicationWithBundleID()
のsegfaultをトリガーできます。これはドライバーを殺します。
修正は、 PathFromURL
の_objc_release()
への呼び出しを_objc_retain()
の呼び出しに置き換えるシングルバイトの変更です。これにより、パスが使用される前に解放されるのを防ぎ、SegFaultを治します。
ConsumertouchDriverにはこの同じバグも含まれており、パッチは同じです。
ペンドライバーとタッチドライバーの両方が、マルチタッチジェスチャーが実行されたときにクラッシュするのを防ぐために修正を修正する必要があります。また、スクロールリングを使用してズームします。
ジェスチャーが実行されると、関数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の結果がどのように構造にキャストされているかに注目してください。 CGEVENTは不透明なタイプであると想定されています。プログラムは、その構造がOSバージョンからOSバージョンに変更されるため、レイアウトを知っているか依存することになっていませんが、ここではeventSubType
とeventDirAmount
フィールドが可能になるように構造にキャストされています。直接割り当てられます。これらの2つの書き込みは、カタリナのヒープの腐敗を引き起こし、 CGEvent
を引き起こします。
値をイベントに保存する適切な方法は、cgeventsetintegervaluefield APIを使用することです。これにより、メモリ内の位置ではなく論理IDでcgeventsのフィールドを参照できます。では、WACOMドライバーが作成する必要がある2つの書き込みの同等のフィールドIDは何ですか?
CGEventSetIntegerValueField
の実装を含むMacos SierraのSkylight Frameworkを分解して、これらのフィールドにIDがどうあるべきかを確認しました。 eventSubType
Field ID 110で記述でき、 eventDirAmount
はID 115で記述できます。しかし、これらのフィールドIDはAppleのドキュメントでは見られないため、Wacomがそれらを使用できなかった理由を説明しています。
私はいくつかのグーグルを行い、これらのフィールドはAppleのプライベートAPIの一部であるため、これらのフィールドが文書化されていないことを発見しました。このWebKitヘッダーは彼らの名前を明らかにします:
kCGEventGestureHIDType = 110
kCGEventGestureSwipeValue = 115
kCGEventGesturePhase = 132
そして、これらのプライベートAPIフィールドは、シエラからビッグサルまで安定しています!これがわかったので、イベント構造への2つの割り当てをこれらの呼び出しに置き換えることができ、ドライバーのクラッシュは排除されます。
_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のApple Bug 8746551の犠牲者です。MacosCatalina以来、優先ペインは、窓の種類がアクティブなウィンドウになることを許可することにより、 NSApp->mainWindow
の動作を効果的に破壊します。 MacOSおよびStandAloneアプリ(以前のバージョンでは、実際のメイン設定ウィンドウのみがmainWindow
になります)。
モーダルシートが開いていて、ユーザーが新しいシートを開きたい場合、最初に元のシートを閉じる必要があります。しかし、Appleのバグにより、Wacomのチェックが現在故障するシートが開いているかどうかを確認します。シートがmainWindow
に接続されているかどうかを確認すると、その代わりに現在のシートに接続されたシートをチェックすることになります。 mainWindow
になります。これにより、クラッシュがトリガーされます(ペンマッピング設定など)。
mainWindow
へのアクセスにパッチを適用して、最初の値が後でキャッシュされるようにしたため、初期値が賢明である限り、 mainWindow
が最初に開封されたシートを指すように更新されてから壊れません( PenTablet.prefpane.newcode.asm
を参照してくださいPenTablet.prefpane.newcode.asm
)。
Intuos 3とCintiqドライバーには、アイテムがクリックされるとすぐにクラッシュする原因となる優先ペインにバグがあります。
Preference PaneのUIの主な機能の1つは、構成できるタブレット、ツール、アプリケーションを表すアイコンのリストです。そのアイコンリストコントロールは、このような関数を使用して、イベント(クリックなど)を子供に派遣します。
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()
関数が必要であることです。これは役に立たずに()とリリース()を保持します。しかし、呼び出されるハンドラー関数の1つはOEventDispatcher_Professional::listClickAction()
であり、その関数はvoid
関数です(明確に定義された返品値はありません)!
したがって、 action:()
最終的には、segfaultを引き起こすゴミポインターで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()
設定の読み込みをきれいにスキップします。これにより、設定はデフォルトにとどまり、ユーザーが設定ペインを使用して設定を編集する場合、設定はきれいに上書きする必要があります。
グラファイヤドライバーのインストーラーは、Catalinaがサポートしていない古い形式なので、完全に再構築する必要がありました。
Graphireの好みは、Catalinaには存在しなくなったMacOS標準ライブラリのプライベートシンボルに誤って依存していたため、開始できなくなりました。
たとえば、WacomのNSNIBWakingOverRide :: AwakeFromNib()関数はGUI脱介入中に呼び出され、ロードされたGUIコントロールをマップに追加して、後でタグでアクセスできるようにします。
void NSNibWakingOverride::awakeFromNib (NSControl * this ) {
OMasterDictionaryPtr-> addObject :withTag:( this , this -> _tag ));
}
しかし、これは私的な分野であるNSCONTROL._TAGの読み取りに依存しています。 nscontrolがこのように定義されたために機能したMacos 10.9で
@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のopopupoutlineview :: reloaddata()関数では、private nstableview._datasourceフィールドが誤って直接読み取られます。
void OPopupOutlineView::reloadData (OPopupOutlineView * this ) {
this -> _dataSource . willReloadDataForOutlineView ( this );
...
}
それで、私はこれにパッチを当て、代わりにパブリックアクセサを使用しました。
void OPopupOutlineView::reloadData (OPopupOutlineView * this ) {
this -> dataSource ()-> willReloadDataForOutlineView ( this );
...
}
これらのドライバーは、グラファイヤ3および4ドライバーと同じ問題を抱えており、さらに同じ修正を使用して、 ORadialSubMenuTableView::reloadData() method
で同じ_dataSource
問題を抱えています。