Как создать обратный вызов для монитора, подключенного к графике Intel?

У меня есть eeepc с графикой Intel. Я хотел бы подключить скрипт к событию монитора, подключенного через VGA. Как это сделать?


person Reactormonk    schedule 29.03.2011    source источник
comment
Для тех, кто ищет решение для Windows: stackoverflow.com/questions/1440285/ stackoverflow.com/questions/3267722/ stackoverflow.com/questions/5981520/   -  person hippietrail    schedule 13.05.2011


Ответы (5)


В качестве грубого решения вы можете опросить sysfs. На моем ноутбуке у меня есть:

$ cat /sys/class/drm/card0-LVDS-1/status
connected

$ cat /sys/class/drm/card0-VGA-1/status
disconnected

Я предполагаю, что для этого требуется DRM ядра и, возможно, KMS.

Чтобы увидеть, можете ли вы запускать что-то автоматически, вы можете запустить udevadm monitor --property и посмотреть, пока вы (отключаете) подключение монитора, чтобы увидеть, сообщаются ли события.

С моим radeon я получаю событие при первом подключении монитора VGA, но никаких событий при последующих отключениях и повторных подключениях. Событие должно выглядеть примерно так (на примере вашего):

KERNEL[1303765357.560848] change /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
UDEV_LOG=0
ACTION=change
DEVPATH=/devices/pci0000:00/0000:00:02.0/drm/card0
SUBSYSTEM=drm
HOTPLUG=1
DEVNAME=dri/card0
DEVTYPE=drm_minor
SEQNUM=2943
MAJOR=226
MINOR=0

К сожалению, сравнивать особо нечего, но пока на картинке присутствует только одна видеокарта, это не так важно. Найдите, откуда udev получает правила в вашей системе (вероятно, /etc/udev/rules.d/), и создайте файл 99-monitor-hotplug.rules с:

ACTION=="change", SUBSYSTEM=="drm", ENV{HOTPLUG}=="1", RUN+="/root/hotplug.sh"

Затем udev запустит hotplug.sh при подключении дисплея. В качестве теста я поместил в /root/hotplug.sh следующее (не забудьте сделать этот скрипт исполняемым):

#!/bin/sh

for output in DVI-I-1 LVDS-1 VGA-1; do
        echo $output >> /root/hotplug.log
        cat /sys/class/drm/card0-$output/status >> /root/hotplug.log
done

При том, что у меня появилась запись в hotplug.log после того, как я подключил внешний дисплей. Даже фильтруя ACTION=="change", я все еще получаю некоторые события при загрузке, поэтому вы можете каким-то образом учесть это в своем скрипте.

person Andy    schedule 19.04.2011
comment
Хорошее начало, но я не люблю опросы. - person Reactormonk; 19.04.2011
comment
@Tass, если вы получаете события, пингуйте меня, и я, вероятно, смогу придумать правило udev для запуска скрипта. - person Andy; 21.04.2011
comment
Спасибо Энди за это! Я создал сценарий, вдохновленный этим постом. Вы можете загрузить его по адресу github.com/codingtony/udev-monitor-hotplug. использует xrandr для включения и выключения монитора, когда они подключены/отключены. Надеюсь, это поможет. - person Tony; 03.12.2012
comment
Я получаю событие при первом подключении монитора VGA, но никаких событий при последующих отключениях и повторных подключениях То же самое для меня, но, похоже, мой сценарий выполняется только в первый раз. Ваш пользовательский скрипт hotplug.sh вызывается каждый раз при отключении и повторном подключении монитора? - person user779159; 21.03.2013
comment
Я пытаюсь настроить это, чтобы учесть возможность запуска системы без подключенного монитора. Для меня udev показывает события как подключения, так и отключения, но только если монитор был подключен при загрузке системы. Есть идеи, как заставить его обращать внимание, если при запуске udev ничего не подключено? Прибегая к опросу, потребовался бы гораздо более запутанный сценарий... - person Perkins; 30.10.2014
comment
Откуда 99? - person Roymunson; 22.08.2020

Этот другой ответ находится на правильном пути: вы хотите прослушивать события DRM от udev.

Я реализовал скрипт Python, который запускает некоторый код, когда любое USB-устройство или внешние дисплеи (не)подключены. Ниже я привожу минимальную версию этого скрипта (непроверенную):

#!/usr/bin/env python3
import pyudev

def udev_event_received(device):
    ...  # Your code here!

context = pyudev.Context()
monitor_drm = pyudev.Monitor.from_netlink(context)
monitor_drm.filter_by(subsystem='drm')
observer_drm = pyudev.MonitorObserver(monitor_drm, callback=udev_event_received, daemon=False)

observer_drm.start()

# This will prevent the program from finishing:
observer_drm.join()

Смотрите также:

person Denilson Sá Maia    schedule 01.10.2018

