it-swarm-eu.dev

Jak zjistím, zda je monitor zapojen nebo odpojen?

Existuje nějaká událost, která se spustí, když připojím nebo odpojím externí monitor do DisplayPort na svém notebooku? ACPID a UDEV vůbec nereagují.

Používám palubní grafiku na intel čipu. Zde je podobná diskuse, která je již několik let stará.

Nechci používat dotazování, ale musím mít nějakou konfiguraci, která nastaví nastavení displeje automaticky v závislosti na tom, zda je displej připojen.

54
janoliver

POZNÁMKA: Toto bylo testováno na notebooku s grafickou kartou řízenou i915.


Pozadí

POZNÁMKA: Když je připojena nová obrazovka, do hostitele není odeslána žádná událost, zůstane to pravda i po mé poslední úpravě. Jediným způsobem je tedy použít dotazování. Snažím se, aby byly co nejefektivnější ...

ÚPRAVA # 3

Nakonec existuje jedno lepší řešení (prostřednictvím ACPI):

Stále neexistuje žádná událost, ale ACPI se zdá být efektivnější než xrandr na dotaz. (Poznámka: Toto vyžaduje načtené moduly jádra ACPI, ale nevyžaduje oprávnění root.

Moje konečné řešení (pomocí bash):

isVgaConnected() {
    local crtState
    read -a < /proc/acpi/video/VID/CRT0/state crtState
    test $(( ( ${crtState[1]} >>4 ) ${1:+*-1+1} )) -ne 0
}

Nyní test:

$ if isVgaConnected; then echo yes; else echo no; fi 
yes

Je zapojen, takže ho nyní odpojím:

$ if isVgaConnected; then echo yes; else echo no; fi 
no

POZNÁMKA: ${1:+*-1+1} povolit argument boolean: Pokud něco je přítomno, odpověď by byla obrácena: ( crtState >> 4 ) * -1 + 1.

a závěrečný skript:

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

UPOZORNĚNÍ: lehčí než xrandr, ale ne nevýznamné se zpožděním menším než ,02 sekund, Bash skript půjde na začátek procesu jedlíci zdrojů (top)!

I když to stojí ~ 0,001 s:

$ time read -a </proc/stat crtStat

Vyžaduje to ~ 0,030 s:

$ read -a < /proc/acpi/video/VID/CRT0/state crtState

To je velké! Takže v závislosti na tom, co potřebujete, lze delay rozumně nastavit mezi 0.5 a 2.

ÚPRAVA # 2

Nakonec jsem něco našel:

Důležité vyloučení odpovědnosti: Hraní s /proc a /sys záznamy mohou poškodit váš systém !!! Takže na produkčních systémech nezkoušejte následující.

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

... po očištění nežádoucích záznamů:

for ((i=0;i<=${#watchFileList[@]};i++)); do
  [[ "${watchFileList[$i]}" =~ /sys/firmware/acpi/interrupts/sci ]] &&
      unset watchFileList[$i] && echo $i
done

To jsem dokázal přečíst:

/proc/acpi/video/VID/CRT0/state:state: 0x1d
/proc/acpi/video/VID/CRT0/state:state: 0x0d
/proc/acpi/video/VID/CRT0/state:state: 0x1d

Když připojím, odpojte a znovu zapojte kabel monitoru.

Při dotazu na konfiguraci (spuštění system/preferences/monitor nebo xrandr), grafické karty udělají typ scan, takže běží xrandr -q vám dá informace, ale musíte zjistit stav.

Prohledal jsem všechny protokoly (jádro, démona, X atd.) Prohledávajícím /proc & /sys a zjevně se zdá, že neexistuje nic, co by vyhovovalo vaší žádosti.

Zkusil jsem to také:

export spc50="$(printf "%50s" "")"
watch -n1  '
    find /proc/acpi/video -type f |
        xargs grep -H . |
        sed "s/^\([^:]*):/\1'$spc50'}:/;
             s/^\(.\{50\}\) *:/\1 /"'

Po tom všem, když spustíte System/Preferences/Monitor zatímco nebyla připojena žádná nová obrazovka ani odpojena, bude se nástroj zobrazovat jednoduše (normálně). Ale pokud jste již dříve připojili nebo odpojili obrazovku, občas spustíte tento nástroj a uvidíte, že na ploše vytvoříte typ reset ​​nebo obnovit ​​(stejný pokud spustíte xrandr).

Zdá se, že to potvrzuje, že tento nástroj požádá o xrandr (nebo pracuje stejným způsobem) pravidelným dotazováním na stav, počínaje okamžikem jeho spuštění.

Můžete vyzkoušet sami:

$ for ((i=10;i--;)); do xrandr -q | grep ' connected' | wc -l; sleep 1; done
1
1
1
2
2
2
1
1
1
1

Tím se na 10 sekund zobrazí počet připojených obrazovek (displejů).

Zatímco to běží, připojte a/nebo odpojte obrazovku/monitor a podívejte se, co se děje. Takže byste mohli vytvořit malou testovací funkci Bash:

isVgaConnected() {
    local xRandr=$(xrandr -q)
    [ "$xRandr" == "${xRandr#*VGA1 con}" ] || return 0
    return 1
}

který by byl použitelný jako v:

$ if isVgaConnected; then echo yes; fi

Ale buďte opatrní, xrandr trvá asi 0,140 s do 0.200 s , zatímco na zástrčkách nedojde k žádné změně a do 0,770 sekund kdykoli něco bylo připojeno nebo odpojeno těsně před ( POZNÁMKA: Zdá se, že to není zdrojový zdroj).

ÚPRAVA # 1

Abych zajistil, že neučím něco nesprávného, ​​prohledával jsem web a dokumenty, ale nenašel jsem nic o DBus and Screens.

Nakonec jsem běžel ve dvou různých oknech dbus-monitor --system (Hrál jsem také s možnostmi) a malý skript, který jsem napsal:

$ for ((i=1000;i--;)); do isVgaConnected && echo yes || echo no; sleep .5; done

... a znovu zapojen, než odpojen monitor, mnohokrát. Takže teď mohu říci:

  • V této konfiguraci pomocí ovladače i915 neexistuje jiný způsob, než spustit xrandr -q vědět, zda je monitor připojen nebo ne.

Ale buďte opatrní, protože se nejeví jiné způsoby. Například se zdá, že xrandr tyto informace sdílí, takže moje plocha GNOME by se automaticky přepnula na xinerama automaticky ... , když jsem běžel xrandr.

Některé dokumenty

14
F. Hauri

Následující řádky se objevily v 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)

při připojování monitoru k konektoru VGA. Takže by mohl existovat způsob, jak to zjistit.

4
sebastianwagner

Přistál jsem k použití srandrd . Sleduje X událostí a spouští skript, když se displej připojí nebo odpojí.

3
scorpp

Pro ty, kteří z jakéhokoli důvodu nechtějí jít hotplug cestou, je stále možné nezkoušet v skriptu pomocí inotifywait:

 #!/bin/bash 
 
 SCREEN_LEFT = DP2 
 SCREEN_RIGHT = eDP1 
 START_DELAY = 5 
 
 renice +19 $$>/dev/null 
 
 spánek $ START_DELAY 
 
 OLD_DUAL = "figurína" 
 
 zatímco [ 1]; do 
 DUAL = $ (cat /sys/class/drm/card0-DP-2/status)

 if ["$ OLD_DUAL"! = "$ DUAL"]; poté 
, pokud ["$ DUAL" == "připojen"]; pak 
 echo 'Nastavení duálního monitoru' 
 xrandr - výstup $ SCREEN_LEFT --auto --rotate normální --pos 0x0 - výstup $ SCREEN_RIGHT --auto --rotate normální - níže $ SCREEN_LEFT 
 Else 
 Echo 'Single monitor setup' 
 Xrandr --auto 
 Fi 
 
 OLD_DUAL = "$ DUAL" 
 fi 
 
 inotifywait -q -e close/sys/class/drm/card0-DP-2/status>/dev/null 
 hotovo 
 

Nejlépe je vyvoláno z vašeho .xsessionrc, nezapomínáme na konec &. Dotaz s xrandrem způsobil vážné problémy s použitelností na mém zcela novém notebooku (myš by se periodicky zastavovala).

3
Balzola

Očividně by mělo něco být! Souborový systém :)/sys sděluje uživatelům, jaký hardware je k dispozici, takže nástroje uživatelského prostoru (například udev nebo mdev) mohou dynamicky naplňovat adresář "/ dev" uzly zařízení představující aktuálně dostupný hardware. Linux poskytuje dvě hotplug rozhraní:/sbin/hotplug a netlink.

V následujícím souboru je malá ukázka C. http://www.kernel.org/doc/pending/hotplug.txt

0
roncsak

Většinou systémový/aplikační software v systému Linux dnes používal některé techniky ipc pro vzájemnou komunikaci. D-Bus se nyní většinou používá v aplikacích GNOME a může pomoci.

Linux Journal:

D-BUS může usnadňovat odesílání událostí nebo signálů prostřednictvím systému, což umožňuje různým komponentám v systému komunikovat a nakonec se lépe integrovat. Například Bluetooth dæmon může vyslat signál příchozího hovoru, který může váš hudební přehrávač zachytit, a ztlumit hlasitost až do ukončení hovoru.

wiki:

D-Bus dodává jak systémového démona (pro události, jako je „přidáno nové hardwarové zařízení“ nebo „změněna tisková fronta“), tak démona pro jednoho uživatele-přihlašovací relace (pro obecné potřeby meziprocesové komunikace mezi uživatelskými aplikacemi)

K dispozici je dokonce i knihovnaPython) a Ubuntu nedávno použil tuto schopnost, která se nazývala " zeitgeist ".

0
Amir Naghizadeh