Как создать обратный вызов для «монитора подключен» на графике Intel? - PullRequest
25 голосов
/ 29 марта 2011

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

Ответы [ 5 ]

28 голосов
/ 19 апреля 2011

Как грубое решение, вы можете опросить 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" у меня все еще есть некоторые события при загрузке, так что вы можете как-то учесть это в своем скрипте.

4 голосов
/ 01 октября 2018

Этот другой ответ находится на правильном пути: вы хотите прослушивать события 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()

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

4 голосов
/ 19 апреля 2011

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

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

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

3 голосов
/ 21 июня 2015

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

Благодаря этой информации я смог успешно загрузить свой медиацентр 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 работает нормально.

2 голосов
/ 11 ноября 2013

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

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

...