~jocave/checkbox/hybrid-amd-gpu-mods

« back to all changes in this revision

Viewing changes to providers/plainbox-provider-checkbox/bin/xrandr_cycle

  • Committer: Zygmunt Krynicki
  • Date: 2013-05-29 07:50:30 UTC
  • mto: This revision was merged to the branch mainline in revision 2153.
  • Revision ID: zygmunt.krynicki@canonical.com-20130529075030-ngwz245hs2u3y6us
checkbox: move current checkbox code into checkbox-old

This patch cleans up the top-level directory of the project into dedicated
sub-project directories. One for checkbox-old (the current checkbox and all the
associated stuff), one for plainbox and another for checkbox-ng.

There are some associated changes, such as updating the 'source' mode of
checkbox provider in plainbox, and fixing paths in various test scripts that we
have.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/env python3
2
 
 
3
 
import argparse
4
 
import errno
5
 
import os
6
 
import re
7
 
import shutil
8
 
import subprocess
9
 
import sys
10
 
import tarfile
11
 
import time
12
 
 
13
 
parser = argparse.ArgumentParser()
14
 
parser.add_argument('--keyword', default='',
15
 
                    help=('A keyword to distinguish the screenshots '
16
 
                          'taken in this run of the script'))
17
 
parser.add_argument('--screenshot-dir',
18
 
                    default=os.environ['HOME'],
19
 
                    help=('Specify a directory to store screenshots in. '
20
 
                          'Default is %(default)s'))
21
 
args = parser.parse_args()
22
 
 
23
 
 
24
 
device_context = ''    # track what device's modes we are looking at
25
 
modes = []             # keep track of all the devices and modes discovered
26
 
current_modes = []     # remember the user's current settings for cleanup later
27
 
failures = 0           # count the number of failed modesets
28
 
failure_messages = []  # remember which modes failed
29
 
success_messages = []  # remember which modes succeeded
30
 
 
31
 
# Run xrandr and ask it what devices and modes are supported
32
 
xrandrinfo = subprocess.Popen('xrandr -q', shell=True, stdout=subprocess.PIPE)
33
 
output = xrandrinfo.communicate()[0].decode().split('\n')
34
 
 
35
 
 
36
 
# The results from xrandr are given in terms of the available display devices.
37
 
# One device can have zero or more associated modes.  Unfortunately xrandr
38
 
# indicates this through indentation and is kinda wordy, so we have to keep
39
 
# track of the context we see mode names in as we parse the results.
40
 
 
41
 
for line in output:
42
 
    # I haven't seen any blank lines in xrandr's output in my tests, but meh
43
 
    if line == '':
44
 
        break
45
 
 
46
 
    # luckily the various data from xrandr are separated by whitespace...
47
 
    foo = line.split()
48
 
 
49
 
    # Check to see if the second word in the line indicates a new context
50
 
    #  -- if so, keep track of the context of the device we're seeing
51
 
    if len(foo) >= 2:  # throw out any weirdly formatted lines
52
 
        if foo[1] == 'disconnected':
53
 
            # we have a new context, but it should be ignored
54
 
            device_context = ''
55
 
        if foo[1] == 'connected':
56
 
            # we have a new context that we want to test
57
 
            device_context = foo[0]
58
 
        elif device_context != '':  # we've previously seen a 'connected' dev
59
 
            # mode names seem to always be of the format [horiz]x[vert]
60
 
            # (there can be non-mode information inside of a device context!)
61
 
            if foo[0].find('x') != -1:
62
 
                modes.append((device_context, foo[0]))
63
 
            # we also want to remember what the current mode is, which xrandr
64
 
            # marks with a '*' character, so we can set things back the way
65
 
            # we found them at the end:
66
 
            if foo[1].find('*') != -1:
67
 
                current_modes.append((device_context, foo[0]))
68
 
 
69
 
# Now we have a list of the modes we need to test.  So let's do just that.
70
 
profile_path = os.environ['HOME'] + '/.shutter/profiles/'
71
 
screenshot_path = os.path.join(args.screenshot_dir, 'xrandr_screens')
72
 
 
73
 
# Where to find the shutter.xml template? Two possible locations.
74
 
shutter_xml_template = None
75
 
 
76
 
if 'PLAINBOX_PROVIDER_DATA' in os.environ:
77
 
    shutter_xml_template = os.path.join(os.environ['PLAINBOX_PROVIDER_DATA'],
78
 
                                        "settings", "shutter.xml")
79
 
else:
80
 
    shutter_xml_template = os.path.join(os.path.split(os.path.dirname(
81
 
                                        os.path.realpath(__file__)))[0],
82
 
                                       "data",
83
 
                                        "settings",
84
 
                                        "shutter.xml")
