summaryrefslogtreecommitdiffstats
path: root/displayconfig/displayconfig-hwprobe.py
blob: 7ba5c69eae110b837eaabbc5cad9a47488363d62 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/python
###########################################################################
# displayconfig-hwprobe.py - description                                  #
# ------------------------------                                          #
# begin     : Sun Jan 22 2006                                             #
# copyright : (C) 2006 by Simon Edwards                                   #
# email     : simon@simonzone.com                                         #
#                                                                         #
###########################################################################
#                                                                         #
#   This program is free software; you can redistribute it and/or modify  #
#   it under the terms of the GNU General Public License as published by  #
#   the Free Software Foundation; either version 2 of the License, or     #
#   (at your option) any later version.                                   #
#                                                                         #
###########################################################################

# This program should be run during boot time. It quickly examines the
# graphics cards (read: PCI devices) in the computer and compares they to
# the list in the file $hardware_info_filename. If the two lists differ
# then the Debian package manager is automatically called to regenerate
# /etc/X11/xorg.conf. This hopefully should mean that people can swap gfx
# cards in and out and always have a system that will run Xorg. (even
# though the config will be most likely be suboptimal. Suboptimal is better
# than no X server).

import ScanPCI
import os
import syslog
import select

hardware_info_filename = "/var/lib/guidance/guidance-gfxhardware-snapshot"
data_file_dir = "/usr/share/apps/guidance/"

def main():
    # Scan the PCI bus.
    pci_bus = ScanPCI.PCIBus(data_file_dir)
    pci_bus.detect()

    # Stuff our device info in to a string.
    hardware_config = ""
    for pci_device in pci_bus.devices:
        if pci_device.isGfxCard():
            hardware_config += "PCI:%i:%i:%i Vendor:%x Device:%x Subvendor:%x Subdevice:%x\n" % \
                (pci_device.pci_bus, pci_device.pci_device, pci_device.pci_function,
                pci_device.vendor, pci_device.device,
                pci_device.subvendor, pci_device.subdevice)

    # Read in the old gfx hardware info in.
    previous_hardware = None
    try:
        fhandle = open(hardware_info_filename)
        previous_hardware = fhandle.read()
        fhandle.close()
    except IOError:
        previous_hardware = None

    if previous_hardware is not None and previous_hardware!=hardware_config:
        # Run dpkg and configure the new hardware.
        syslog.syslog(syslog.LOG_INFO, "Graphics card hardware has changed. Reconfiguring xorg.conf using 'dpkg-reconfigure xserver-xorg'.")
        cmd = ['dpkg-reconfigure','xserver-xorg']
        environ = os.environ.copy()
        environ['DEBIAN_FRONTEND'] = 'noninteractive'
        #os.spawnvpe(os.P_WAIT, 'dpkg-reconfigure', cmd, environ)
        result = ExecWithCapture('/usr/sbin/dpkg-reconfigure', cmd, 0, '/', 0,1, -1, environ)
        for line in result.split('\n'):
            syslog.syslog(syslog.LOG_INFO,"dpkg-reconfigure:"+line)

        # [21:18] <Riddell> you are brave indeed
        # [21:21] <Sime> I figured some kind of non-interactive "dpkg-reconfigure xorg" might be enough.
        # [21:22] <Riddell> yep

    if previous_hardware is None or previous_hardware!=hardware_config:
        syslog.syslog(syslog.LOG_INFO, "Writing graphics card hardware list to "+hardware_info_filename)
        # Write out the gfx hardware info
        tmp_filename = hardware_info_filename + ".tmp"
        fhandle = open(tmp_filename,'w')
        fhandle.write(hardware_config)
        fhandle.close()
        os.rename(tmp_filename, hardware_info_filename)


############################################################################
def ExecWithCapture(command, argv, searchPath = 0, root = '/', stdin = 0,
        catchfd = 1, closefd = -1, environ = None):

    if not os.access(root + command, os.X_OK) and not searchPath:
        raise RuntimeError, command + " can not be run"

    (read, write) = os.pipe()
    childpid = os.fork()
    if (not childpid):
        if (root and root != '/'): os.chroot(root)
        os.dup2(write, catchfd)
        os.close(write)
        os.close(read)

        if closefd != -1:
            os.close(closefd)
        if stdin:
            os.dup2(stdin, 0)
            os.close(stdin)

        # Replace the environment
        if environ is not None:
            os.environ.clear()
            os.environ.update(environ)

        if searchPath:
            os.execvp(command, argv)
        else:
            os.execv(command, argv)
        sys.exit(1)
    os.close(write)

    rc = ""
    s = "1"
    while s:
        select.select([read], [], [])
        s = os.read(read, 1000)
        rc = rc + s

    os.close(read)

    try:
        os.waitpid(childpid, 0)
    except OSError, (errno, msg):
        print __name__, "waitpid:", msg

    return rc

main()