Gutsy Gibbonで一部ホットキーが機能しない問題を何とかする
Ubuntu 7.10 (Gutsy Gibbon)がリリースされて喜び勇んでアップデートしてしまったのだが、ThinkPadなど一部のノートPCではFn+F7を使ったディスプレイ切り替えや無線LAN切り替えができないという問題がある。これではプレゼンテーションや飛行機内での使用に差し支える。
ググるといっぱいヒットする。
よくよく調べるとThinkPad以外でも同様の現象があり、まだ修正方法は見つかっていないようだ。現象を端的に言うのは結構難しい。
まず、acpi_listenコマンドを使ってFn+F5、Fn+F7を押下してもibm/hotkey HKEYイベントが観測できる場合とそうでない場合がある。イベントが検出できない場合には、acpid経由で/etc/acpi以下のスクリプトも実行されない、だから切り替えられない。
もう少し調べてみる。/proc/acpi/ibm/hotkeyをcatとしてみると、
$ cat /proc/acpi/ibm/hotkey status: enabled mask: 0xffff7f commands: enable, disable, reset,
とか表示されるが、このmask値が0xffffffならFn+F5やFn+F7を拾えるのだが、このmask値が0xffffff以外に設定されてしまう場合があるようだ。
ではそのmask値は誰が設定しているかというと、/etc/init.d/hotkey-setupで設定している。このスクリプトの中では、/etc/X11/xorg.confの中から正規表現を使ってディスプレイドライバ名を切り出しているのだが、不完全である。例えば、「Driver "ati"」が2回現れる/etc/X11/xorg.confに対して「ati ati」という文字列をディスプレイドライバ名として認識してしまい、そんなドライバは存在しないので、Fn+F7を拾えないようなmask値を/proc/acpi/ibm/hotkeyに設定してしまう。
したがって、/etc/X11/xorg.confをしかるべく書き直すか、/etc/init.d/hotkey-setupを書き直す必要がある。
もう一つは、/etc/acpi/events/ibm-videobtnを見れば分かるとおり、acpidがイベントを拾えたとしても/bin/trueしか実行されないようになっていることである。/bin/trueの代わりに切り替え用のスクリプトを実行する必要がある。
で、確かFeistyでも/bin/trueになっていた。どうやって切り替えを実現していたのかは分からないけど。
そのうちアップデートが出るだろうが、とりあえずの対策を考えてみた。
無線LANの切り替え (Fn+F5)
/etc/acpi/events/ibm-wirelessを見るとFn+F5を押したときには、/etc/acpi/ibm-wireless.shが実行されることが分かる。このスクリプトを使ってトグルでオン・オフできる。
sudo /etc/acpi/ibm-wireless.sh
ディスプレイの切り替え (Fn+F7)
前準備として/etc/X11/xorg.confを適当に設定しておく。例えば以下の操作を行っておく。
- VGA/DVIケーブルを繋がない状態でマシンを起動し、gdmからログインする。
- VGA/DVIケーブルを繋ぐ。繋ぐディスプレイはそこそこ解像度があれば何でもいい。
- GNOMEのメニューから「システム>システム管理>モニタとグラフィックスカード」を起動する。
- 「ディスプレイ2」を選択し、「Plug 'n' Play」「1280x1024」「60Hz」あたりを選び、「無効にする」状態のまま「OK」する。
- 「All users must log off for ...」というメッセージが出るので、VGAケーブルを抜いてから、「システム>終了」からログアウトし、再度ログインする。
Fn+F5の場合と同様に/etc/acpi/events/ibm-videobtnを見ると/bin/trueを実行することが分かる。要はプレースホルダとして用意されているだけで、仮にacpidがFn+F7押下を検出したとしても実際にはディスプレイ切り替えは行われない設定になっている。
ではどうするかというと、/proc/acpi/ibm/videoを叩く方法と、xrandrコマンドを使う方法がある。ここでは後者を紹介する。
次に下のスクリプトをダウンロードして、chmod +xする。
必要に応じて接続するディスプレイの解像度をEXT_RESOLUTIONに設定しておく。デフォルトでSXGAに設定してある。大抵の液晶モニタ・プロジェクタは対応しているだろうから変更は必要ないと思われる。あとはスクリプトを使っていつでも切り替えられる。
内蔵のLCDのみで表示する場合:
$ ./gutsy-display-switcher.sh 0
内蔵のLCDと外部ディスプレイで表示する場合:
$ ./gutsy-display-switcher.sh 1
外部ディスプレイのみで表示する場合:
$ ./gutsy-display-switcher.sh 2
こんな感じ。
Comments and Trackbacks