как я могу определить, когда монитор подключен или отключен?

<p>есть ли <em> какое-либо </em> событие, которое запускается, когда я подключаю или отключаю внешний монитор к displayport моего ноутбука? acpid и udev вообще не реагируют.</p><p>я использую встроенную графику на чипе intel. <a href="http://lists.x.org/archives/xorg/2007-july/026067.html">здесь</a> - похожая дискуссия, которой уже пару лет.</p><p>я не хочу использовать опрос, но мне нужно иметь некоторую конфигурацию, которая автоматически устанавливает параметры дисплея в зависимости от того, подключен ли дисплей.</p>

<p><strong> примечание: </strong> <em> это было проверено на ноутбуке с графической картой с приводом i915.</em></p><hr><h3>фон</h3><p><strong> примечание: </strong> когда подключен новый экран, хосту не отправляется событие, оно остается верным даже после моего последнего редактирования. таким образом, единственный способ - использовать опрос. пытаясь сделать их максимально эффективными ...</p><h3>правка № 3</h3><p>наконец, есть одно лучшее решение (через acpi):</p><p>пока еще нет событий, но acpi кажется более эффективным, чем <code>xrandr</code>, чтобы узнать. (примечание: для этого <strong> требуются </strong> загруженные модули ядра acpi, но не требуются права root).</p><p>мое окончательное решение (с использованием bash):</p><pre><code>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 </code></pre><p>он подключен, так что теперь я отключаю его:</p><pre><code>$ if isvgaconnected; then echo yes; else echo no; fi no <strong> примечание: </strong> ${1:+*-1+1}</code> разрешить аргумент <em> логическое значение</em>: если <em> что-то присутствует</em>, ответ будет инвертированным: <code>( crtstate >> 4 ) * -1 + 1</code>.</p><p>и последний сценарий:</p><pre><code>#!/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 <strong> предупреждения: </strong>  легче, чем xrandr, но не менее важно с задержкой меньше, чем  0.02 секунд сценарий bash перейдет к началу процесса пожирателей ресурсов (top)!пока это стоит ~ 0,001 сек:$ time read -a </proc/stat crtstat </code></pre><p>это требует ~ 0,030 сек:</p><pre><code>$ read -a < /proc/acpi/video/vid/crt0/state crtstate это большое! таким образом, в зависимости от того, что вам нужно, delay может быть разумно установлено между 0.5 а также 2.правка № 2я наконец-то нашел что-то, используя это:<strong> важный отказ от ответственности: </strong> игра с /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%sr" ${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 </code></pre><p>я был в состоянии прочитать это:</p><pre><code>/proc/acpi/video/vid/crt0/state:state: 0x1d /proc/acpi/video/vid/crt0/state:state: 0x0d /proc/acpi/video/vid/crt0/state:state: 0x1d </code></pre><p>когда я подключаю, отключаю и снова подключаю кабель монитора.</p><p>когда конфиг запрашивается (работает <code>system/preferences/monitor</code> или <code>xrandr</code>), видеокарты выполняют тип <em> сканирование</em>, поэтому выполняется <code>xrandr -q</code> дать вам информацию, но вы должны опросить статус.</p><p>я просмотрел все журналы (ядро, демон, x и т.д.), просматривая <code>/proc</code> & <code>/sys</code>, и явно не существует ничего, что могло бы удовлетворить вашу просьбу.</p><p>я тоже попробовал это:</p><pre><code>export spc50="$(printf "%50s" "")" watch -n1 ' find /proc/acpi/video -type f | xargs grep -h . | sed "s/^([^:]):/1'$spc50'}:/; s/^\(.\{50\}\) *:/\1 /"' </code></pre><p>после всего этого, если вы запустите <code>system/preferences/monitor</code> пока новый экран не был подключен или отключен, инструмент будет отображаться просто (обычно). но если вы ранее подключали или отключали экран, иногда вы запускаете этот инструмент, и вы видите, что ваш рабочий стол делает вид <em> сбросить</em> или <em> обновить</em> (то же самое, если вы запускаете <code>xrandr</code>).</p><p>кажется, это подтверждает, что этот инструмент запрашивает <code>xrandr</code> (или работает аналогичным образом), периодически опрашивая состояние, начиная с момента его запуска.</p><p>вы можете попробовать себя:</p><pre><code>$ 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 } </code></pre><p>который будет использоваться как в:</p><pre><code>$ if isvgaconnected; then echo yes; fi но будьте осторожны, xrandr занимает около <strong> от 0,140 с до 0,200 с </strong>, в то время как на вилках не происходит никаких изменений и до <strong> 0,700 с </strong> всякий раз, когда что-то было подключено или отключено непосредственно перед (<strong> примечание: </strong> кажется, это не пожиратель ресурсов).правка # 1чтобы убедиться, что я не преподаю что-то неправильное, я искал в интернете и документах, но ничего не нашел о  dbus and screens.наконец, я запустил в двух разных окнах dbus-monitor --system (я тоже играл с опциями) и небольшой сценарий, который я написал:$ for ((i=1000;i--;)); do isvgaconnected && echo yes || echo no; sleep .5; done </code></pre><p>... и снова подключил, чем отключил монитор, много раз. теперь я могу сказать:</p><ul> <li><em> в этой конфигурации <strong> с использованием драйвера i915 </strong> нет другого способа, кроме запуска <code>xrandr -q</code> чтобы узнать, подключен ли монитор или нет.</em></li> </ul><p>но будьте осторожны, потому что, похоже, других путей нет. например, <code>xrandr</code>, похоже, делится этой информацией, поэтому мой рабочий стол gnome переключился бы на <code>xinerama</code> автоматически ... <strong>, когда я запустил <code>xrandr</code> </strong>.</p><h3>некоторые документы</h3><ul> <li> <a href="https://wiki.archlinux.org/index.php/xrandr#toggle\_external\_monitor">скрипт для переключения внутреннего/внешнего дисплея для ноутбуков</a> </li> <li> <a href="http://www.x.org/docs/intel/hd/ihd\_os\_vol\_3\_part4\_bjs.pdf">справочное руководство программиста intel hd opensource</a> </li> </ul>

