Bluetooth Apple Magic Keyboard用Fnキー(2015)

Bluetooth Apple Magic Keyboard用Fnキー(2015)

使用に問題があります。アップルマジックキーボード(リチウムイオンバッテリーを搭載したBluetoothワイヤレス、充電およびテザリングを使用するためのLightningポート)Fedora 25を含む(カーネル:)4.8.15-300.fc25.x86_64

問題は、ワイヤレスモードで使用しているときにFnキーが登録されていないようです。私はそれを試しましたが、xevキー自体はイベントを発生させず、他のキーと一緒にキーを押すと他のキーだけを押すのとは異なりイベントは発生しません。そのキーを使用したいのは、Fn+ Fn/を別々にマッピングし、基本的にファンクションキーに設定されているマルチメディアキーも使用したいからです。HomeEnd

興味深いことに、ライトニングケーブルを使用してコンピュータに接続すると、キーボードは通常のApple有線キーボードのように動作します。これは、Bluetoothラジオを使用せずにOriginal AppleにUSBハードウェア/ドライバ(おそらく登録経由)を使用するためであると仮定します。アルミキーボードのUSBデバイスIDが異なりますが、これは確認されていません。)これにより、ファンクションキーだけでなく、インターネットで見つけることができるプライマリファンクションキーやマルチメディアキーなどのすべての機能を使用できます。

ただ、Bluetoothキーボードで使っても同じ機能が出てほしいです。可能であればカーネルをパッチします。しかし、どこで始めるのか、どうやってテストしてデバッグするのかわかりません(明らかにあまり「侵入的」な方法を最初に試してみたい)。

この問題を解決する方法のアイデアを歓迎します。

修正する

を読むときに/dev/hidraw0キーを押すと何らかのアクティビティが発生するため、Fnこれはfnシステムに登録されているが途中で失われたことを意味します。

アップデート2

evtestこのキーを押すとイベントは表示されずFn/dev/input/event4Magic Keyboardのイベントデバイス)、イベントは発生しません(他のキーは実行されます)。したがって、問題は、Fnシステムがキー(/dev/hidraw0データ表示を介して暗黙的に)を読み取ったが渡されないことです/dev/input/event4。しかし、Linuxでユーザー入力データストリームがどのように機能するのかわからないので、これは単なる推測です。

アップデート3

fn以下は、キーを数回押した結果です(押す+離す)。

> sudo cat /dev/hidraw2 | hexdump
0000000 0001 0000 0000 0000 0000 0001 0000 0000
0000010 0000 0200 0001 0000 0000 0000 0000 0001
0000020 0000 0000 0000 0200 0001 0000 0000 0000
0000030 0000 0001 0000 0000 0000 0200 0001 0000
0000040 0000 0000 0000 0001 0000 0000 0000 0200
0000050 0001 0000 0000 0000 0000 0001 0000 0000
0000060 0000 0200 0001 0000 0000 0000 0000 0001
0000070 0000 0000 0000 0200 0001 0000 0000 0000
0000080 0000 0001 0000 0000 0000 0200 0001 0000
0000090 0000 0000 0000 0001 0000 0000 0000 0200
00000a0 0001 0000 0000 0000 0000 0001 0000 0000
00000b0 0000 0200 0001 0000 0000 0000 0000 0001
00000c0 0000 0000 0000 0200 0001 0000 0000 0000
00000d0 0000 0001 0000 0000 0000 0200 0001 0000
00000e0 0000 0000 0000 0001 0000 0000 0000 0200
00000f0 0001 0000 0000 0000 0000 0001 0000 0000
0000100 0000 0200 0001 0000 0000 0000 0000 0001
0000110 0000 0000 0000 0200 0001 0000 0000 0000
0000120 0000 0001 0000 0000 0000 0200 0001 0000
0000130 0000 0000 0000 0001 0000 0000 0000 0200
0000140 0001 0000 0000 0000 0000 0001 0000 0000
0000150 0000 0200 0001 0000 0000 0000 0000 0001
0000160 0000 0000 0000 0200 0001 0000 0000 0000
0000170 0000 0001 0000 0000 0000 0200 0001 0000
0000180 0000 0000 0000 0001 0000 0000 0000 0200
0000190 0001 0000 0000 0000 0000 0001 0000 0000
00001a0 0000 0200 0001 0000 0000 0000 0000 0001
00001b0 0000 0000 0000 0200 0001 0000 0000 0000
00001c0 0000 0001 0000 0000 0000 0200 0001 0000
00001d0 0000 0000 0000 0001 0000 0000 0000 0200
00001e0 0001 0000 0000 0000 0000 0001 0000 0000
00001f0 0000 0200 0001 0000 0000 0000 0000 0001
0000200 0000 0000 0000 0200 0001 0000 0000 0000
0000210 0000 0001 0000 0000 0000 0200 0001 0000
0000220 0000 0000 0000 0001 0000 0000 0000 0200
0000230 0001 0000 0000 0000 0000 0001 0000 0000