У вас есть три варианта:

  1. Опрос определенной записи в sysfs.
  2. Используйте inotify для обнаружения изменений в sysfs.
  3. Используйте сокет netlink с NETLINK_KOBJECT_UEVENT и прослушайте change uevent для нужного вам устройства.

В любом из упомянутых способов вам все равно придется проводить опрос тем или иным образом, поэтому я бы выбрал первый вариант.

person jmkeyes    schedule 19.04.2011
comment
Сокеты inotify и netlink позволяют использовать select() и друзей. Вы действительно считаете это опросом? - person Brian Cain; 30.11.2012
comment
Прелесть использования select() или poll() для опроса обновлений заключается в том, что вы засыпаете до тех пор, пока либо не истечет время ожидания, либо ядро ​​не разбудит вас, чтобы сообщить вам, что произошло одно из событий, которые вы опрашиваете (что-то вроде вводящего в заблуждение). Это не то же самое, что большинство людей называют опросом, это даже интерфейс для прерываний GPIO... интерфейсы select() или poll(). - person Svartalf; 23.02.2015
comment
inotify не работает с изменениями sysfs, так как это не настоящая файловая система как таковая. Попробуйте, если не верите мне. sudo inotifywait -e modify -m --format '%:e %f' /sys/class/drm/something, поэтому ваш второй вариант недействителен. - person nicholas.alipaz; 11.03.2015
comment
"Нет, inotify не работает с sysfs, а если и работает, то случайно, и любые данные, которые вы получаете для этого, вероятно, совершенно неверны". Грег К.Х., 29 марта 2014 г. - person Denilson Sá Maia; 13.02.2016
comment
@ DenilsonSáMaia Ваша ссылка сегодня не работает, или у меня нет к ней доступа... - person WinEunuuchs2Unix; 30.09.2018
comment
@WinEunuuchs2Unix: новая ссылка: spinics.net/lists/linux-fsdevel/msg73924. html - person Denilson Sá Maia; 01.10.2018
comment
@ DenilsonSáMaia Спасибо за ссылку. Я пока откажусь от inotifywait и вместо этого попробую dbus-monitor. - person WinEunuuchs2Unix; 02.10.2018
comment
@WinEunuuchs2Unix, если вы пропустили; вчера я также опубликовал ответ: stackoverflow.com/a/52595370 - person Denilson Sá Maia; 03.10.2018

Спасибо Себастьянвагнер!

С помощью этой информации я смог успешно загрузить свой медиацентр Kodi с выключенным телевизором. Действительно, когда телевизор выключен, драйвер Intel не хочет устанавливать режим, и при включении телевизора у меня появляется пустой экран.

Журнал Kodi показал следующую строку:

WARNING: CXRandR::Query - output HDMI1 has no current mode, assuming disconnected

Поэтому я создал следующую строку в /etc/udev/rules.d/99-monitor-hotplug.rules:

ACTION=="change", SUBSYSTEM=="drm", ENV{HOTPLUG}=="1", RUN+="/usr/sbin/hotplugtv.sh"

Содержимое /usr/sbin/hotplugtv.sh (мой X-сервер работает как root):

#!/bin/bash

export DISPLAY=:0
export XAUTHORITY=/root/.Xauthority

/bin/date 2>&1 >> /var/log/hotplugtv.log;
if [[ $(cat /sys/class/drm/card0-HDMI-A-1/status | grep -Ec "^connected") -eq 1 ]]; then
        echo "TV connected!" >> /var/log/hotplugtv.log;
        /bin/sleep 2s;
        /usr/bin/xrandr --verbose --output HDMI1 --auto 2>&1 >> /var/log/hotplugtv.log;
else
        echo "TV disconnected!" >> /var/log/hotplugtv.log;
fi

Не забудьте перезагрузить правила udev, когда будете вносить какие-либо изменения в свой скрипт (это сводило меня с ума!):

udevadm control --reload-rules

Будьте осторожны, чтобы отключить любые заставки в Kodi, потому что они остаются активированными навсегда, когда вы, наконец, включаете телевизор. С другой стороны, энергосбережение / DPMS работает нормально.

person Gurv    schedule 21.06.2015

Предполагая, что вы используете X, сценарий может проанализировать вывод xrandr, чтобы увидеть, какие мониторы подключены. Это должно работать с любой видеокартой. Это тот же инструмент, который вы, вероятно, будете использовать, чтобы использовать изменения в вашем скрипте.

Это не решает проблему с уведомлениями для автоматического запуска скрипта. Хотя у меня нет отличного универсального решения, распространенным случаем является обнаружение присутствия внешнего монитора, потому что ноутбук подключен к док-станции. В этом случае вы можете настроить запуск сценария на что-то другое, что срабатывает при подключении к док-станции, например, на добавление или удаление USB-клавиатуры или Ethernet.

person user2977712    schedule 11.11.2013