<p>следующие строки появились в <code>udevadm monitor</code></p><pre><code>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) </code></pre><p>при подключении монитора к vga-разъему. так что может быть способ выяснить это.</p>

<p>я придерживался использования <a href="https://github.com/jceb/srandrd">srandrd</a> . он отслеживает события x и запускает ваш сценарий, когда дисплей подключается или отключается.</p>

<p>для тех, кто по какой-либо причине не хочет идти по маршруту горячего подключения, все еще возможно не опрашивать в скрипте с использованием inotifywait:</p><pre> #!/bin/баш 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" == "подключен"]; затем 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 сделано </pre><p>лучше всего вызывать его из .xsessionrc, не забывая окончание &. опрос xrandr дал серьезные проблемы с юзабилити на моем новом ноутбуке (мышь периодически зависала).</p>

<p>очевидно, что-то должно быть! файловая система :)/sys сообщает пользовательскому пространству, какое оборудование доступно, поэтому инструменты пользовательского пространства (такие как udev или mdev) могут динамически заполнять каталог "/ dev" узлами устройства, представляющими доступное в настоящее время оборудование. linux предоставляет два интерфейса горячего подключения:/sbin/hotplug и netlink.</p><p>в следующем файле есть небольшая демонстрация c. <a href="http://www.kernel.org/doc/pending/hotplug.txt">http://www.kernel.org/doc/pending/hotplug.txt</a> </p>

<p>в основном системное/прикладное программное обеспечение в linux сегодня использует некоторые методы ipc для связи друг с другом. d-bus теперь в основном используется с приложениями gnome и может помочь.</p><p> <a href="http://www.linuxjournal.com/article/7744">linux journal:</a> </p><blockquote> <p>d-bus может облегчать отправку событий или сигналов через систему, позволяя различным компонентам системы обмениваться данными и, в конечном итоге, лучше интегрироваться. например, демон bluetooth может отправлять сигнал входящего вызова, который может перехватить ваш музыкальный проигрыватель, приглушая громкость до завершения вызова.</p> </blockquote><p>вики:</p><blockquote> <p>d-bus предоставляет как системный демон (для таких событий, как "добавленное новое аппаратное устройство" или "очередь принтера изменена"), так и демон для сеанса входа в систему для каждого пользователя (для общих потребностей межпроцессного взаимодействия между пользовательскими приложениями)</p> </blockquote><p>для этого есть даже библиотека python), и ubuntu недавно использовала эту способность, которая называется " <a href="http://wiki.zeitgeist-project.com/getting\_started">zeitgeist</a> ".</p>