Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Is there any event that is triggered when I plug in or out an external monitor into the DisplayPort of my laptop? ACPID and UDEV don't react at all.

I'm using onboard graphics on an intel chip. Here is a similar discussion which is already a couple of years old.

I don't want to use polling but I need to have some configuration that set's the display settings automatically depending on if the display is connected.

share|improve this question
4  
It can be done with udev. What is your kernel version? Are you using KMS (kernel mode setting)? –  Andy May 25 '11 at 16:00
    
Thanks for the answer. I am not sure about KMS, but as I said in the question, udev doesn't send any events. (udevadm monitor --property does not react at all) –  janoliver May 25 '11 at 16:27
    
@Andy: the last time this came up, it seemed that most systems required polling. If you've found a way to trigger a udev event, could you answer that question? –  Gilles May 25 '11 at 23:03
1  
I finally got it running loading i915 as kernel module. –  janoliver May 29 '11 at 12:13
3  
You can use xrandr or disper to detect if external monitor has been plugged in. github.com/wertarbyte/autorandr can show you how to use them. But xrandr/disper might not supported your video card. –  number5 Dec 5 '11 at 10:33

5 Answers 5

up vote 7 down vote accepted
+50

This was tested on a laptop with a i915 drived graphic card.

Definitively, in my config/install, there are not. :-(

When a new screen is plugged, no event is sent to the host! (This stay true after my last edit!)

So the only way is to use pooling... Trying to make them lighter as possible...

Last Edit : Finaly there is one better solution (through acpi):

At all, there are still no event! But acpi seem lighter than xrandr to inquire. (Nota: This require acpi modules loaded! But don't require root privileges)

My final purpose (using 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

(I'ts plugged! well, I unplugg them:)

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

Nota: ${1:+*-1+1} permit a boolean argument: If something is present, answer would be inversed: ( crtState >> 4 ) * -1 + 1.

and finalized:

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

Warning, lighter than xrandr, but not unimportant with a delay smaller than 0.02 seconds, the bash script will go to the top of resource eaters process (top)! While time read -a </proc/stat crtStat cost ~0.001 sec, read -a < /proc/acpi/video/VID/CRT0/state crtState require ~0.030 sec! This is big!! So depending on what you need. delay could be reasonably set between 0.5 and 2

Hope this help!

Edit 1

I've finaly found something, using this:

(Important disclaimer: Playing with /proc and /sys entries could break your system!!! So don't try the following on production system!!! At all don't blame me for anything happening to your material, your health, your wife or your dog!)

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

... after some cleaning of unwanted entrys:

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

I've been able to read this:

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

When I plug, Unplug, and re-plug monitor cable.

Old post

When the config is inquired (running system/preferences/monitor or xrandr), graphic card do a kind of scan before or all.

So running xrandr -q give you the info, but you have to poll the status.

I'v scanned all logs, (kernel, daemon, X and so) searched through /proc and /sys, clearly nothing seem exist to satisfy your request.

I've tried this too:

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

At all, I you run System/Preferences/Monitor while no new screen have just been plugged, nor unplugged, the tool will appear simply (normaly). But if you've plugged or unplugged a screen before, at time you run this tool you will see your desktop make a kind of reset or refresh (same if you run xrandr).

This seem confirm that this tool ask for xrandr (or work in the same manner) by pooling status periodicaly starting at time he is run.

You could try yourself:

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

This will display how much screen are connect, for 10 seconds.

While this run, plug and/or unplug your screen and look what's happen.

So you could create a litle bash test function:

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

useable in:

if isVgaConnected ;then echo yes;fi

But care, xrandr take about 0,140 sec to 0,200 sec while no change happens on plugs and upto 0,700 seconds whenever something was plugged or unplugged just before (Nota: It seem no to be a resource eater).

Edit: For ensuring I'm not teaching something false, I've searched around web and docs, but did'nt find anything about DBus and Screens.

Finaly, I've run in two differents windows dbus-monitor --system (I've been played with options too;) and the little script I wrote:

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

... and again plug, than unplug monitor, many times. So now I could say:

  • In this configuration, using i915 driver, there is no other way than running xrandr -q to know if a monitor is plugged or no.

But care, because as there is no other ways, xrandr seem share this info, so my gnome desktop swith to xinerama automaticaly... when I run xrandr

Some docs

share|improve this answer

The following lines appeared in 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)

when attaching a monitor to the VGA-Connector. So there might be a way to figure this out.

share|improve this answer
    
With an nVidia 9800 GT and proprietary drivers, udevadm monitor shows nothing when I connect an HDMI monitor. What hardware/drivers are you using? –  frankster Sep 8 at 8:30

Obviously there should be something! :) /sys filesystem tells userspace what hardware is available, so userspace tools (such as udev or mdev) can dynamically populate a "/dev" directory with device nodes representing the currently available hardware. Linux provides two hotplug interfaces: /sbin/hotplug and netlink.

There is a small C demo in the following file. http://www.kernel.org/doc/pending/hotplug.txt

share|improve this answer

Mostly system/application software on Linux today used some ipc techniques for communicating with each other. D-Bus is now mostly used with GNOME applications, and might help.

Linux Journal:

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)

There is even a Python library for this, and ubuntu recently used this ability which called "zeitgeist".

share|improve this answer

Graphically you can see if the monitor is recognized with Monitor, I know that you can find this on Ubuntu, Fedora and others in this(or a similar) location.

System/Preferences/Monitor

And you can turn-on/off any monitor you want or use both at same time with duplicate image in both monitor or independent monitors

share|improve this answer
2  
He asked for an event that's triggered when a monitor is plugged/unplugged –  Michael Mrozek Dec 24 '12 at 2:18
    
Did you look here? stackoverflow.com/questions/5469828/… –  Satish Jan 3 '13 at 15:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.