Como posso detectar quando um monitor está conectado ou desconectado?

47

Existe algum evento que é acionado quando eu conecto um monitor externo no DisplayPort do meu laptop? ACPID e UDEV não reagem de todo.

Estou usando gráficos integrados em um chip Intel. Aqui é uma discussão semelhante que já tem alguns anos.

Eu não quero usar polling, mas eu preciso ter alguma configuração que defina as configurações de exibição automaticamente dependendo se o monitor está conectado.

    
por janoliver 25.05.2011 / 14:02

7 respostas

13

OBSERVAÇÃO: Isso foi testado em um laptop com placa gráfica i915.

Antecedentes

OBSERVAÇÃO: Quando uma nova tela é conectada, nenhum evento é enviado ao host. Isso permanece verdadeiro mesmo depois da minha última edição. Então, a única maneira é usar o polling. Tentando torná-los tão eficientes quanto possível ...

EDIT # 3

Finalmente, há uma solução melhor (por meio da ACPI):

Ainda não há evento, mas a ACPI parece mais eficiente do que xrandr para perguntar. (Nota: Este requer módulos do kernel da ACPI carregados, mas não requer privilégios de root).

Minha solução final (usando o bash):

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

Agora, um teste:

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

Ele está conectado, então agora eu o desconecto:

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

NOTA: ${1:+*-1+1} permite um argumento booleano : Se algo estiver presente , a resposta seria invertida: ( crtState >> 4 ) * -1 + 1 .

e o roteiro final:

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

AVISOS: mais claro que xrandr , mas não sem importância com um atraso menor que 0,02 segundos, o script Bash irá para o início do processo de comedores de recursos ( top )!

Enquanto isso custa ~ 0,001 seg:

$ time read -a </proc/stat crtStat

Isso requer ~ 0,030 seg:

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

Isso é grande! Então, dependendo do que você precisa, delay pode ser razoavelmente definido entre 0.5 e 2 .

Espero que esta ajuda!

EDIT # 2

Eu finalmente encontrei algo usando isso:

Aviso importante: Jogar com /proc e /sys entradas pode quebrar o seu sistema !!! Portanto, não tente o seguinte em sistemas de produção.

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

... após alguma limpeza de entradas indesejadas:

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

Eu consegui ler isto:

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

Quando eu conecto, desconecto e reconecto no cabo do monitor.

Resposta Original

Quando a configuração é consultada (executando system/preferences/monitor ou xrandr ), as placas gráficas fazem um tipo de varredura , portanto, executar xrandr -q fornece as informações, mas você precisa pesquisar o status.

Eu verifiquei todos os registros, (kernel, daemon, X e assim por diante) pesquisando /proc & /sys , e aparentemente nada parece existir que satisfaça seu pedido.

Eu também tentei isso:

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

Depois de tudo isso, se você executar System/Preferences/Monitor enquanto nenhuma nova tela acaba de ser conectada, nem desligada, a ferramenta aparecerá simplesmente (normalmente). Mas se você conectou ou desconectou uma tela antes, às vezes você executará esta ferramenta e verá sua área de trabalho fazendo um tipo de reset ou atualização (mesmo se você executar xrandr ).

Isso parece confirmar que essa ferramenta solicita xrandr (ou funciona da mesma maneira) pelo status de sondagem periodicamente, começando no momento em que é executada.

Você pode tentar:

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

Isso mostrará quantas telas (monitores) estão conectadas por 10 segundos.

Enquanto isso é executado, conecte e / ou desconecte sua tela / monitor e veja o que acontece. Então você pode criar uma pequena função de teste Bash:

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

que seria utilizável como em:

$ if isVgaConnected; then echo yes; fi

Mas tenha cuidado, xrandr demora cerca de 0,140 seg. a 0,200 seg. , enquanto não ocorre qualquer alteração nas fichas e até 0,700 segundos sempre que alguma coisa foi ligada ou desligada antes ( NOTA: parece não ser um comedor de recursos).

