모니터의 전원이 연결되어 있거나 분리되어 있는지 어떻게 알 수 있습니까?


53

거기에 어떤 내 노트북의 디스플레이에 외부 모니터 또는 밖으로 연결하면 트리거 이벤트는? ACPID와 UDEV는 전혀 반응하지 않습니다.

인텔 칩에서 온보드 그래픽을 사용하고 있습니다. 여기 이미 몇 년 된 비슷한 토론이 있습니다.

폴링을 사용하고 싶지 않지만 디스플레이가 연결되어 있는지에 따라 디스플레이 설정을 자동으로 설정하는 구성이 필요합니다.


4
udev로 할 수 있습니다. 커널 버전은 무엇입니까? KMS (커널 모드 설정)를 사용하고 있습니까?
Andy

답변 해주셔서 감사합니다. KMS에 대해 잘 모르겠지만 질문에서 언급했듯이 udev는 이벤트를 보내지 않습니다. ( udevadm 모니터
속성

@Andy : 이것이 마지막으로 나타 났을 , 대부분의 시스템에는 폴링이 필요한 것 같았 습니다 . udev 이벤트를 발생시키는 방법을 찾았다면 그 질문에 대답 할 수 있습니까?
Gilles

1
마침내 커널 모듈로 i915를로드하여 실행했습니다.
janoliver

3
xrandr 또는 disper 를 사용하여 외부 모니터가 연결되어 있는지 감지 할 수 있습니다 . github.com/wertarbyte/autorandr 에서 사용 방법을 보여줄 수 있습니다. 그러나 xrandr / disper가 비디오 카드를 지원하지 않을 수 있습니다.

답변:


13

참고 : 이것은 i915 기반 그래픽 카드가 장착 된 랩톱에서 테스트되었습니다.


배경

참고 : 새 화면이 연결되면 호스트로 이벤트가 전송되지 않으며, 이는 마지막 편집 후에도 그대로 유지됩니다. 따라서 유일한 방법은 폴링을 사용하는 것입니다. 최대한 효율적으로 만들려고 노력 중입니다 ...

편집 # 3

마지막으로 ACPI를 통한 한 가지 더 나은 솔루션이 있습니다.

아직 이벤트는 없지만 ACPI는 xrandr문의하는 것보다 더 효율적 입니다. (의 Nota :이 필요 ACPI 커널 모듈로드하지만 루트 권한이 필요하지 않습니다).

내 마지막 해결책 (bash 사용) :

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

이제 테스트 :

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

연결되었으므로 이제 분리하십시오.

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

참고 : 부울 인수 ${1:+*-1+1}허용 : 무언가 존재하는 경우 답변이 반전됩니다 : .( crtState >> 4 ) * -1 + 1

그리고 마지막 스크립트 :

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

경고 : 보다 가볍지 만 xrandr0.02 초 보다 작은 지연으로 중요하지 않은 Bash 스크립트는 리소스 활용 프로세스의 맨 위로 이동합니다 ( top)!

이 비용은 ~ 0.001 초이지만 :

$ time read -a </proc/stat crtStat

~ 0.030 초가 필요합니다.

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

이것은 크다! 따라서 필요한 내용에 따라 및 delay사이에 합리적으로 설정할 수 있습니다 .0.52

편집 # 2

나는 이것을 사용하여 마침내 무언가를 발견했다.

중요한 면책 조항 : 게임을 /proc하고 /sys입장하면 시스템이 손상 될 수 있습니다 !!! 따라서 프로덕션 시스템에서 다음을 시도하지 마십시오.

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

... 원치 않는 항목을 청소 한 후 :

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

나는 이것을 읽을 수 있었다 :

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

모니터 케이블을 꽂고 뽑았다가 다시 꽂을 때.

원래 답변

구성을 조회 (실행 system/preferences/monitor또는 xrandr) 할 때 그래픽 카드는 스캔 유형을 수행 하므로 실행 xrandr -q은 정보를 제공하지만 상태를 폴링해야합니다.

/proc&를 통해 검색하는 모든 로그 (커널, 데몬, X 등)를 스캔 /sys했으며 요청을 충족시키는 것은 존재하지 않는 것 같습니다.

나는 이것을 시도했다.

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

결국, System/Preferences/Monitor새로운 화면이 연결되지 않았거나 분리되지 않은 상태에서 실행하면 도구가 단순히 (일반적으로) 나타납니다. 그러나 이전에 화면을 연결하거나 연결 해제 한 경우 때때로이 도구를 실행하면 데스크톱이 재설정 또는 새로 고침 유형 을 실행하는 것을 볼 수 있습니다 (실행하는 경우와 동일 xrandr).

이것은 도구가 xrandr실행될 때부터 주기적으로 상태를 폴링 하여이 도구가 요청 하거나 동일한 방식으로 작동 함 을 확인하는 것 같습니다 .

당신은 자신을 시도 할 수 있습니다 :

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

10 초 동안 연결된 화면 (디스플레이) 수를 표시합니다.

이것이 실행되는 동안, 화면 / 모니터를 꽂거나 뽑고 무슨 일이 일어나는지보십시오. 따라서 작은 Bash 테스트 기능을 만들 수 있습니다.

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

다음과 같이 사용할 수 있습니다.

$ if isVgaConnected; then echo yes; fi

그러나 플러그에 아무런 변화가없는 동안 xrandr0.140 초에서 0.200 초가 걸리며 , 바로 전에 무언가를 꽂거나 뽑을 때마다 최대 0.700 초가 걸립니다 ( 참고 : 자원 먹는 사람이 아닌 것 같습니다).

편집 # 1

내가 잘못된 것을 가르치지 않도록 웹과 문서를 검색했지만 DBus와 Screens대해서는 아무것도 찾지 못했습니다 .

마지막으로, 나는 두 가지 다른 창 dbus-monitor --system(옵션으로도 연주했습니다)과 내가 쓴 작은 스크립트에서 실행했습니다.

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

... 다시 모니터의 플러그를 뽑는 것보다 여러 차례 연결했습니다. 이제 말할 수 있습니다.

  • 이 구성에서는 i915 driver를 사용하여xrandr -q 모니터가 연결되어 있는지 여부를 알기위한 방법 외에는 다른 방법이 없습니다.

그러나 다른 방법이없는 것처럼 보이기 때문에주의하십시오. 예를 들어, xrandr이 정보를 공유하는 것 같습니다. 따라서 GNOME 데스크탑은 xinerama자동으로 실행xrandr 됩니다.

일부 문서


4

다음 라인에 등장 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 커넥터에 모니터를 연결할 때 따라서 이것을 알아낼 수있는 방법이있을 수 있습니다.


nVidia 9800 GT 및 독점 드라이버를 사용하면 HDMI 모니터를 연결할 때 udevadm 모니터에 아무 것도 표시되지 않습니다. 어떤 하드웨어 / 드라이버를 사용하고 있습니까?
frankster

안타깝게도, 그것은 저에게 신뢰할 수 없습니다. 모니터를 플러그인 할 때 때때로 이러한 이벤트 메시지가 표시되는 경우가 있습니다.
Tobias

3

어떤 이유로 든 핫 플러그 ​​경로를 사용하지 않으려는 경우 inotifywait를 사용하여 스크립트 내에서 폴링하지 않을 수 있습니다.

#! / bin / bash

SCREEN_LEFT = DP2
SCREEN_RIGHT = eDP1
START_DELAY = 5

레 니체 +19 $$> / dev / null

수면 $ START_DELAY

OLD_DUAL = "더미"

[1] 동안; 하다
    듀얼 = $ (고양이 / sys / class / drm / card0-DP-2 / 상태)

    [ "$ OLD_DUAL"! = "$ DUAL"] 인 경우; 그때
        [ "$ DUAL"== "connected"] 인 경우; 그때
            에코 '듀얼 모니터 설정'
            xrandr-출력 $ SCREEN_LEFT-자동-일반 회전 --pos 0x0-출력 $ SCREEN_RIGHT-자동-정상 회전-$ SCREEN_LEFT 이하
        그밖에
            에코 '단일 모니터 설정'
            xrandr-자동
        fi

        OLD_DUAL = "$ DUAL"
    fi

    inotifywait -q -e 닫기 / sys / class / drm / card0-DP-2 / status> / dev / null
끝난

종료 &를 잊지 않고 .xsessionrc에서 호출하는 것이 가장 좋습니다. xrandr와의 폴링은 새로운 랩탑에서 사용성에 심각한 문제를 일으켰습니다 (마우스는 주기적으로 멈춤).


난 당신이 inotify를에 사용할 수있는 생각하지 않았을 /proc그냥 일을 inotifywait -q -e close /sys/class/drm/card0-DP-2/status 내 시스템에 DP-2를 분리시 끝나지 않았다 참
nhed

3

나는 srandrd 사용을 고집했다 . X 이벤트를 모니터링하고 디스플레이가 연결되거나 연결이 끊어지면 스크립트를 트리거합니다.


0

분명히 뭔가가 있어야합니다! :) / sys 파일 시스템은 사용자 공간에 사용 가능한 하드웨어를 알려주므로 사용자 공간 도구 (예 : udev 또는 mdev)는 "/ dev"디렉토리를 현재 사용 가능한 하드웨어를 나타내는 장치 노드로 동적으로 채울 수 있습니다. Linux는 / sbin / hotplug 및 netlink의 두 가지 핫 플러그 ​​인터페이스를 제공합니다.

