Bir monitörün takılı veya fişli olduğunu nasıl tespit edebilirim?


53

Dizüstü bilgisayarımın DisplayPort'una harici bir monitör taktığımda veya çıkardığımda tetiklenen herhangi bir olay var mı ? ACPID ve UDEV hiç tepki vermiyor.

Dahili çipte yerleşik grafikleri kullanıyorum. İşte zaten birkaç yaşında olan benzer bir tartışma.

Yoklama kullanmak istemiyorum ancak ekranın bağlı olup olmadığına bağlı olarak, ekran ayarlarını otomatik olarak ayarlayan bazı yapılandırmalara ihtiyacım var.


4
Udev ile yapılabilir. Çekirdek versiyonun nedir? KMS kullanıyor musunuz (çekirdek modu ayarı)?
Andy

Cevap için teşekkürler. KMS hakkında emin değilim, ancak soruda dediğim gibi, udev herhangi bir olay göndermiyor. ( udevadm monitör - özellik hiç tepki vermiyor)
janoliver

@Andy: Bu son ortaya çıktığında , çoğu sistemin yoklama gerektirdiği görülüyordu. Bir udev etkinliğini tetiklemenin bir yolunu bulursanız, bu soruyu cevaplayabilir misiniz?
Gilles 'SO- kötülük'

1
Sonunda i915'i çekirdek modül olarak yükleyerek çalıştırdım.
janoliver

3
Harici monitörün takılı olup olmadığını tespit etmek için xrandr veya disper kullanabilirsiniz. Github.com/wertarbyte/autorandr bunları nasıl kullanacağınızı gösterebilir. Ancak xrandr / disper, ekran kartınızı desteklemiyor olabilir.
number5

Yanıtlar:


13

NOT: Bu, i915 tahrikli grafik kartlı bir dizüstü bilgisayarda test edilmiştir.


Arka fon

NOT: Yeni bir ekran takıldığında, ana bilgisayara hiçbir olay gönderilmez, bu, son düzenlememden sonra bile geçerlidir. Yani tek yol yoklama kullanmak. Onları olabildiğince verimli kılmaya çalışıyorum ...

# 3 DÜZENLEME

Sonunda daha iyi bir çözüm var (ACPI aracılığıyla):

Hala bir olay yok, ancak ACPI sormaktan daha verimli görünüyor xrandr. (Not: Bu , yüklü ACPI çekirdek modüllerini gerektirir , ancak kök ayrıcalıkları gerektirmez).

Son çözümüm (bash kullanarak):

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

Şimdi bir test:

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

Fişe takılı, bu yüzden şimdi fişini çekiyorum:

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

NOT: ${1:+*-1+1} Bir izin boolean argüman: Eğer bir şey mevcutsa , cevap ters olurdu: ( crtState >> 4 ) * -1 + 1.

ve son senaryo:

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

UYARILAR: 0,02 saniyeden daha kısa bir gecikmeyle daha hafif xrandr, ancak önemsiz değil , Bash komut dosyası kaynak yiyenlerin işleminin en üstüne gider ( )!top

Bu maliyet ~ 0,001 sn iken:

$ time read -a </proc/stat crtStat

Bu, ~ 0.030 sn gerektirir:

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

Bu büyük! Yani ihtiyacınız olana bağlı olarak, ve delayarasında makul bir şekilde ayarlanmış olabilir .0.52

# 2 DÜZENLEME

Sonunda bunu kullanarak bir şey buldum:

Önemli feragatname: Oynamak /procve /sysgirişler sisteminizi bozabilir !!! Bu yüzden üretim sistemlerinde aşağıdakileri denemeyin.

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

... istenmeyen meraklıları temizledikten sonra:

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

Bunu okuyabildim:

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

Monitör kablosunu taktığımda, fişten çekip çıkarın.

Orijinal cevap

Yapılandırma sorulduğunda (çalışıyor system/preferences/monitorveya çalışıyor xrandr), grafik kartları bir tür tarama yapar , bu nedenle çalıştırma xrandr -qsize bilgi verir, ancak durumu yoklamanız gerekir.

Tüm günlükleri taradım, (çekirdek, daemon, X vb.) /proc& /sys, Ve açıkça talebinizi karşılayacak hiçbir şey bulunmadığı görülüyor.

Bunu da denedim:

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

Tüm bunlardan sonra, System/Preferences/Monitoryeni bir ekran henüz takılı olmadığında ya da takılı olmadığında çalışırsanız , araç basitçe (normal olarak) görünecektir. Ancak, daha önce bir ekranı taktıysanız veya çıkardıysanız, zaman zaman bu aracı çalıştırırsınız ve masaüstünüzde bir tür sıfırlama veya yenileme işlemi görürsünüz (çalıştırırsanız aynı xrandr).

Bu, bu aracın xrandrçalıştırıldığı zamandan itibaren periyodik olarak oy kullanma durumunu istediğini (veya aynı şekilde çalıştığını) onaylıyor gibi görünüyor .

Kendin deneyebilirsin:

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

Bu, 10 saniye boyunca kaç ekranın bağlandığını görüntüler.

Bu çalışırken, ekranınızı / monitörünüzü fişe takıp çıkarın ve neler olduğuna bakın. Böylece küçük bir Bash test fonksiyonu yaratabilirsiniz:

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

hangi gibi kullanılabilir:

$ if isVgaConnected; then echo yes; fi

Ancak dikkatli olun, fişlerde herhangi bir değişiklik yapılmazken ve daha önce bir şey takıldığında ya da çıkarıldığında 0.700 saniyeye kadar sürebilirken , 0.240 saniye ilexrandr yaklaşık 0.140 saniye sürer ( NOT: Bir kaynak yiyici gibi görünmüyor).