85
 
 
86
 
if args.keyword:
87
 
    screenshot_path = screenshot_path + '_' + args.keyword
88
 
 
89
 
regex = re.compile(r'filename="[^"\r\n]*"')
90
 
 
91
 
# Keep the shutter profile in place before starting
92
 
 
93
 
# Any errors creating the directories or copying the template is fatal,
94
 
# since things won't work if we fail.
95
 
try:
96
 
    os.makedirs(profile_path, exist_ok=True)
97
 
    os.makedirs(screenshot_path, exist_ok=True)
98
 
except OSError as excp:
99
 
    raise SystemExit("ERROR: Unable to create "
100
 
                     "required directories: {}".format(excp))
101
 
 
102
 
try:
103
 
    shutil.copy(shutter_xml_template, profile_path)
104
 
except (IOError, OSError) as excp:
105
 
    print("ERROR: Unable to copy {} to {}: {}".format(shutter_xml_template,
106
 
                                                      profile_path,
107
 
                                                      excp))
108
 
    if excp.errno == errno.ENOENT:
109
 
        print("Try setting PLAINBOX_PROVIDER_DATA to the the data path of a")
110
 
        print("provider shipping the 'shutter.xml' template file, usually ")
111
 
        print("found under /usr/share.")
112
 
    raise SystemExit()
113
 
 
114
 
try:
115
 
    old_profile = open(profile_path + 'shutter.xml', 'r')
116
 
    content = old_profile.read()
117
 
    new_profile = open(profile_path + 'shutter.xml', 'w')
118
 
    # Replace the folder name with the desired one
119
 
    new_profile.write(re.sub(r'folder="[^"\r\n]*"',
120
 
                             'folder="%s"' % screenshot_path, content))
121
 
    new_profile.close()
122
 
    old_profile.close()
123
 
except:
124
 
    raise SystemExit("ERROR: While updating folder name "
125
 
                     "in shutter profile: {}".format(sys.exc_info()))
126
 
 
127
 
for mode in modes:
128
 
    cmd = 'xrandr --output ' + mode[0] + ' --mode ' + mode[1]
129
 
    retval = subprocess.call(cmd, shell=True)
130
 
    if retval != 0:
131
 
        failures = failures + 1
132
 
        message = 'Failed to set mode ' + mode[1] + ' for output ' + mode[0]
133
 
        failure_messages.append(message)
134
 
    else:
135
 
        # Update shutter profile to save the image as the right name
136
 
        mode_string = mode[0] + '_' + mode[1]
137
 
 
138
 
        try:
139
 
            old_profile = open(profile_path + 'shutter.xml', 'r')
140
 
            content = old_profile.read()
141
 
            new_profile = open(profile_path + 'shutter.xml', 'w')
142
 
            new_profile.write(regex.sub('filename="%s"' % mode_string,
143
 
                              content))
144
 
            new_profile.close()
145
 
            old_profile.close()
146
 
 
147
 
            shuttercmd = ['shutter', '--profile=shutter', '--full', '-e']
148
 
            retval = subprocess.call(shuttercmd, shell=False)
149
 
 
150
 
            if retval != 0:
151
 
                print("""Could not capture screenshot -
152
 
                         you may need to install the package 'shutter'.""")
153
 
 
154
 
        except:
155
 
            print("""Could not configure screenshot tool -
156
 
                     you may need to install the package 'shutter',
157
 
                     or check that {}/{} exists and is writable.""".format(
158
 
                profile_path,
159
 
                'shutter.xml'))
160
 
 
161
 
        message = 'Set mode ' + mode[1] + ' for output ' + mode[0]
162
 
        success_messages.append(message)
163
 
    time.sleep(3)  # let the hardware recover a bit
164
 
 
165
 
# Put things back the way we found them
166
 
 
167
 
for mode in current_modes:
168
 
    cmd = 'xrandr --output ' + mode[0] + ' --mode ' + mode[1]
169
 
    subprocess.call(cmd, shell=True)
170
 
 
171
 
# Tar up the screenshots for uploading
172
 
try:
173
 
    with tarfile.open(screenshot_path + '.tgz', 'w:gz') as screen_tar:
174
 
        for screen in os.listdir(screenshot_path):
175
 
            screen_tar.add(screenshot_path + '/' + screen, screen)
176
 
except:
177
 
    pass
178
 
 
179
 
# Output some fun facts and knock off for the day
180
 
 
181
 
for message in failure_messages:
182
 
    print(message, file=sys.stderr)
183
 
 
184
 
for message in success_messages:
185
 
    print(message)
186
 
 
187
 
if failures != 0:
188
 
    exit(1)
189
 
else:
190
 
    exit(0)