detect VGA output hotplugging

Paul pauldu at linpus.com
Tue Aug 12 22:02:40 PDT 2008


Hi there!

I have to write a program which can automatically switch the display to
the internal LVDS output when the external VGA output is plugged out. if
we do not do this, the internal output will remain black, and user can
not switch to it any more unless he plugs in the external output again.
so this program should be able to detect when the external VGA output is
plugged out, but I can't find any notification for X clients to be
notified when the VGA output is hotplugged, so I use the polling way.

I use a timeout to do the detect, source code of the timeout callback as
the following: 

static gboolean
detect_monitor_timeout_cb (gpointer user_data)
{
        int i;
        char cmd[256];
        int cur_num_monitor = 0;
        XRRScreenResources * res;
        XRROutputInfo   * monitor_info;
        gboolean external_connected = FALSE;
        gboolean external_on = FALSE;
        gboolean internal_on = TRUE;

        res = XRRGetScreenResources (GDK_DISPLAY (), GDK_ROOT_WINDOW
());
        if (!res)
                fatal ("could not get screen resources");

        for (i = 0; i < res->noutput; i++) {
                monitor_info = XRRGetOutputInfo (GDK_DISPLAY (), res,
res->outputs[i]);
                if (monitor_info == NULL)
                        continue;

                if (monitor_info->connection == RR_Connected)
                        cur_num_monitor++;

                if (strcmp (monitor_info->name, INTERNAL_MONITOR_NAME)
== 0) {
                        if (monitor_info->crtc == None)
                                internal_on = FALSE;
                        else
                                internal_on = TRUE;

                if (strcmp (monitor_info->name, EXTERNAL_MONITOR_NAME)
== 0) {
                        if (monitor_info->connection == RR_Connected)
                                external_connected = TRUE;

                        if (monitor_info->crtc == None)
                                external_on = FALSE;
                        else
                                external_on = TRUE;
                }
        }

        if (cur_num_monitor < pre_num_monitor
         && external_connected == FALSE
         && internal_on == FALSE) {
                memset (cmd, 0, sizeof(cmd));
                sprintf (cmd, "xrandr --output %s --off --output %s
--auto", EXTERNAL_MONITOR_NAME, INTERNAL_MONITOR_NAME);
                system (cmd);
        }

        pre_num_monitor = cur_num_monitor;

        return TRUE;
}

but after I executed this program I found that the cpu usage of X server
was always very high.

timeout         average cpu usage of X server
0.5s            19%
4s              7%

Unfortunately, we can't accept this CPU power cost, so I wonder that if
there is any problem with my program or a better way can be used to
slove this problem. Any information/advice would be greatly appreciated.


Cheers,

Paul

======================================

CPU: Intel(R) Atom(TM) CPU N270   @ 1.60GHz

[root at localhost user] lspci | grep VGA
00:02.0 VGA compatible controller: Intel 945GME Express Integrated
Graphics Controller (rev 03)

x server:
xorg-x11-server-Xorg-1.3.0.0-35.fc8
xorg-x11-server-utils-7.3-1.fc8
xorg-x11-utils-7.3-1.fc8

[root at localhost user] xrandr
Screen 0: minimum 320 x 200, current 1024 x 600, maximum 1024 x 768
VGA connected (normal left inverted right x axis y axis)
   1024x600       60.0 +
   1024x768       85.0     84.9     75.1     75.0  
   800x600        84.9     85.1     75.0  
   640x480        84.6     75.0     60.0  
   720x400        70.1  
LVDS connected 1024x600+0+0 (normal left inverted right x axis y axis)
195mm x 113mm
   1024x600       60.0*+
   800x600        60.3  
   640x480        59.9  
TV disconnected (normal left inverted right x axis y axis)


xorg.conf:

# Xorg configuration created by system-config-display
Section "ServerFlags"
        Option "DontZap" "yes"
        Option "DontVTSwitch" "yes"
EndSection

Section "ServerLayout"
        Identifier     "Default Layout"
        Screen      0  "Screen0" 0 0
        InputDevice    "Mouse0" "CorePointer"
        InputDevice    "Synaptics Mouse" "AlwaysCore"
        InputDevice    "Keyboard0" "CoreKeyboard"
EndSection

Section "InputDevice"
        Identifier  "Keyboard0"
        Driver      "kbd"
        Option      "XkbModel" "pc105"
        Option      "XkbLayout" "us,gb"
        Option      "XkbVariant" "euro"
        Option      "XkbOptions" "grp:alt_shift_toggle"
EndSection

Section "InputDevice"
        Identifier "Synaptics Mouse"
        Driver     "synaptics"
        Option     "Device" "/dev/psaux"
        Option     "Protocol" "auto-dev"
        Option     "LeftEdge"  "1700"
        Option  "RightEdge"     "5300"
        Option  "TopEdge"       "1700"
        Option  "BottomEdge"    "4200"
        Option  "FingerLow"     "25"
        Option  "FingerHigh"    "30"
        Option  "MaxTapTime"    "180"
        Option  "MaxTapMove"    "220"
        Option  "VertScrollDelta" "100"
        Option  "MinSpeed"      "0.09"
        Option  "MaxSpeed"      "0.18"
        Option  "AccelFactor"   "0.0015"
        Option  "SHMConfig"     "on"
EndSection

Section "InputDevice"
        Identifier  "Mouse0"
        Driver      "mouse"
        Option      "Protocol" "IMPS/2"
        Option      "Device" "/dev/input/mice"
        Option      "ZAxisMapping" "4 5"
        Option      "Emulate3Buttons" "no"
EndSection

Section "Monitor"
        Identifier  "Monitor0"
        Modeline  "1024x600" 48.96 1024 1064 1168 1312 600 601 604 622
-HSync +VSync
EndSection

Section "Device"
        Identifier  "Videocard0"
        Driver      "intel"
        Option      "Clone" "true"
        Option "MonitorLayout" "LVDS,VGA"
        BusID   "PCI:0:2:0"
EndSection

Section "Screen"
        Identifier "Screen0"
        Device     "Videocard0"
        Monitor     "Monitor0"
        DefaultDepth     24
        SubSection "Display"
                Viewport   0 0
                Depth     24
                Modes    "1024x600" "800x600" "640x480"
                Virtual 1024 768
        EndSubSection
EndSection




More information about the xorg mailing list