# 1 DÜZENLEME

Yanlış bir şey öğretmediğimden emin olmak için Web ve dokümanlar arasında arama yaptım ancak DBus ve Ekranlar hakkında hiçbir şey bulamadım .

Sonunda, iki farklı pencerede dbus-monitor --system(seçeneklerle de oynuyorum) ve yazdığım küçük senaryoyu kullandım:

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

... ve tekrar takılı, monitörün fişini çektikten çok defa. Şimdi söyleyebilirim ki:

  • Bu yapılandırmada, i915 sürücüsünü kullanarak , xrandr -qmonitörün takılı olup olmadığını bilmek dışında koşmanın başka yolu yoktur .

Ancak dikkatli olun, çünkü başka yollar görünmüyor. Örneğin, xrandrbu bilgi paylaşmak gibi görünüyor, bu yüzden benim GNOME masaüstü geçmek istiyorsunuz xineramaotomatik ... Kaçtım zamanxrandr .

Bazı dokümanlar


4

Aşağıdaki satırlar göründü: 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)

VGA Konektörüne bir monitör takarken. Yani bunu çözmenin bir yolu olabilir.


NVidia 9800 GT ve tescilli sürücüler ile udevadm monitör, HDMI monitör bağladığımda hiçbir şey göstermiyor. Hangi donanım / sürücüleri kullanıyorsunuz?
frankster

Yazık ki, bu benim için güvenilir çalışmıyor. Bazen bu olay iletilerini monitörümü taktığımda alıyorum ve bazen vermiyor.
Tobias,

3

Her ne sebeple olursa olsun, hotplug rotasını kullanmak istemeyenlere, inotifywait kullanarak bir betiğin içinde yoklama yapmak mümkündür:

#! / Bin / bash

SCREEN_LEFT = DP2
SCREEN_RIGHT = eDP1
START_DELAY = 5

renice +19 $$> / dev / null

uyku $ START_DELAY

OLD_DUAL = "kukla"

[1] iken; yap
    DUAL = $ (kedi / sys / sınıf / drm / kart0-DP-2 / durum)

    eğer ["$ OLD_DUAL"! = "$ DUAL"]; sonra
        eğer ["$ DUAL" == "bağlı"]; sonra
            echo 'İkili monitör kurulumu'
            xrandr - çıkış $ SCREEN_LEFT - otomatik - normal döndür - 0x0 - çıkış $ SCREEN_RIGHT - otomatik - döndür normal - sıfır $ SCREEN_LEFT
        Başka
            echo 'Tek monitör kurulumu'
            xrandr --auto
        fi

        OLD_DUAL = "$ ÇİFT"
    fi

    inotifywait -q -e kapat / sys / sınıf / drm / kart0-DP-2 / durum> / dev / null
tamam

En iyisi .xsessionrc adresinden çağrılır, sonunu unutmamaktır. Xrandr ile oylama, yeni dizüstü bilgisayarımda ciddi kullanılabilirlik sorunları ortaya çıkardı (fare belirli aralıklarla dururdu).


/procinotifywait -q -e close /sys/class/drm/card0-DP-2/status
İnotify'ı

3

Srandrd kullanmaya saplandım . X olaylarını izler ve bir ekran bağlandığında veya bağlantısı kesildiğinde komut dosyanızı tetikler.


0

Açıkçası bir şey olmalı! :) / sys dosya sistemi kullanıcılara hangi donanımın mevcut olduğunu söyler, böylece kullanıcı araçları (udev veya mdev gibi) dinamik olarak "/ dev" dizini dinamik olarak mevcut donanımları temsil eden cihaz düğümleriyle doldurabilir. Linux iki hotplug arayüzü sunar: / sbin / hotplug ve netlink.

Aşağıdaki dosyada küçük bir C demosu var. http://www.kernel.org/doc/pending/hotplug.txt


0

Günümüzde Linux'taki sistem / uygulama yazılımı bugün birbirleriyle iletişim kurmak için bazı ipc teknikleri kullandı. D-Bus artık çoğunlukla GNOME uygulamalarında kullanılıyor ve yardımcı olabilir.

Linux Journal:

D-BUS, sistemdeki olayların veya sinyallerin sistemdeki farklı bileşenlerin iletişim kurmasına ve nihayetinde daha iyi bütünleşmesine izin vererek gönderilmesini kolaylaştırabilir. Örneğin, bir Bluetooth dekanı, müzik çalarınızın arayabileceği ve arama sona erene kadar sesi kısmadan gelen bir arama sinyali gönderebilir.

wiki:

D-Bus, hem bir sistem arka plan programı ("yeni donanım aygıtı eklendi" ya da "yazıcı kuyruğu değiştirildi" gibi olaylar için) hem de kullanıcı başına bir oturum açma oturumu arka plan programı (kullanıcı uygulamaları arasında genel süreçler arası iletişim ihtiyaçları için) sağlar

Bunun için bir Python kütüphanesi bile var ve ubuntu son zamanlarda " zeitgeist " adı verilen bu yeteneği kullandı .


-6

Grafik olarak, monitörün tanınıp tanımadığını görebilirsiniz Monitor, bunu Ubuntu, Fedora ve diğerlerinde bu (veya benzer) bir konumda bulabileceğinizi biliyorum.

Sistem / Tercihler / Monitör

Ayrıca, hem monitörde hem de bağımsız monitörde yinelenen görüntüyle aynı anda kullanmak istediğiniz monitörleri açıp kapatabilirsiniz.


2
Bir monitör takıldığında / çıkarıldığında tetiklenen bir olay istedi
Michael Mrozek

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.