EDIT # 1

Para garantir que não estou ensinando algo incorreto, pesquisei na Web e em documentos, mas não encontrei nada sobre DBus e Telas .

Finalmente, eu corri em duas janelas diferentes dbus-monitor --system (eu tenho jogado com opções também) e o pequeno script que eu escrevi:

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

... e novamente conectado, do que desconectado do monitor, muitas vezes. Então agora eu poderia dizer:

  • Nessa configuração, usando o driver i915 , não há outra maneira de executar xrandr -q para saber se um monitor está conectado ou não.

Mas tenha cuidado, porque não parece haver outras maneiras. Por exemplo, xrandr parece compartilhar essa informação, então minha área de trabalho GNOME mudaria para xinerama automaticamente ... quando eu corria xrandr .

Alguns docs

por 23.07.2018 / 05:59
4

As seguintes linhas foram exibidas em 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)

ao conectar um monitor ao conector VGA. Então, pode haver uma maneira de descobrir isso.

    
por 30.03.2014 / 22:52
3

Para aqueles que, por alguma razão, não querem usar a rota do hotplug, ainda é possível não pesquisar em um script usando inotifywait:

#!/bin/bash

SCREEN_LEFT=DP2
SCREEN_RIGHT=eDP1
START_DELAY=5

renice +19 $$ >/dev/null

sleep $START_DELAY

OLD_DUAL="dummy"

while [ 1 ]; do
    DUAL=$(cat /sys/class/drm/card0-DP-2/status)

    if [ "$OLD_DUAL" != "$DUAL" ]; then
        if [ "$DUAL" == "connected" ]; then
            echo 'Dual monitor setup'
            xrandr --output $SCREEN_LEFT --auto --rotate normal --pos 0x0 --output $SCREEN_RIGHT --auto --rotate normal --below $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
done

É melhor invocado a partir do seu .xsessionrc, sem esquecer o final & A pesquisa com o xrandr forneceu sérios problemas de usabilidade em meu novo laptop (o mouse travaria periodicamente).

    
por 16.06.2015 / 14:05
3

Continuei usando srandrd . Ele monitora eventos X e aciona seu script quando um monitor é conectado ou desconectado.

    
por 12.11.2017 / 12:35
0

Obviamente, deve haver alguma coisa! O sistema de arquivos :) / sys informa ao userspace que hardware está disponível, portanto, ferramentas de espaço de usuário (como udev ou mdev) podem preencher dinamicamente um diretório "/ dev" com nós de dispositivos que representam o hardware atualmente disponível. O Linux fornece duas interfaces de hotplug: / sbin / hotplug e netlink.

Existe uma pequena demonstração C no seguinte arquivo. link

    
por 13.11.2012 / 10:28
0

Principalmente o software de sistema / aplicativo no Linux hoje usa algumas técnicas de ipc para comunicação entre si. O D-Bus agora é usado principalmente com aplicativos GNOME e pode ajudar.

Jornal do Linux:

D-BUS can facilitate sending events, or signals, through the system, allowing different components in the system to communicate and ultimately to integrate better. For example, a Bluetooth dæmon can send an incoming call signal that your music player can intercept, muting the volume until the call ends.

wiki:

D-Bus supplies both a system daemon (for events such as "new hardware device added" or "printer queue changed") and a per-user-login-session daemon (for general inter-process communication needs among user applications)

Existe até uma biblioteca Python para isso, e o ubuntu recentemente usou essa habilidade que chamou de " zeitgeist ".

    
por 23.11.2012 / 20:04
-6

Graficamente, você pode ver se o monitor é reconhecido com Monitor , eu sei que você pode encontrar isso no Ubuntu, no Fedora e em outros locais (ou similares).

System/Preferences/Monitor

E você pode ligar / desligar qualquer monitor que quiser ou usar os dois ao mesmo tempo com a imagem duplicada no monitor ou nos monitores independentes

    
por 18.10.2011 / 16:43