如何为“监视器插入”创建回调在英特尔显卡上?

发布于 2024-10-27 18:48:50 字数 55 浏览 1 评论 0原文

我有一个带有英特尔显卡的 eeepc。我想将脚本与通过 VGA 插入显示器的事件挂钩。怎么做呢?

I've got an eeepc with an intel graphics. I'd like to hook a script to the event of a monitor plugged via VGA. How to do that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

烟花易冷人易散 2024-11-03 18:48:50

作为一个粗略的解决方案,您可以对 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"

<连接显示器后,code>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",我仍然在启动时收到一些事件,因此您可能需要在脚本中以某种方式考虑到这一点。

As a crude solution, you may be able to poll on sysfs. On my laptop I have:

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

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

I'm guessing this requires kernel DRM and possibly KMS.

To see if you can trigger something automatically, you could run udevadm monitor --property, and watch while you are (dis-)connecting the monitor to see if events are reported.

With my radeon, I get an event the first time I connect a VGA monitor, but no events on subsequent disconnects and reconnects. The event should look something like (using yours as an example):

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

Unfortunately there's not a lot to match against, but as long as there's only one video card in the picture that's not too important. Find where udev gets rules from on your system (probably /etc/udev/rules.d/), and create a 99-monitor-hotplug.rules file with:

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

udev will then run hotplug.sh when a display is connected. As a test, I put the following in /root/hotplug.sh (don't forget to make this script executable):

#!/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

With that, I got an entry in hotplug.log after I connected an external display. Even filtering for ACTION=="change", I still got some events on boot, so you may want to take that into account somehow in your script.

远山浅 2024-11-03 18:48:50

另一个答案位于正确的路径上:您想要监听来自udev的DRM事件。

我实现了一个 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()

另请参阅:

This other answer is on the right path: you want to listen to DRM events from udev.

I've implemented a Python script that runs some code when either USB devices or external displays are (un)plugged. I'm including below a minimal version of that script (untested):

#!/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()

See also:

恍梦境° 2024-11-03 18:48:50

谢谢塞巴斯蒂安瓦格纳!

有了这些信息,我就能够在电视关闭的情况下成功启动我的 Kodi 媒体中心。
事实上,当电视关闭时,英特尔驱动程序不想设置模式,当我后来打开电视电源时,我得到了空白屏幕。

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 似乎工作得很好。

Thanks sebastianwagner!

With this information, I've been able to successfully boot my Kodi media center with the TV turned off.
Indeed, when the TV is off, the Intel driver doesn't want to set up a mode and I got a blank screen when I later powered on the TV.

The Kodi log showed the following line:

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

So I created the following line in /etc/udev/rules.d/99-monitor-hotplug.rules :

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

Content of /usr/sbin/hotplugtv.sh (my X server is running as 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

Don't forget to reload udev rules when you make any change to your script (this was driving me crazy!):

udevadm control --reload-rules

Be careful to disable any screen saver in Kodi because they stay activated forever when you finally power up the TV.
On the other hand energy saving / DPMS seems to work fine.

浅唱々樱花落 2024-11-03 18:48:50

您有三个选项:

  1. 轮询 sysfs 中的特定条目。
  2. 使用 inotify 检测 sysfs 中的变化。
  3. 将 netlink 套接字与 NETLINK_KOBJECT_UEVENT 结合使用,并侦听所需设备的 change uevent。

在提到的任何一种方式中,您仍然需要以某种方式进行轮询,所以我只选择第一个选项。

You have three options:

  1. Poll on a specific entry in sysfs.
  2. Use inotify to detect changes in sysfs.
  3. Use a netlink socket with NETLINK_KOBJECT_UEVENT and listen for a change uevent for the device you want.

In any of the ways mentioned, you're still going to have to poll in one way or another, so I'd just go with the first option.

泅人 2024-11-03 18:48:50

假设您正在运行 X,脚本可以解析 xrandr 的输出以查看连接了哪些监视器。这应该适用于任何显卡。您可能会使用该工具来利用脚本中的更改。

它不能解决自动运行脚本的通知问题。虽然我没有很好的通用解决方案,但常见的情况是检测何时存在外部显示器,因为笔记本电脑已连接到扩展坞。在这种情况下,您可以让脚本由连接到扩展坞时触发的其他内容触发,例如添加或删除 USB 键盘或以太网。

Assuming you're running X, a script can parse the output of xrandr to see what monitors are connected. This should work with any graphics card. This is the same tool you'll probably use to make use of the change in your script.

It doesn't solve the issue with notifications to automatically run a script. While I don't have a great generic solution, a common case is detecting when an external monitor is present because a laptop is connected to a docking station. In this case, you can have your script trigger off of something else that triggers when connecting to the docking station such as the addition or removal of a USB keyboard or ethernet.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文