ノートパソコンのDisplayPortに外部モニターをプラグインまたはプラグアウトしたときにトリガーされるanyイベントはありますか? ACPIDとUDEVはまったく反応しません。
Intelチップでオンボードグラフィックスを使用しています。 ここ は、すでに数年前の同様の議論です。
ポーリングを使用したくありませんが、ディスプレイが接続されているかどうかに応じて、ディスプレイ設定を自動的に設定するいくつかの構成が必要です。
注:これは、i915駆動グラフィックカードを搭載したラップトップでテストされました。
注:新しい画面が接続されると、イベントがホストに送信されず、これは最後の編集後もtrueのままでした。したがって、唯一の方法はポーリングを使用することです。それらを可能な限り効率的にしようとしています...
最後に、(ACPIを介して)1つのより良いソリューションがあります。
まだイベントはありませんが、ACPIはxrandr
よりも問い合わせに効率的です。 (注意:これはACPIカーネルモジュールをロードする必要がありますが、root権限は必要ありません)。
私の最終的な解決策(bashを使用):
isVgaConnected() {
local crtState
read -a < /proc/acpi/video/VID/CRT0/state crtState
test $(( ( ${crtState[1]} >>4 ) ${1:+*-1+1} )) -ne 0
}
今テスト:
$ if isVgaConnected; then echo yes; else echo no; fi
yes
差し込まれているので、今は外します。
$ if isVgaConnected; then echo yes; else echo no; fi
no
注:${1:+*-1+1}
permit boolean argument:If something is現在、答えは逆になります:( crtState >> 4 ) * -1 + 1
。
そして最後のスクリプト:
#!/bin/bash
export crtProcEntry=/proc/acpi/video/VID/CRT0/state
isVgaConnected() {
local crtState
read -a < $crtProcEntry crtState
test $(( ( ${crtState[1]} >>4 ) ${1:+*-1+1} )) -ne 0
}
delay=.1
unset switch
isVgaConnected || switch=not
while :;do
while isVgaConnected $switch;do
sleep $delay
done
if [ "$switch" ];then
unset switch
echo VGA IS connected
# doing something while VGA is connected
else
switch=not
echo VGA is NOT connected.
# doing something else, maybe.
fi
done
警告:xrandr
よりも軽いが、重要ではない0.02秒、Bashスクリプトはリソースイータープロセス(top
)の先頭に移動します!
これには約0.001秒かかりますが、
$ time read -a </proc/stat crtStat
これには〜0.030秒必要です:
$ read -a < /proc/acpi/video/VID/CRT0/state crtState
これは大きいです!したがって、必要に応じて、delay
は0.5
と2
の間で合理的に設定できます。
これを使って、ようやく何かを見つけました:
重要な免責事項:/proc
および/sys
エントリを使用すると、システムが壊れる可能性があります!!!したがって、本番システムでは以下を試さないでください。
mapfile watchFileList < <(
find /sys /proc -type f 2>/dev/null |
grep -i acpi\\\|i91
)
Prompt=("/" "|" '\' '-');
l=0
while :; do
mapfile watchStat < <(
grep -H . ${watchFileList[@]} 2>/dev/null
)
for ((i=0;i<=${#watchStat[@]};i++)); do
[ "${watchStat[i]}" == "${oldStat[i]}" ] || echo ${watchStat[i]}
done
oldStat=("${watchStat[@]}")
sleep .5
printf "\r%s\r" ${Prompt[l++]}
[ $l -eq 4 ]&&l=0
done
...不要なエントリをいくつか削除した後:
for ((i=0;i<=${#watchFileList[@]};i++)); do
[[ "${watchFileList[$i]}" =~ /sys/firmware/acpi/interrupts/sci ]] &&
unset watchFileList[$i] && echo $i
done
私はこれを読むことができました:
/proc/acpi/video/VID/CRT0/state:state: 0x1d
/proc/acpi/video/VID/CRT0/state:state: 0x0d
/proc/acpi/video/VID/CRT0/state:state: 0x1d
モニターケーブルを接続、取り外し、再接続したとき。
設定が照会されると(system/preferences/monitor
またはxrandr
を実行)、グラフィックカードは scan のタイプを実行するため、xrandr -q
を実行すると、情報ですが、ステータスをポーリングする必要があります。
私はすべてのログ(カーネル、デーモン、Xなど)をスキャンして/proc
&/sys
を検索しましたが、リクエストを満たすものが何も存在しないようです。
私もこれを試しました:
export spc50="$(printf "%50s" "")"
watch -n1 '
find /proc/acpi/video -type f |
xargs grep -H . |
sed "s/^\([^:]*):/\1'$spc50'}:/;
s/^\(.\{50\}\) *:/\1 /"'
結局、新しい画面が接続されていない、または接続されていないときにSystem/Preferences/Monitor
を実行すると、ツールは(通常は)単純に表示されます。ただし、以前に画面を接続または切断したことがある場合は、このツールを実行すると、デスクトップが reset またはのタイプを作成することがわかります更新(xrandr
を実行した場合も同じ)。
これは、このツールが実行時に開始して定期的にステータスをポーリングすることにより、このツールがxrandr
を要求する(または同じように機能する)ことを確認しているようです。
あなたは自分で試すことができます:
$ for ((i=10;i--;)); do xrandr -q | grep ' connected' | wc -l; sleep 1; done
1
1
1
2
2
2
1
1
1
1
これにより、接続されている画面(ディスプレイ)の数が10秒間表示されます。
これが実行されている間、画面/モニターを接続または取り外して、何が起こっているかを確認します。したがって、小さなBashテスト関数を作成できます。
isVgaConnected() {
local xRandr=$(xrandr -q)
[ "$xRandr" == "${xRandr#*VGA1 con}" ] || return 0
return 1
}
これは次のように使用できます。
$ if isVgaConnected; then echo yes; fi
ただし、xrandr
には約0.140秒から0.200秒かかりますが、プラグおよび0.700秒直前に何かが接続または取り外しされたとき(注:リソースではないようです食べる人)。
私が何か間違ったことを教えていないことを確認するために、私はWebとドキュメントを検索しましたが、 DBusとScreens については何も見つかりませんでした。
最後に、2つの異なるウィンドウdbus-monitor --system
(私もオプションで遊んでいます)で実行し、記述した小さなスクリプトを実行しました。
$ for ((i=1000;i--;)); do isVgaConnected && echo yes || echo no; sleep .5; done
...何度も何度も、プラグを抜いて、モニターを抜いた。だから今私は言うことができます:
xrandr -q
を実行して、モニターが接続されているかどうか。しかし、他の方法がないように見えるので、注意してください。たとえば、xrandr
はこの情報を共有しているようです。そのため、GNOMEデスクトップはxinerama
に自動的に切り替わります...実行したときにxrandr
。
次の行がudevadm monitor
KERNEL[46578.184280] change /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
UDEV [46578.195887] change /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
モニターをVGAコネクタに接続する場合。したがって、これを理解する方法があるかもしれません。
srandrd の使用にこだわりました。 Xイベントを監視し、ディスプレイが接続または切断されたときにスクリプトをトリガーします。
何らかの理由でhotplugルートを使用したくない場合は、inotifywaitを使用してスクリプト内でポーリングしないことも可能です。
#!/ bin/bash SCREEN_LEFT = DP2 SCREEN_RIGHT = eDP1 START_DELAY = 5 renice +19 $$>/dev/null sleep $ START_DELAY OLD_DUAL = "dummy" while [ 1]; do DUAL = $(cat /sys/class/drm/card0-DP-2/status) if ["$ OLD_DUAL"!= "$ DUAL"];次に if ["$ DUAL" == "connected"]; then echo 'デュアルモニターのセットアップ' xrandr --output $ SCREEN_LEFT --auto --rotate normal --pos 0x0 --output $ SCREEN_RIGHT --auto --rotate normal --below $ SCREEN_LEFT else echo 'シングルモニターセットアップ' xrandr --auto fi OLD_DUAL = "$ DUAL" fi inotifywait -q -e close/sys/class/drm/card0-DP-2/status>/dev/null done
末尾の&を忘れないで、.xsessionrcから呼び出すのが最適です。 xrandrでポーリングすると、私の真新しいラップトップで深刻なユーザビリティの問題が発生しました(マウスは定期的に停止します)。
明らかに何かがあるはずです! :)/sysファイルシステムは、利用可能なハードウェアをユーザー空間に通知するため、ユーザー空間ツール(udevやmdevなど)は、現在利用可能なハードウェアを表すデバイスノードを「/ dev」ディレクトリに動的に入力できます。 Linuxには、/ sbin/hotplugとnetlinkの2つのホットプラグインターフェイスが用意されています。
次のファイルに小さなCデモがあります。 http://www.kernel.org/doc/pending/hotplug.txt
今日のLinuxのシステム/アプリケーションソフトウェアのほとんどは、相互に通信するためにいくつかのipcテクニックを使用しています。 D-Busは現在GNOMEアプリケーションで主に使用されており、役立つ可能性があります。
D-BUSは、システムを介したイベントまたは信号の送信を容易にし、システム内のさまざまなコンポーネントが通信し、最終的にはより適切に統合できるようにします。たとえば、Bluetoothデーモンは、音楽プレーヤーが傍受できる着信信号を送信し、通話が終了するまで音量をミュートできます。
wiki:
D-Busは、システムデーモン(「新しいハードウェアデバイスの追加」や「プリンターキューの変更」などのイベント用)とユーザーごとのログインセッションデーモン(ユーザーアプリケーション間の一般的なプロセス間通信のニーズ用)の両方を提供します
Pythonこのためのライブラリもあり、ubuntuは最近、「 zeitgeist 」と呼ばれるこの機能を使用しました。