~ubuntu-branches/ubuntu/trusty/plainbox-provider-checkbox/trusty

« back to all changes in this revision

Viewing changes to provider_bin/graphics_driver

  • Committer: Package Import Robot
  • Author(s): Zygmunt Krynicki
  • Date: 2014-04-07 19:00:31 UTC
  • mfrom: (3.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20140407190031-rf836grml6oilfyt
Tags: 0.4-1
* New upstream release. List of bugfixes:
  https://launchpad.net/plainbox-provider-checkbox/14.04/0.4
* debian/watch: look for new releases on launchpad
* debian/rules: stop using pybuild and use manage.py
  {i18n,build,install,validate} instead. This also drops dependency on
  python3-distutils-extra and replaces that with intltool
* debian/control: drop X-Python3-Version
* debian/control: make plainbox-provider-checkbox depend on python and
  python2.7 (for some scripts) rather than suggesting them.
* debian/upstream/signing-key.asc: Use armoured gpg keys to avoid having to
  keep binary files in Debian packaging. Also, replace that with my key
  since I made the 0.3 release upstream.
* debian/source/lintian-overrides: add an override for warning about no
  source for flash movie with reference to a bug report that discusses that
  issue.
* debian/source/include-binaries: drop (no longer needed)
* debian/patches: drop (no longer needed)
* debian/plainbox-provider-checkbox.lintian-overrides: drop (no longer
  needed)
* Stop being a python3 module, move to from DPMT to PAPT

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/env python3
2
 
#========================================================================
3
 
#
4
 
# based on xlogparse
5
 
#
6
 
# DESCRIPTION
7
 
#
8
 
# Parses Xlog.*.log format files and allows looking up data from it
9
 
#
10
 
# AUTHOR
11
 
#   Bryce W. Harrington <bryce@canonical.com>
12
 
#
13
 
# COPYRIGHT
14
 
#   Copyright (C) 2010-2012 Bryce W. Harrington
15
 
#   All Rights Reserved.
16
 
#
17
 
# Permission is hereby granted, free of charge, to any person obtaining
18
 
# a copy of this software and associated documentation files (the
19
 
# "Software"), to deal in the Software without restriction, including
20
 
# without limitation the rights to use, copy, modify, merge, publish,
21
 
# distribute, sublicense, and/or sell copies of the Software, and to
22
 
# permit persons to whom the Software is furnished to do so, subject to
23
 
# the following conditions:
24
 
#
25
 
# The above copyright notice and this permission notice shall be included
26
 
# in all copies or substantial portions of the Software.
27
 
#
28
 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29
 
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30
 
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
31
 
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
32
 
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
33
 
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
34
 
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 
#
36
 
#========================================================================
37
 
import re
38
 
import sys
39
 
import os
40
 
 
41
 
from subprocess import Popen, PIPE, check_output, CalledProcessError
42
 
 
43
 
 
44
 
class XorgLog(object):
45
 
 
46
 
    def __init__(self, logfile=None):
47
 
        self.modules = []
48
 
        self.errors = []
49
 
        self.warnings = []
50
 
        self.info = []
51
 
        self.notimpl = []
52
 
        self.notices = []
53
 
        self.cards = []
54
 
        self.displays = {}
55
 
        self.xserver_version = None
56
 
        self.boot_time = None
57
 
        self.boot_logfile = None
58
 
        self.kernel_version = None
59
 
        self.video_driver = None
60
 
        self.xorg_conf_path = None
61
 
        self.logfile = logfile
62
 
 
63
 
        if logfile:
64
 
            self.parse(logfile)
65
 
 
66
 
    def parse(self, filename):
67
 
        self.displays = {}
68
 
        display = {}
69
 
        display_name = "Unknown"
70
 
        in_file = open(filename, errors='ignore')
71
 
        gathering_module = False
72
 
        found_ddx = False
73
 
        module = None
74
 
        for line in in_file.readlines():
75
 
 
76
 
            m = re.search(r'\(..\)', line)
77
 
            if m:
78
 
                if gathering_module and module is not None:
79
 
                    self.modules.append(module)
80
 
                gathering_module = False
81
 
                module = None
82
 
                m = re.search(
83
 
                    '\(II\) Loading.*modules\/drivers\/(.+)_drv\.so', line)
84
 
                if m:
85
 
                    found_ddx = True
86
 
                m = re.search(r'\(II\) Module (\w+):', line)
87
 
                if m:
88
 
                    module = {
89
 
                        'name':         m.group(1),
90
 
                        'vendor':       None,
91
 
                        'version':      None,
92
 
                        'class':        None,
93
 
                        'abi_name':     None,
94
 
                        'abi_version':  None,
95
 
                        'ddx':          found_ddx,
96
 
                        }
97
 
                    found_ddx = False
98
 
                    gathering_module = True
99
 
 
100
 
            if gathering_module:
101
 
                m = re.search(r'vendor="(.*:?)"', line)
102
 
                if m:
103
 
                    module['vendor'] = m.group(1)
104
 
 
105
 
                m = re.search(r'module version = (.*)', line)
106
 
                if m:
107
 
                    module['version'] = m.group(1)
108
 
 
109
 
                if module['name'] == 'nvidia':
110
 
                    try:
111
 
                        version = check_output(
112
 
                            "nvidia-settings -v",
113
 
                            shell=True,
114
 
                            universal_newlines=True)
115
 
                        m = re.search(r'.*version\s+([0-9\.]+).*', version)
116
 
                        if m:
117
 
                            module['version'] = m.group(1)
118
 
                    except CalledProcessError:
119
 
                        pass
120
 
 
121
 
                m = re.search(r'class: (.*)', line)
122
 
                if m:
123
 
                    module['class'] = m.group(1)
124
 
 
125
 
                m = re.search(r'ABI class:\s+(.*:?), version\s+(.*:?)', line)
126
 
                if m:
127
 
                    if m.group(1)[:5] == "X.Org":
128
 
                        module['abi_name'] = m.group(1)[6:]
129
 
                    else:
130
 
                        module['abi_name'] = m.group(1)
131
 
                    module['abi_version'] = m.group(2)
132
 
                continue
133
 
 
134
 
            # General details
135
 
            m = re.search(r'Current Operating System: (.*)$', line)
136
 
            if m:
137
 
                uname = m.group(1)
138
 
                self.kernel_version = uname.split()[2]
139
 
                continue
140
 
 
141
 
            m = re.search(r'Kernel command line: (.*)$', line)
142
 
            if m:
143
 
                self.kernel_command_line = m.group(1)
144
 
                continue
145
 
 
146
 
            m = re.search(r'Build Date: (.*)$', line)
147
 
            if m:
148
 
                self.kernel_command_line = m.group(1)
149
 
                continue
150
 
 
151
 
            m = re.search(r'Log file: "(.*)", Time: (.*)$', line)
152
 
            if m:
153
 
                self.boot_logfile = m.group(1)
154
 
                self.boot_time = m.group(2)
155
 
 
156
 
            m = re.search(r'xorg-server ([^ ]+) .*$', line)
157
 
            if m:
158
 
                self.xserver_version = m.group(1)
159
 
                continue
160
 
 
161
 
            m = re.search(r'Using a default monitor configuration.', line)
162
 
            if m and self.xorg_conf_path is None:
163
 
                self.xorg_conf_path = 'default'
164
 
                continue
165
 
 
166
 
            m = re.search(r'Using config file: "(.*)"', line)
167
 
            if m:
168
 
                self.xorg_conf_path = m.group(1)
169
 
                continue
170
 
 
171
 
            # EDID and Modelines
172
 
            m = re.search(r'\(II\) (.*)\(\d+\): EDID for output (.*)', line)
173
 
            if m:
174
 
                self.displays[display_name] = display
175
 
                self.video_driver = m.group(1)
176
 
                display_name = m.group(2)
177
 
                display = {'Output': display_name}
178
 
                continue
179
 
 
180
 
            m = re.search(
181
 
                r'\(II\) (.*)\(\d+\): Assigned Display Device: (.*)$', line)
182
 
            if m:
183
 
                self.displays[display_name] = display
184
 
                self.video_driver = m.group(1)
185
 
                display_name = m.group(2)
186
 
                display = {'Output': display_name}
187
 
                continue
188
 
 
189
 
            m = re.search(r'\(II\) (.*)\(\d+\): Setting mode "(.*?):', line)
190
 
            if m:
191
 
                self.displays[display_name] = display
192
 
                self.video_driver = m.group(1)
193
 
                display_name = m.group(2)
194
 
                display = {'Output': display_name}
195
 
                continue
196
 
 
197
 
            m = re.search(
198
 
                r'Manufacturer: (.*) *Model: (.*) *Serial#: (.*)', line)
199
 
            if m:
200
 
                display['display manufacturer'] = m.group(1)
201
 
                display['display model'] = m.group(2)
202
 
                display['display serial no.'] = m.group(3)
203
 
 
204
 
            m = re.search(r'EDID Version: (.*)', line)
205
 
            if m:
206
 
                display['display edid version'] = m.group(1)
207
 
 
208
 
            m = re.search(r'EDID vendor \"(.*)\", prod id (.*)', line)
209
 
            if m:
210
 
                display['vendor'] = m.group(1)
211
 
                display['product id'] = m.group(2)
212
 
 
213
 
            m = re.search(
214
 
                r'Max Image Size \[(.*)\]: *horiz.: (.*) *vert.: (.*)', line)
215
 
            if m:
216
 
                display['size max horizontal'] = "%s %s" % (
217
 
                    m.group(2), m.group(1))
218
 
                display['size max vertical'] = "%s %s" % (
219
 
                    m.group(3), m.group(1))
220
 
 
221
 
            m = re.search(r'Image Size: *(.*) x (.*) (.*)', line)
222
 
            if m:
223
 
                display['size horizontal'] = "%s %s" % (m.group(1), m.group(3))
224
 
                display['size vertical'] = "%s %s" % (m.group(2), m.group(3))
225
 
 
226
 
            m = re.search(r'(.*) is preferred mode', line)
227
 
            if m:
228
 
                display['mode preferred'] = m.group(1)
229
 
 
230
 
            m = re.search(r'Modeline \"(\d+)x(\d+)\"x([0-9\.]+) *(.*)$', line)
231
 
            if m:
232
 
                key = "mode %sx%s@%s" % (m.group(1), m.group(2), m.group(3))
233
 
                display[key] = m.group(4)
234
 
                continue
235
 
 
236
 
            # Errors and Warnings
237
 
            m = re.search(r'\(WW\) (.*)$', line)
238
 
            if m:
239
 
                self.warnings.append(m.group(1))
240
 
                continue
241
 
 
242
 
            m = re.search(r'\(EE\) (.*)$', line)
243
 
            if m:
244
 
                self.errors.append(m.group(1))
245
 
                continue
246
 
 
247
 
        if display_name not in self.displays.keys():
248
 
            self.displays[display_name] = display
249
 
        in_file.close()
250
 
 
251
 
    def errors_filtered(self):
252
 
        excludes = set([
253
 
            'error, (NI) not implemented, (??) unknown.',
254
 
            'Failed to load module "fglrx" (module does not exist, 0)',
255
 
            'Failed to load module "nv" (module does not exist, 0)',
256
 
            ])
257
 
        return [err for err in self.errors if err not in excludes]
258
 
 
259
 
    def warnings_filtered(self):
260
 
        excludes = set([
261
 
            'warning, (EE) error, (NI) not implemented, (??) unknown.',
262
 
            'The directory "/usr/share/fonts/X11/cyrillic" does not exist.',
263
 
            'The directory "/usr/share/fonts/X11/100dpi/" does not exist.',
264
 
            'The directory "/usr/share/fonts/X11/75dpi/" does not exist.',
265
 
            'The directory "/usr/share/fonts/X11/100dpi" does not exist.',
266
 
            'The directory "/usr/share/fonts/X11/75dpi" does not exist.',
267
 
            'Warning, couldn\'t open module nv',
268
 
            'Warning, couldn\'t open module fglrx',
269
 
            'Falling back to old probe method for vesa',
270
 
            'Falling back to old probe method for fbdev',
271
 
            ])
272
 
        return [err for err in self.warnings if err not in excludes]
273
 
 
274
 
 
275
 
def get_driver_info(xlog):
276
 
    '''Return the running driver and version'''
277
 
    print('-' * 13, 'VIDEO DRIVER INFORMATION', '-' * 13)
278
 
    if xlog.video_driver:
279
 
        for module in xlog.modules:
280
 
            if module['name'] == xlog.video_driver.lower():
281
 
                print("Video Driver: %s" % module['name'])
282
 
                print("Driver Version: %s" % module['version'])
283
 
                print('\n')
284
 
                return 0
285
 
    else:
286
 
        print("ERROR: No video driver loaded! Possibly in failsafe mode!",
287
 
                file=sys.stderr)
288
 
        return 1
289
 
 
290
 
 
291
 
def is_laptop():
292
 
    return os.path.isdir('/proc/acpi/button/lid')
293
 
 
294
 
 
295
 
def hybrid_graphics_check(xlog):
296
 
    '''Check for Hybrid Graphics'''
297
 
    card_id1 = re.compile('.*0300: *(.+):(.+) \(.+\)')
298
 
    card_id2 = re.compile('.*0300: *(.+):(.+)')
299
 
    cards_dict = {'8086': 'Intel', '10de': 'NVIDIA', '1002': 'AMD'}
300
 
    cards = []
301
 
    drivers = []
302
 
    formatted_cards = []
303
 
 
304
 
    output = Popen(['lspci', '-n'], stdout=PIPE, universal_newlines=True)
305
 
    card_list = output.communicate()[0].split('\n')
306
 
 
307
 
    # List of discovered cards
308
 
    for line in card_list:
309
 
        m1 = card_id1.match(line)
310
 
        m2 = card_id2.match(line)
311
 
        if m1:
312
 
            id1 = m1.group(1).strip().lower()
313
 
            id2 = m1.group(2).strip().lower()
314
 
            id = id1 + ':' + id2
315
 
            cards.append(id)
316
 
        elif m2:
317
 
            id1 = m2.group(1).strip().lower()
318
 
            id2 = m2.group(2).strip().lower()
319
 
            id = id1 + ':' + id2
320
 
            cards.append(id)
321
 
 
322
 
    print('-' * 13, 'HYBRID GRAPHICS CHECK', '-' * 16)
323
 
    for card in cards:
324
 
        formatted_name = cards_dict.get(card.split(':')[0], 'Unknown')
325
 
        formatted_cards.append(formatted_name)
326
 
        print('Graphics Chipset: %s (%s)' % (formatted_name, card))
327
 
 
328
 
    for module in xlog.modules:
329
 
        if module['ddx'] and module['name'] not in drivers:
330
 
            drivers.append(module['name'])
331
 
    print('Loaded DDX Drivers: %s' %
332
 
            ', '.join(drivers))
333
 
 
334
 
    has_hybrid_graphics = (len(cards) > 1 and is_laptop()
335
 
        and (cards_dict.get('8086') in formatted_cards
336
 
        or cards_dict.get('1002') in formatted_cards))
337
 
 
338
 
    print('Hybrid Graphics: %s' % (has_hybrid_graphics
339
 
                                   and 'yes' or 'no'))
340
 
 
341
 
    return 0
342
 
 
343
 
 
344
 
def main():
345
 
    xlog = XorgLog("/var/log/Xorg.0.log")
346
 
    results = []
347
 
 
348
 
    results.append(get_driver_info(xlog))
349
 
    results.append(hybrid_graphics_check(xlog))
350
 
 
351
 
    return 1 if 1 in results else 0
352
 
 
353
 
if __name__ == "__main__":
354
 
    sys.exit(main())