다음 파일에는 작은 C 데모가 있습니다. http://www.kernel.org/doc/pending/hotplug.txt


0

오늘날 Linux의 시스템 / 응용 소프트웨어는 대부분 서로 통신하기 위해 일부 ipc 기술을 사용했습니다. D-Bus는 현재 대부분 그놈 응용 프로그램과 함께 사용되며 도움이 될 수 있습니다.

리눅스 저널 :

D-BUS는 시스템을 통한 이벤트 또는 신호 전송을 용이하게하여 시스템의 여러 구성 요소가 통신하고 궁극적으로 더 나은 통합을 가능하게합니다. 예를 들어, Bluetooth 데몬은 음악 플레이어가 가로 챌 수있는 수신 전화 신호를 보내 통화가 끝날 때까지 볼륨을 소거 할 수 있습니다.

위키 :

D-Bus는 시스템 데몬 ( "새 하드웨어 장치 추가"또는 "프린터 큐 변경"과 같은 이벤트의 경우)과 사용자 별 로그인 세션 데몬 (사용자 응용 프로그램 간의 일반적인 프로세스 간 통신 요구)을 모두 제공합니다.

이를위한 파이썬 라이브러리도 있으며, 우분투는 최근에 " zeitgeist " 라고 불리는이 기능을 사용했습니다 .


-6

그래픽으로 모니터가 인식 Monitor되는지 알 수 있습니다. 우분투, 페도라 및 기타 (또는 유사한) 위치에서 이것을 찾을 수 있음을 알고 있습니다.

시스템 / 환경 설정 / 모니터

또한 모니터 또는 독립 모니터 모두에서 중복 이미지로 원하는 모니터를 켜거나 끌 수 있습니다.


2
그는 모니터를 꽂거나 뽑을 때 트리거되는 이벤트를 요청했습니다
Michael Mrozek

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.