奇妙な点は、発売後、たまに2行が出力されることもあるが、ほとんど1行が出力されるという点だfn

F2Fn+それぞれ次のようになりますF2

sudo cat /dev/hidraw2 | hexdump
0000000 0001 0000 0000 0000 0000 0001 3b00 0000
^[OQ0000010 0000 0000 0001 0000 0000 0000 0000 0001
^[OQ0000020 3b00 0000 0000 0000 0001 0000 0000 0000
^[OQ0000030 0000 0001 3b00 0000 0000 0000 0001 0000
0000040 0000 0000 0000 0001 3b00 0000 0000 0000
^[OQ0000050 0001 0000 0000 0000 0000 0001 3b00 0000
^[OQ0000060 0000 0000 0001 0000 0000 0000 0000 0001
^[OQ0000070 3b00 0000 0000 0000 0001 0000 0000 0000
0000080 0000 0101 0000 0000 0000 0000 0101 0600
^C

Fn+ F2:

> sudo cat /dev/hidraw2 | hexdump
0000000 0001 0000 0000 0000 0000 0001 0000 0000
^[OQ0000010 0000 0200 0001 3b00 0000 0000 0200 0001
0000020 0000 0000 0000 0200 0001 3b00 0000 0000
^[OQ0000030 0200 0001 0000 0000 0000 0200 0001 3b00
^[OQ0000040 0000 0000 0200 0001 0000 0000 0000 0200
^[OQ0000050 0001 3b00 0000 0000 0200 0001 0000 0000
^[OQ0000060 0000 0200 0001 3b00 0000 0000 0200 0001
0000070 0000 0000 0000 0200 0001 3b00 0000 0000
^[OQ0000080 0200 0001 0000 0000 0000 0200 0001 3b00
^[OQ0000090 0000 0000 0200 0001 0000 0000 0000 0200
^[OQ00000a0 0001 3b00 0000 0000 0200 0001 0000 0000
00000b0 0000 0200 0001 0000 0000 0000 0000 0101
00000c0 0000 0000 0000 0000 0101 0600 0000 0000
^C

アップデート4

@dirktの要求に応じて、レポート記述子情報は次のようになります(コメントの説明に従って行を実行できないため、ここに完全なダンプがあります。hidraw2キーボードを変更する必要があることにも注意してください)。

> sudo ./hid-desc /dev/hidraw2
Report Descriptor Size: 171
Report Descriptor:
05 01 09 06 a1 01 85 01 05 07 15 00 25 01 19 e0 29 e7 75 01 95 08 81 02 95 05 75 01 05 08 19 01 29 05 91 02 95 01 75 03 91 03 95 08 75 01 15 00 25 01 06 00 ff 09 03 81 03 95 06 75 08 15 00 25 65 05 07 19 00 29 65 81 00 95 01 75 01 15 00 25 01 05 0c 09 b8 81 02 95 01 75 01 06 00 ff 09 03 81 02 95 01 75 06 81 03 06 02 ff 09 55 85 55 15 00 26 ff 00 75 08 95 40 b1 a2 c0 06 00 ff 09 14 a1 01 85 90 05 84 75 01 95 03 15 00 25 01 09 61 05 85 09 44 09 46 81 02 95 05 81 01 75 08 95 01 15 00 26 ff 00 09 65 81 02 c0 00 

Raw Name: Magic Keyboard
Raw Phys: 00:c2:c6:f7:eb:57
Raw Info:
    bustype: 5 (Bluetooth)
    vendor: 0x004c
    product: 0x0267

答え1

上記のヒントの助けを借りて、Apple Magic KeyboardをBluetoothに接続するときにFnキーが機能するようにするパッチを作成できました。

問題のいくつかは、Magic KeyboardがベンダーID 0x004c(AppleのBluetoothベンダーID)を表示しているのに対し、hid-appleは0x05ac(Apple USBベンダーID)のみを見つけるため、hid-appleの代わりにhid-genericモジュールが使用されることです。です。 。

2番目の問題は、元のapple_input_mappinggitログのコードで発生しました。hidinput_configure_usage

パッチはここに掲載されています:https://bugzilla.kernel.org/show_bug.cgi?id=99881#c41

答え2

部分的な答え: HIDインフラストラクチャとHID生データの理解

(免責事項:USBに対してのみこれをすべて行ったが、Bluetoothにも同じまたは同様の方法で適用されると仮定します。)

HIDデバイスは、明確に定義された形式でレポートを送受信できます。特定のデバイスの形式は次のとおりです。HID記述子、USBの場合は、他のUSB記述子と非常によく似ています(lsusbバインドされていない場合はリストできます)。詳細(USB)は以下で確認できます。HID (Human Interface Device) のデバイスクラスの定義 PDF文書

HIDのカーネル文書を見つけることができますDocumentation/hid。説明したように、hiddev.txtイベントのデータフローは次のとおりです。

 usb.c --> hid-core.c --> hid-input.c --> input-subsystem

特に、drivers/hid/hid-input.cルーチン内では、レポートはhidinput_configure_usageHID記述子に基づいて解析されます。

Fnしたがって、鍵が見えない場合は、何か間違っています。

hidraw0異なるIDを持つ複数のレポートがあるかのように表示される出力は疑わしいようです(このレポートのIDは1、通常のキーボードレポートのIDは0です)。

ただし、これを保証するにはHID記述子が必要です。 HID記述子はデバイスのioctlを介して使用できますhidraw。たとえば、https://github.com/DIGImend/usbhid-dumpget descriptor(USBのみ)を使用してhttps://github.com/DIGImend/hidrd解析できます。/samples/hidraw/hid-example.cioctlでHID記述子を取得する方法を示すファイルもカーネルソースコードにあります。このファイルは簡単に変更して同様の16進ダンプを生成できますusbhid-dump。 Bluetoothで書く必要があります。ペーストビン。コンパイル用make

(外部プロジェクトのコンパイルに慣れていない場合:両方のファイルのzipファイルをダウンロードし、各ファイルの圧縮を空のディレクトリ(、、、)./bootstrapに解凍します。バイナリで直接作業して追加できます。)./configuremake$PATH

これで、以下を使用して記述子を解析できます。

sudo ./hid-desc /dev/hidraw0 | tail -n+3 | head -1 | hidrd-convert -ihex -ospec

この出力(または機能しない場合は16進ダンプ)を提供することに加えて、さまざまな他のキー(文字、矢印)を押して何が起こるかをテストしhidrawてくださいFn。また、キーを正常に押したときに何が起こるかをテストしてみてください。

カーネルに特別なレポートを認識させることができない場合は、進める最善の方法がわかりません。おそらく最も簡単な方法は、イベントを分析hidrawして追加の入力イベントを生成するCプログラムを書くことです。生成入力

修正する:HID記述子の00末尾に追加のコンテンツが含まれています。削除すると解決

Usage Page (Desktop),                           ; Generic desktop controls (01h)
Usage (Keyboard),                               ; Keyboard (06h, application collection)
Collection (Application),
    Report ID (1),                      ; +00 report id
    Usage Page (Keyboard),                      ; Keyboard/keypad (07h)
    Logical Minimum (0),
    Logical Maximum (1),
    Usage Minimum (KB Leftcontrol),             ; Keyboard left control (E0h, dynamic value)
    Usage Maximum (KB Right GUI),               ; Keyboard right GUI (E7h, dynamic value)
    Report Size (1),
    Report Count (8),
    Input (Variable),                   ; +01 modifier
    Report Count (5),
    Report Size (1),
    Usage Page (LED),                           ; LEDs (08h)
    Usage Minimum (01h),
    Usage Maximum (05h),
    Output (Variable),
    Report Count (1),
    Report Size (3),
    Output (Constant, Variable),
    Report Count (8),
    Report Size (1),
    Logical Minimum (0),
    Logical Maximum (1),
    Usage Page (FF00h),                         ; FF00h, vendor-defined
    Usage (03h),
    Input (Constant, Variable),         ; +02 vendor
    Report Count (6),
    Report Size (8),
    Logical Minimum (0),
    Logical Maximum (101),
    Usage Page (Keyboard),                      ; Keyboard/keypad (07h)
    Usage Minimum (None),                       ; No event (00h, selector)
    Usage Maximum (KB Application),             ; Keyboard Application (65h, selector)
    Input,                              ; +03 6 keysym bytes
    Report Count (1),
    Report Size (1),
    Logical Minimum (0),
    Logical Maximum (1),
    Usage Page (Consumer),                      ; Consumer (0Ch)
    Usage (Eject),                              ; Eject (B8h, one-shot control)
    Input (Variable),                   : +09.0
    Report Count (1),
    Report Size (1),
    Usage Page (FF00h),                         ; FF00h, vendor-defined
    Usage (03h),
    Input (Variable),                   ; +09.1
    Report Count (1),
    Report Size (6),
    Input (Constant, Variable),         : +09.2-7
    Usage Page (FF02h),                         ; FF02h, vendor-defined
    Usage (55h),
    Report ID (85),
    Logical Minimum (0),
    Logical Maximum (255),
    Report Size (8),
    Report Count (64),
    Feature (Variable, No Preferred, Volatile),
End Collection,
Usage Page (FF00h),                             ; FF00h, vendor-defined
Usage (14h),
Collection (Application),
    Report ID (144),
    Usage Page (Power Device),                  ; Power device (84h, power page)
    Report Size (1),
    Report Count (3),
    Logical Minimum (0),
    Logical Maximum (1),
    Usage (61h),
    Usage Page (Power Batsys),                  ; Power battery system (85h, power page)
    Usage (44h),
    Usage (46h),
    Input (Variable),
    Report Count (5),
    Input (Constant),
    Report Size (8),
    Report Count (1),
    Logical Minimum (0),
    Logical Maximum (255),
    Usage (65h),
    Input (Variable),
End Collection

01id hexの入力イベントレポート、id hexのバッテリステータスレポート90、通常どおりLEDを設定する出力、およびベンダー固有の機能制御があります。

入力イベントレポートのバイトを表示しました。ベンダーによって定義されたいくつかのフィールドがあります。私たちはそのフィールドが何をしているのかわからず、推測することしかできません。

入力イベントレポートは10バイトで構成され、例では次のようにデコードします。

ID MM VA K1 K2 K3 K4 K5 K6 VB

01 00 00 00 00 00 00 00 00 02  ; press? Fn 
01 00 00 00 00 00 00 00 00 00  ; release? Fn

01 00 00 3b 00 00 00 00 00 00  ; press F2
01 00 00 00 00 00 00 00 00 00  ; release

01 00 00 00 00 00 00 00 00 00  ;
01 00 00 00 00 00 00 00 00 02  ; press Fn?
01 00 00 3b 00 00 00 00 00 02  ; press F2
01 00 00 00 00 00 00 00 00 02  ; release F2 (but not Fn?)

IDただ報告してください。MM標準の8つの修飾子ビットを使用すると、キー用のスペースはありませんFn。最大6つのキーを同時に押すことができますK1。ベンダーによって異なります。前の例では、を押してを押してから離したと仮定すると、ビット1は修飾子(または少なくともそれに関連するもの)を表すようです。K6VAVBFnF2VBFn

hexdump -e '10/1 "%02X ""\n"'出力ラインごとに9バイトを取得し、Fn最終的に上書きしたいキーの組み合わせを含む、複数のキーの組み合わせでこの仮説をテストするために使用します。

修正する:完全性と今後の参考のために、もはやこの特定のケースとは関係がないと思います。 HIDイベントはUHIDを使用して注入できます。Documentation/hid/uhid.txtカーネルを参照してくださいsamples/uhid/uhid-example.c

関連情報