<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.thinkwiki.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Newacct</id>
	<title>ThinkWiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://www.thinkwiki.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Newacct"/>
	<link rel="alternate" type="text/html" href="https://www.thinkwiki.org/wiki/Special:Contributions/Newacct"/>
	<updated>2026-05-01T08:20:21Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.12</generator>
	<entry>
		<id>https://www.thinkwiki.org/w/index.php?title=Code/tp_power_monitor.py&amp;diff=50251</id>
		<title>Code/tp power monitor.py</title>
		<link rel="alternate" type="text/html" href="https://www.thinkwiki.org/w/index.php?title=Code/tp_power_monitor.py&amp;diff=50251"/>
		<updated>2011-01-09T03:54:13Z</updated>

		<summary type="html">&lt;p&gt;Newacct: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
# COPYRIGHT (C) 2006 Matthew Garman&lt;br /&gt;
# matthew (dot) garman (at) gmail (dot) com&lt;br /&gt;
# License: MIT &amp;lt;http://www.opensource.org/licenses/mit-license.php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import sys, time, getopt, os, re&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class tpPowerMonitorDataSource:&lt;br /&gt;
&lt;br /&gt;
    # The name of the file to parse for needed data (data_source_file) OR&lt;br /&gt;
    # the name of a command whose output will be read as a file&lt;br /&gt;
    # (os.popen(shell_command)).&lt;br /&gt;
    #&lt;br /&gt;
    # Typically, data_source_file will be something from /proc (or&lt;br /&gt;
    # possibly /sys), and shell_command will be a utility+arguments such&lt;br /&gt;
    # as &amp;quot;iwconfig eth1 power&amp;quot;.&lt;br /&gt;
    #&lt;br /&gt;
    # Note that you should set EITHER data_source_file OR shell_command,&lt;br /&gt;
    # but not both.&lt;br /&gt;
    data_source_file    = None&lt;br /&gt;
    shell_command       = None&lt;br /&gt;
&lt;br /&gt;
    # The line number of the data file containing our data OR the string&lt;br /&gt;
    # that marks the beginning of the line in which we're interested&lt;br /&gt;
    # (startswith_string) OR a regular expression to key the data for&lt;br /&gt;
    # which we're looking (regexp_pattern).&lt;br /&gt;
    line_number         = None&lt;br /&gt;
    startswith_string   = None&lt;br /&gt;
    regexp_pattern      = None&lt;br /&gt;
&lt;br /&gt;
    # The string that delimits the line containing our data.  This will be&lt;br /&gt;
    # used as the parameter to split().  Note that you can leave this as&lt;br /&gt;
    # None to split on whitespace.&lt;br /&gt;
    split_string        = None&lt;br /&gt;
&lt;br /&gt;
    # A mapping of data names to indices in the split string.&lt;br /&gt;
    name_index_map      = {}&lt;br /&gt;
&lt;br /&gt;
    def __init__(self, file, cmd, line, swstr, pat, splstr, map):&lt;br /&gt;
        self.data_source_file    = file&lt;br /&gt;
        self.shell_command       = cmd&lt;br /&gt;
        self.line_number         = line&lt;br /&gt;
        self.startswith_string   = swstr&lt;br /&gt;
        self.regexp_pattern      = pat&lt;br /&gt;
        self.split_string        = splstr&lt;br /&gt;
        self.name_index_map      = map&lt;br /&gt;
&lt;br /&gt;
    def printMembers(self):&lt;br /&gt;
        print &amp;quot;\t&amp;quot; + 'self.data_source_file = ' + str(self.data_source_file)&lt;br /&gt;
        print &amp;quot;\t&amp;quot; + 'self.shell_command = ' + str(self.shell_command)&lt;br /&gt;
        print &amp;quot;\t&amp;quot; + 'self.line_number = ' + str(self.line_number)&lt;br /&gt;
        print &amp;quot;\t&amp;quot; + 'self.startswith_string = ' + str(self.startswith_string)&lt;br /&gt;
        print &amp;quot;\t&amp;quot; + 'self.regexp_pattern = ' + str(self.regexp_pattern)&lt;br /&gt;
        print &amp;quot;\t&amp;quot; + 'self.split_string = ' + str(self.split_string)&lt;br /&gt;
        print &amp;quot;\t&amp;quot; + 'self.name_index_map = ' + str(self.name_index_map)&lt;br /&gt;
&lt;br /&gt;
    def readData(self, d):&lt;br /&gt;
        # open the data source file or run the command that will produce&lt;br /&gt;
        # the data&lt;br /&gt;
        file = None&lt;br /&gt;
        if self.data_source_file:&lt;br /&gt;
            file = open(self.data_source_file, 'r')&lt;br /&gt;
        elif self.shell_command:&lt;br /&gt;
            file = os.popen(self.shell_command)&lt;br /&gt;
        else:&lt;br /&gt;
            print 'error: no data source defined'&lt;br /&gt;
            self.printMembers()&lt;br /&gt;
        # read the contents of the file into a list and close the file&lt;br /&gt;
        lines = None&lt;br /&gt;
        if file:&lt;br /&gt;
            lines = file.readlines()&lt;br /&gt;
            file.close()&lt;br /&gt;
        else:&lt;br /&gt;
            print 'error: data file not opened'&lt;br /&gt;
            self.printMembers()&lt;br /&gt;
        # now get the line in the file with our data&lt;br /&gt;
        line = None&lt;br /&gt;
        if lines:&lt;br /&gt;
            if None != self.line_number:&lt;br /&gt;
                line = lines[self.line_number]&lt;br /&gt;
            elif self.startswith_string:&lt;br /&gt;
                for l in lines:&lt;br /&gt;
                    if l.startswith(self.startswith_string):&lt;br /&gt;
                        line = l&lt;br /&gt;
                        break&lt;br /&gt;
            elif self.regexp_pattern:&lt;br /&gt;
                for l in lines:&lt;br /&gt;
                    if re.compile(self.regexp_pattern).match(l):&lt;br /&gt;
                        line = l&lt;br /&gt;
                        break&lt;br /&gt;
        else:&lt;br /&gt;
            print 'error: no lines in data file'&lt;br /&gt;
            self.printMembers()&lt;br /&gt;
        # now get the data we want from the line itself&lt;br /&gt;
        if line:&lt;br /&gt;
            fields = line.split(self.split_string)&lt;br /&gt;
            for key, value in self.name_index_map.items():&lt;br /&gt;
                d[key] = fields[value].strip()&lt;br /&gt;
        else:&lt;br /&gt;
            print 'error: could not find line with data in file'&lt;br /&gt;
            self.printMembers()&lt;br /&gt;
&lt;br /&gt;
# END --- class tpPowerMonitorDataSource&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
tp_data_sources = [&lt;br /&gt;
&lt;br /&gt;
    tpPowerMonitorDataSource(&lt;br /&gt;
        '/proc/cpuinfo',             # data file&lt;br /&gt;
        None,                        # shell command&lt;br /&gt;
        None,                        # line index&lt;br /&gt;
        'cpu MHz',                   # startswith() string&lt;br /&gt;
        None,                        # regexp pattern&lt;br /&gt;
        ':',                         # split string&lt;br /&gt;
        {'proc_cpuinfo_cpu_mhz': 1}  # name-to-index map&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    # http://thinkwiki.org/wiki/Ipw2200#Power_Management&lt;br /&gt;
    tpPowerMonitorDataSource(&lt;br /&gt;
        None,                          # data file&lt;br /&gt;
        '/sbin/iwpriv eth1 get_power', # shell command&lt;br /&gt;
        0,                             # line index&lt;br /&gt;
        None,                          # startswith() string&lt;br /&gt;
        None,                          # regexp pattern&lt;br /&gt;
        ':',                           # split string&lt;br /&gt;
        {'iwpriv_get_power': 2}        # name-to-index map&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    # http://forums.gentoo.org/viewtopic-t-447841.html&lt;br /&gt;
    # see post from ruben on Wed Mar 29, 2006 4:09 am&lt;br /&gt;
    tpPowerMonitorDataSource(&lt;br /&gt;
        None,&lt;br /&gt;
        '/usr/bin/sudo /sbin/hdparm -C /dev/sda',&lt;br /&gt;
        None,&lt;br /&gt;
        ' drive state is',&lt;br /&gt;
        None,&lt;br /&gt;
        ':',&lt;br /&gt;
        {'hard_drive_power_state': 1}&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    # http://thinkwiki.org/wiki/Thermal_sensors&lt;br /&gt;
    tpPowerMonitorDataSource(&lt;br /&gt;
        '/proc/acpi/ibm/thermal',&lt;br /&gt;
        None,&lt;br /&gt;
        0,&lt;br /&gt;
        None,&lt;br /&gt;
        None,&lt;br /&gt;
        None,&lt;br /&gt;
        {'ibm_thermal_cpu':     1,&lt;br /&gt;
         'ibm_thermal_hdaps':   2,&lt;br /&gt;
         'ibm_thermal_pmcia':   3,&lt;br /&gt;
         'ibm_thermal_gpu':     4,&lt;br /&gt;
         'ibm_thermal_batt_fl': 5,&lt;br /&gt;
         'ibm_thermal_batt_br': 7 }&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    # http://mailman.linux-thinkpad.org/pipermail/linux-thinkpad/2006-July/034738.html&lt;br /&gt;
    tpPowerMonitorDataSource(&lt;br /&gt;
        '/proc/acpi/processor/CPU/power',&lt;br /&gt;
        None,&lt;br /&gt;
        None,&lt;br /&gt;
        'bus master activity',&lt;br /&gt;
        None,&lt;br /&gt;
        ':',&lt;br /&gt;
        {'bus_master_activity': 1}&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    tpPowerMonitorDataSource(&lt;br /&gt;
        '/proc/acpi/battery/BAT0/state',&lt;br /&gt;
        None,&lt;br /&gt;
        None,&lt;br /&gt;
        'present rate:',&lt;br /&gt;
        None,&lt;br /&gt;
        None,&lt;br /&gt;
        {'battery0_state_present_rate': 2}&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    tpPowerMonitorDataSource(&lt;br /&gt;
        None,&lt;br /&gt;
        '/usr/bin/sudo /usr/sbin/radeontool dac',&lt;br /&gt;
        0,&lt;br /&gt;
        None,&lt;br /&gt;
        None,&lt;br /&gt;
        None,&lt;br /&gt;
        {'radeontool_dac_ext_vga': -1}&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    tpPowerMonitorDataSource(&lt;br /&gt;
        None,&lt;br /&gt;
        '/usr/bin/sudo /usr/sbin/radeontool light',&lt;br /&gt;
        0,&lt;br /&gt;
        None,&lt;br /&gt;
        None,&lt;br /&gt;
        None,&lt;br /&gt;
        {'radeontool_light_lcd': -1}&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    # http://forums.gentoo.org/viewtopic-t-343029-highlight-rovclock.html&lt;br /&gt;
    tpPowerMonitorDataSource(&lt;br /&gt;
        None,&lt;br /&gt;
        '/usr/bin/sudo /usr/sbin/rovclock -i',&lt;br /&gt;
        None,&lt;br /&gt;
        'Core: ',&lt;br /&gt;
        None,&lt;br /&gt;
        None,&lt;br /&gt;
        {'rovclock_gpu_clock': 1,&lt;br /&gt;
         'rovclock_mem_clock': 4 }&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    tpPowerMonitorDataSource(&lt;br /&gt;
        None,&lt;br /&gt;
        '/sbin/iwconfig eth1',&lt;br /&gt;
        None,&lt;br /&gt;
        None,&lt;br /&gt;
        '.*Power Management.*',&lt;br /&gt;
        ':',&lt;br /&gt;
        {'wireless_power_mgmt_state': 1}&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    tpPowerMonitorDataSource(&lt;br /&gt;
        '/proc/loadavg',&lt;br /&gt;
        None,&lt;br /&gt;
        0,&lt;br /&gt;
        None,&lt;br /&gt;
        None,&lt;br /&gt;
        None,&lt;br /&gt;
        {'proc_loadavg_1min': 0,&lt;br /&gt;
         'proc_loadavg_5min': 1,&lt;br /&gt;
         'proc_loadavg_15min': 2 }&lt;br /&gt;
    ),&lt;br /&gt;
]&lt;br /&gt;
log_data = list()&lt;br /&gt;
poll_freq_hz = 1&lt;br /&gt;
run_time_sec = 60*60&lt;br /&gt;
logfile = None&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def collectPowerData():&lt;br /&gt;
    global run_time_sec&lt;br /&gt;
    global poll_freq_hz&lt;br /&gt;
    global log_data&lt;br /&gt;
    global logfile&lt;br /&gt;
    global tp_data_sources&lt;br /&gt;
&lt;br /&gt;
    log = None&lt;br /&gt;
    if logfile:&lt;br /&gt;
        log = open(logfile, 'w')&lt;br /&gt;
        log.write(&amp;quot;time, data\n&amp;quot;)&lt;br /&gt;
    end_t = time.time()+run_time_sec&lt;br /&gt;
    while time.time() &amp;lt; end_t:&lt;br /&gt;
        datum = {}&lt;br /&gt;
        for dsrc in tp_data_sources:&lt;br /&gt;
            dsrc.readData(datum)&lt;br /&gt;
        log_data.append(datum)&lt;br /&gt;
        if log: log.write(str(time.time()) + ', ' + str(datum) + &amp;quot;\n&amp;quot;)&lt;br /&gt;
        time.sleep(1.0/float(poll_freq_hz))&lt;br /&gt;
    if log: log.close()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def createStats():&lt;br /&gt;
    global log_data&lt;br /&gt;
    global logfile&lt;br /&gt;
    log = None&lt;br /&gt;
    if logfile:&lt;br /&gt;
        log = open(logfile, 'a')&lt;br /&gt;
    if log: log.close()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def usage():&lt;br /&gt;
    print 'Usage: ' + sys.argv[0] + \&lt;br /&gt;
        '[-h] [-f freq_hz] [-t time_min] [-l logfile]'&lt;br /&gt;
    print &amp;quot;\t-h            Display this help&amp;quot;&lt;br /&gt;
    print &amp;quot;\t-f freq_hz    The polling frequency in Hertz, default=&amp;quot; \&lt;br /&gt;
        + str(poll_freq_hz)&lt;br /&gt;
    print &amp;quot;\t-t time_min   Total poll time in minutes, default=&amp;quot; \&lt;br /&gt;
        + str(run_time_sec/60)&lt;br /&gt;
    print &amp;quot;\t-l logfile    Write poll data to indicated log file&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    global poll_freq_hz&lt;br /&gt;
    global run_time_sec&lt;br /&gt;
    global logfile&lt;br /&gt;
&lt;br /&gt;
    # parse options&lt;br /&gt;
    # see: http://docs.python.org/lib/module-getopt.html&lt;br /&gt;
    try:&lt;br /&gt;
        opts, args = getopt.getopt(sys.argv[1:], &amp;quot;hf:t:l:&amp;quot;)&lt;br /&gt;
    except getopt.GetoptError:&lt;br /&gt;
        usage()&lt;br /&gt;
        sys.exit(2)&lt;br /&gt;
    for o, a in opts:&lt;br /&gt;
        if '-h' == o:&lt;br /&gt;
            usage()&lt;br /&gt;
            sys.exit()&lt;br /&gt;
        if '-f' == o:&lt;br /&gt;
            poll_freq_hz = int(a)&lt;br /&gt;
        if '-t' == o:&lt;br /&gt;
            run_time_sec = int(a)*60&lt;br /&gt;
        if '-l' == o:&lt;br /&gt;
            logfile = a&lt;br /&gt;
&lt;br /&gt;
    # do stuff&lt;br /&gt;
    print 'running for ' + str(run_time_sec/60) + ' minutes'&lt;br /&gt;
    print 'poll rate:  ' + str(poll_freq_hz) + ' Hz'&lt;br /&gt;
    print 'logfile:    ' + str(logfile)&lt;br /&gt;
    collectPowerData()&lt;br /&gt;
    print '...done!'&lt;br /&gt;
    print 'Data points collected: ' + str(len(log_data))&lt;br /&gt;
    sum = 0&lt;br /&gt;
    for d in log_data:&lt;br /&gt;
        sum += int(d['battery0_state_present_rate'])&lt;br /&gt;
    avg = float(sum) / float(len(log_data))&lt;br /&gt;
    print 'Average power draw:    ' + str(avg)&lt;br /&gt;
    if logfile:     log = open(logfile, 'a')&lt;br /&gt;
    if log:&lt;br /&gt;
        log.write('Average power draw:    ' + str(avg))&lt;br /&gt;
        log.close()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Newacct</name></author>
		
	</entry>
	<entry>
		<id>https://www.thinkwiki.org/w/index.php?title=Code/tp-theft&amp;diff=49370</id>
		<title>Code/tp-theft</title>
		<link rel="alternate" type="text/html" href="https://www.thinkwiki.org/w/index.php?title=Code/tp-theft&amp;diff=49370"/>
		<updated>2010-08-14T19:23:31Z</updated>

		<summary type="html">&lt;p&gt;Newacct: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
#&lt;br /&gt;
# tp-theft v0.5.1&lt;br /&gt;
# (http://thinkwiki.org/wiki/Script_for_theft_alarm_using_HDAPS)&lt;br /&gt;
&lt;br /&gt;
# Provided under the GNU General Public License version 2 or later or&lt;br /&gt;
# the GNU Free Documentation License version 1.2 or later, at your option.&lt;br /&gt;
# See http://www.gnu.org/copyleft/gpl.html for the Warranty Disclaimer.&lt;br /&gt;
&lt;br /&gt;
# This script uses the HDAPS accelerometer found on recent ThinkPad models&lt;br /&gt;
# to emit an audio alarm when the laptop is tilted. In sufficiently&lt;br /&gt;
# populated environments, it can be used as a laptop theft deterrent.&lt;br /&gt;
# Uses a state machine and some heuristics to reduce false alarms.&lt;br /&gt;
#&lt;br /&gt;
# By default the alarm will be activated only when the KDE screen saver is&lt;br /&gt;
# locked. If you you open the laptop lid (or press the lid button) shortly&lt;br /&gt;
# before or after the beginning of movement, the alarm will be suspended&lt;br /&gt;
# (except for a brief warning) and you will get a few seconds of grace to &lt;br /&gt;
# unlock the screen saver. You can disable this functionality by passing &lt;br /&gt;
# the &amp;quot;--arm&amp;quot; parameter, or by setting  $use_kde=0 and $use_lid=0.&lt;br /&gt;
#&lt;br /&gt;
# There is also an option to track a BlueTooth device (e.g., a mobile phone).&lt;br /&gt;
# In this case, the alarm is activated (and optionally, the KDE desktop is &lt;br /&gt;
# locked) whenever the device is turned off or too distant for a given period,&lt;br /&gt;
# and deactivated when the BlueTooth device is nearby. You need to provide the&lt;br /&gt;
# device's BD address. If both KDE screen saver and BlueTooth checking are&lt;br /&gt;
# enabled, then the alarm will be activated when *either* the screensaver&lt;br /&gt;
# is enabled or the BlueTooth device is amiss.&lt;br /&gt;
#&lt;br /&gt;
# To control the sound and blinkenlights, and adjust the alarm activation &lt;br /&gt;
# parameters, see the variables below.&lt;br /&gt;
&lt;br /&gt;
use strict;&lt;br /&gt;
use warnings;&lt;br /&gt;
use FileHandle;&lt;br /&gt;
use IO::Pipe;&lt;br /&gt;
use Time::HiRes qw(sleep time);&lt;br /&gt;
use POSIX qw(:errno_h :signal_h);&lt;br /&gt;
&lt;br /&gt;
##############################&lt;br /&gt;
# Siren volume and content&lt;br /&gt;
&lt;br /&gt;
# Alarm audio volume (0..100)&lt;br /&gt;
my $alarm_volume = 70;&lt;br /&gt;
# Alarm command (default: synthesize a siren for 1.0 seconds):&lt;br /&gt;
my $alarm_cmd = &amp;quot;sox -t nul /dev/null -t wav -s -w -c2 -r48000 -t raw - synth 1.0 sine 2000-4000 sine 4000-2000 | aplay -q -fS16_LE -c2 -r48000&amp;quot;;&lt;br /&gt;
# my $alarm_cmd = &amp;quot;aplay keep_your_hands_off_me.wav&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
# Warning audio volume (0..100)&lt;br /&gt;
my $warn_volume = 45;&lt;br /&gt;
# Alarm command (default: synthesize a biref siren):&lt;br /&gt;
my $warn_cmd = &amp;quot;sox -t nul /dev/null -t wav -s -w -c2 -r48000 -t raw - synth 0.10 sine 2000-4000 sine 4000-2000 | aplay -q -fS16_LE -c2 -r48000&amp;quot;;&lt;br /&gt;
# my $warn_cmd = &amp;quot;aplay warning.wav&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
# Set ibm_acpi volume (0..15), if ibm_acpi is loaded with &amp;quot;experimental=1&amp;quot;.&lt;br /&gt;
# Combining $acpi_volume=15 and $alarm_volume=100 makes the alarm &lt;br /&gt;
# dangerously loud.&lt;br /&gt;
my $acpi_volume = 10;&lt;br /&gt;
&lt;br /&gt;
# Blink system LEDs when alarm activated?&lt;br /&gt;
my $use_led = 'safe';  # 0=off, 'safe'=only LEDs whose state you can recover, 'all'=pretty blinkenlights!&lt;br /&gt;
&lt;br /&gt;
# Blink ThinkLight when alarm activated?&lt;br /&gt;
my $use_light = 0;  # 0=off, 1=on&lt;br /&gt;
&lt;br /&gt;
##############################&lt;br /&gt;
# Activation control&lt;br /&gt;
&lt;br /&gt;
# Tilt threshold (increase value to decrease sensitivity):&lt;br /&gt;
my $thresh = 0.20;&lt;br /&gt;
# Minimum movement duration between warning and alarm:&lt;br /&gt;
my $min_hold = 1.3;&lt;br /&gt;
# When armed, any movement triggers alarm. How long should it remain armed?&lt;br /&gt;
my $arm_persist = 6;&lt;br /&gt;
&lt;br /&gt;
# After this many seconds of no movement, will allow a grace period again:&lt;br /&gt;
my $grace_relax = 15;&lt;br /&gt;
&lt;br /&gt;
# Activate according to KDE screen saver? Otherwise, always active:&lt;br /&gt;
my $use_kde = 1;&lt;br /&gt;
# When screen saver locked, wait this long before activation:&lt;br /&gt;
my $kde_lock_delay =  8;&lt;br /&gt;
&lt;br /&gt;
# Provide grace period if laptop lid is opened?&lt;br /&gt;
my $use_lid = 1;&lt;br /&gt;
# Opening a lid will grant this many seconds of grace (once):&lt;br /&gt;
my $lid_grace = 7;&lt;br /&gt;
# Lid must to be opened within this time to hold/pause alarm:&lt;br /&gt;
my $lid_grace_window = 8;&lt;br /&gt;
# Alarm will hold off this long when grace is available:&lt;br /&gt;
my $lid_hold = 3;&lt;br /&gt;
&lt;br /&gt;
# Control arming according by presence of a BlueTooth token&lt;br /&gt;
my $use_bluetooth = 0;&lt;br /&gt;
# Lock KDE screen saver when BlueTootk is not present?&lt;br /&gt;
my $bluetooth_lock_kde = 1;&lt;br /&gt;
# BD address of BlueTooth token (use &amp;quot;hcitool scan&amp;quot; to find this)&lt;br /&gt;
my $bluetooth_token_addr = '00:00:00:00:00:00';&lt;br /&gt;
# Consider token amiss when its received signal leve is below this (see &amp;quot;hcitool rssi&amp;quot;)&lt;br /&gt;
my $bluetooth_min_rssi = -10;&lt;br /&gt;
# Activate if BlueTooth token not seen this long:&lt;br /&gt;
my $bluetooth_activate_period = 12;&lt;br /&gt;
# Disactivate if BlueTooth token seen this recently:&lt;br /&gt;
my $bluetooth_deactivate_period = 5;&lt;br /&gt;
# If BlueTooth detection activated KDE lock, don't do it again for this long&lt;br /&gt;
my $bluetooth_lock_kde_interval = 30;&lt;br /&gt;
# If BlueTooth wasn't polled for this long, disregard recent history&lt;br /&gt;
my $bluetooth_reset_period = 10; &lt;br /&gt;
&lt;br /&gt;
##############################&lt;br /&gt;
# Other setup vars&lt;br /&gt;
&lt;br /&gt;
my $interval = 0.1;  # sampling intervalm in seconds&lt;br /&gt;
my $depth = 10;      # number of recent samples to analyze&lt;br /&gt;
my $verbose = 2;     # 0=nothing, 1=alarms, 2=state transitions, 3=everything&lt;br /&gt;
my $kde_check_interval = 1.5; # KDE screen saver check is expensive&lt;br /&gt;
my $bluetooth_sleep = 1;       # Sleep interval in BlueTooth check loop&lt;br /&gt;
&lt;br /&gt;
my $pos_file = '/sys/devices/platform/hdaps/position';&lt;br /&gt;
my $lid_file = '/proc/acpi/button/lid/LID/state';&lt;br /&gt;
my $led_file = '/proc/acpi/ibm/led';&lt;br /&gt;
my $light_file = '/proc/acpi/ibm/light';&lt;br /&gt;
my $bay_file = '/proc/acpi/ibm/bay';&lt;br /&gt;
my $volume_file = '/proc/acpi/ibm/volume'; # load ibm_acpi with experimental=1&lt;br /&gt;
my $bluetooth_file = '/proc/acpi/ibm/bluetooth'; # load ibm_acpi with experimental=1&lt;br /&gt;
&lt;br /&gt;
my $alsactl = '/usr/sbin/alsactl';&lt;br /&gt;
my $amixer = 'amixer';&lt;br /&gt;
my $kdesktop_lock = '/usr/bin/kdesktop_lock';&lt;br /&gt;
my $hcitool = '/usr/bin/hcitool';&lt;br /&gt;
my $l2ping = '/usr/bin/l2ping';&lt;br /&gt;
&lt;br /&gt;
##############################&lt;br /&gt;
# Utility functions&lt;br /&gt;
&lt;br /&gt;
sub say {&lt;br /&gt;
    my ($verb, $what) = @_;&lt;br /&gt;
    print(gmtime().&amp;quot;: $what\n&amp;quot;) if $verb&amp;lt;=$verbose;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub slurp { # read whole file&lt;br /&gt;
    my ($filename) = @_;&lt;br /&gt;
    local $/;&lt;br /&gt;
    my $fh = new FileHandle($filename,&amp;quot;&amp;lt;&amp;quot;) or return;&lt;br /&gt;
    return &amp;lt;$fh&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub burp { # write whole file&lt;br /&gt;
    my ($filename) = shift;&lt;br /&gt;
    my $fh = new FileHandle($filename,&amp;quot;&amp;gt;&amp;quot;) or die &amp;quot;Can't open $filename for writing: $!&amp;quot;;&lt;br /&gt;
    print $fh @_ or die &amp;quot;Can't write to $filename: $!&amp;quot;;&lt;br /&gt;
    close $fh or die &amp;quot;Can't close $filename after writing: $!&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub stddev { # standard deviation of list&lt;br /&gt;
    my $sum=0;&lt;br /&gt;
    my $sumsq=0;&lt;br /&gt;
    my $n=$#_+1;&lt;br /&gt;
    for my $v (@_) {&lt;br /&gt;
        $sum += $v;&lt;br /&gt;
        $sumsq += $v*$v;&lt;br /&gt;
    }&lt;br /&gt;
    return sqrt($n*$sumsq - $sum*$sum)/($n*($n-1));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub frac {&lt;br /&gt;
    my ($x) = @_;&lt;br /&gt;
    return $x-int($x);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub max {&lt;br /&gt;
    return $_[0] &amp;gt; $_[1] ? $_[0] : $_[1];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
my $alarm_file; # flags ongoing alarm (and also stores saved mixer settings)&lt;br /&gt;
&lt;br /&gt;
sub sound_alarm {&lt;br /&gt;
    # Sound alarm. Forks bash code which sets given volumes, runs the given&lt;br /&gt;
    # command, and then restores the given volumes to their saved values.&lt;br /&gt;
    my ($name, $volume, $acpi_volume, $cmd) = @_;&lt;br /&gt;
    return if (defined($alarm_file) &amp;amp;&amp;amp; -f $alarm_file);&lt;br /&gt;
    say(1,$name);&lt;br /&gt;
    $alarm_file = `mktemp /tmp/tp-theft-tmp.XXXXXXXX` or die &amp;quot;mktemp: $?&amp;quot;;&lt;br /&gt;
    chomp($alarm_file);&lt;br /&gt;
    my ($acpi_vol_file, $acpi_vol_set, $acpi_vol_restore);&lt;br /&gt;
    if ($_=slurp($volume_file) and m/^level:\s+(\d+)\n/) {&lt;br /&gt;
        $acpi_vol_file = $volume_file; &lt;br /&gt;
        $acpi_vol_set = &amp;quot;level $acpi_volume&amp;quot;; &lt;br /&gt;
        $acpi_vol_restore = &amp;quot;level $1&amp;quot;; &lt;br /&gt;
        if (m/^mute:\s+on$/m) {&lt;br /&gt;
          $acpi_vol_set = &amp;quot;up,&amp;quot;.$acpi_vol_set; # unmute first&lt;br /&gt;
          $acpi_vol_restore .= &amp;quot;,mute&amp;quot;;         # mute last&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        $acpi_vol_file='/dev/null'; $acpi_vol_set=''; $acpi_vol_restore='';&lt;br /&gt;
    }&lt;br /&gt;
    system('/bin/bash', '-c', &amp;lt;&amp;lt;&amp;quot;EOF&amp;quot;)==0 or die &amp;quot;Failed: $?&amp;quot;;&lt;br /&gt;
( trap \&amp;quot;echo '$acpi_vol_restore' &amp;gt; $acpi_vol_file; sleep 0.1;&lt;br /&gt;
         $alsactl -f $alarm_file restore;&lt;br /&gt;
         rm -f $alarm_file&lt;br /&gt;
       \&amp;quot; EXIT HUP QUIT TERM&lt;br /&gt;
  $alsactl -f $alarm_file store &amp;amp;&amp;amp;                         # store ALSA&lt;br /&gt;
  echo '$acpi_vol_set' &amp;gt; $acpi_vol_file &amp;amp;&amp;amp; sleep 0.1 &amp;amp;&amp;amp;    # set ACPI&lt;br /&gt;
  $amixer -q set Master $volume% unmute &amp;amp;&amp;amp;                 # set ALSA Master&lt;br /&gt;
  $amixer -q set PCM 100% unmute &amp;amp;&amp;amp;                        # set alsa PCM&lt;br /&gt;
  $cmd ) &amp;amp;                                                 # invoke command&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################&lt;br /&gt;
# KDE screen saver lock check&lt;br /&gt;
&lt;br /&gt;
if ($use_kde) { # Basic sanity check&lt;br /&gt;
    `/sbin/pidof kdesktop`; $?==0 or die &amp;quot;Can't use KDE, it's not running.\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub kdesktop_lock_status {&lt;br /&gt;
    # See if kdesktop_lock is running and check its cmdline and automatic lock delay&lt;br /&gt;
    my $bin = $kdesktop_lock;&lt;br /&gt;
    my $pids = `/sbin/pidof $bin`;&lt;br /&gt;
    return 'off' unless $?==0;&lt;br /&gt;
    for my $pid (split(/\s+/,$pids)) {&lt;br /&gt;
        next unless $pid =~ m/^\d+$/;&lt;br /&gt;
        # Attached to display &amp;quot;:0&amp;quot; or &amp;quot;localhost:0&amp;quot;?&lt;br /&gt;
        my $environ = slurp(&amp;quot;/proc/$pid/environ&amp;quot;) or next;&lt;br /&gt;
        my $good=0; my $home;&lt;br /&gt;
        for (split(/\x00/,$environ)) { &lt;br /&gt;
            $good=1 if m/^DISPLAY=(localhost)?:0$/; &lt;br /&gt;
            $home=$1 if m/^HOME=(.+)$/;  # also remember its $HOME&lt;br /&gt;
        }&lt;br /&gt;
        next unless $good;&lt;br /&gt;
        # Check command line&lt;br /&gt;
        my $cmdline = slurp(&amp;quot;/proc/$pid/cmdline&amp;quot;) or next;&lt;br /&gt;
        $cmdline =~ m/^[^\x00]+\x00(?:([^\x00]+)\x00)?/ or die &amp;quot;Cannot parse $bin command line\n&amp;quot;;&lt;br /&gt;
        if (!defined($1)) {&lt;br /&gt;
            # Read KDE screensaver lock time&lt;br /&gt;
            defined($home) or die &amp;quot;Cannot find HOME in environment of $bin process&amp;quot;;&lt;br /&gt;
            my $rc_path = &amp;quot;$home/.kde/share/config/kdesktoprc&amp;quot;;&lt;br /&gt;
            my $rc = new FileHandle($rc_path,&amp;quot;&amp;lt;&amp;quot;) or die &amp;quot;Error opening $rc_path: $!&amp;quot;;&lt;br /&gt;
            while (&amp;lt;$rc&amp;gt;) { m/^LockGrace=(\d+)$/ and return ('auto', $1/1000.0); };&lt;br /&gt;
            die &amp;quot;Cannot parse $rc_path&amp;quot;;&lt;br /&gt;
        } elsif ($1 eq '--forcelock') {&lt;br /&gt;
            return &amp;quot;force&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return 'off';&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
my $last_kls_update = 0; # time of last update&lt;br /&gt;
my $last_kls = 'init';   # last state seen&lt;br /&gt;
my $last_kls_start;      # when that state started&lt;br /&gt;
my @last_kls_opwhy = ();&lt;br /&gt;
&lt;br /&gt;
sub check_kde_lock {&lt;br /&gt;
    # De/activate according to KDE screen saver:&lt;br /&gt;
    my $now=time();&lt;br /&gt;
    return @last_kls_opwhy if $now &amp;lt; $last_kls_update + $kde_check_interval;&lt;br /&gt;
    my ($kls, $auto_delay) = kdesktop_lock_status();&lt;br /&gt;
    $last_kls_update = time();&lt;br /&gt;
    if ($kls ne $last_kls) {&lt;br /&gt;
        $last_kls = $kls;&lt;br /&gt;
        $last_kls_start = $now;&lt;br /&gt;
    }&lt;br /&gt;
    if ($kls eq 'off') { # no screen saver&lt;br /&gt;
        @last_kls_opwhy = (0, 'KDE screen saver not locked');&lt;br /&gt;
    } elsif ($kls eq 'auto') { # screen saver with automatic lock&lt;br /&gt;
        if ($now &amp;gt;= $last_kls_start + $auto_delay + $kde_lock_delay) {&lt;br /&gt;
            @last_kls_opwhy = (1, 'KDE screen saver is auto-locked');&lt;br /&gt;
        }&lt;br /&gt;
    } elsif ($kls eq 'force') { # screen saver with forced lock&lt;br /&gt;
        if ($now &amp;gt;= $last_kls_start + $kde_lock_delay) {&lt;br /&gt;
            @last_kls_opwhy = (1, 'KDE screen saver is forced-locked');&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return @last_kls_opwhy;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Lock KDE desktop&lt;br /&gt;
sub force_kde_lock {&lt;br /&gt;
    return if ($last_kls eq 'auto' or $last_kls eq 'force');&lt;br /&gt;
    say(1, &amp;quot;Locking KDE desktop&amp;quot;);&lt;br /&gt;
    # system('dcop kdesktop KScreensaverIface lock') or die &amp;quot;Cannot lock KDE dekstop: $!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    my %oldENV = %ENV;&lt;br /&gt;
    my $kde_pids = `/sbin/pidof -x /usr/bin/startkde`;&lt;br /&gt;
    for my $kde_pid (split(/\s+/,$kde_pids)) {&lt;br /&gt;
        my $kde_env = slurp(&amp;quot;/proc/$kde_pid/environ&amp;quot;) or next;&lt;br /&gt;
        %ENV = ();&lt;br /&gt;
        for (split(/\x00/,$kde_env)) {&lt;br /&gt;
            m/^(DISPLAY|HOME|XAUTHORITY|USER|DBUS_SESSION_BUS_ADDRESS)=(.+)$/&lt;br /&gt;
                and $ENV{$1} = $2;&lt;br /&gt;
        }&lt;br /&gt;
        next unless defined($ENV{DISPLAY}) and $ENV{DISPLAY} =~ m/^:/;&lt;br /&gt;
        system('dcop kdesktop KScreensaverIface lock') and die &amp;quot;Cannot lock KDE dekstop: $!&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
    my %ENV = %oldENV;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
##############################&lt;br /&gt;
# Lid checking&lt;br /&gt;
&lt;br /&gt;
if ($use_lid) { # sanity check&lt;br /&gt;
    slurp($lid_file) or die &amp;quot;Can't use lid via $lid_file: $!&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
my $last_lid_status = 'open';&lt;br /&gt;
my $last_lid_open = 0;&lt;br /&gt;
&lt;br /&gt;
sub check_lid {&lt;br /&gt;
    my $lid = slurp($lid_file) or return;&lt;br /&gt;
    if ($lid =~ m/state: *open$/) {&lt;br /&gt;
        $last_lid_open = time() if ($last_lid_status eq 'closed');&lt;br /&gt;
        $last_lid_status = 'open';&lt;br /&gt;
    } else {&lt;br /&gt;
        $last_lid_status = 'closed';&lt;br /&gt;
    }&lt;br /&gt;
    return $last_lid_status;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################&lt;br /&gt;
# LED blinking&lt;br /&gt;
&lt;br /&gt;
# Flash LEDs&lt;br /&gt;
sub led_activate {&lt;br /&gt;
    return if $use_led eq '0';&lt;br /&gt;
    my $ledf = new FileHandle($led_file,&amp;quot;&amp;gt;&amp;quot;);&lt;br /&gt;
    if (!defined($ledf)) {&lt;br /&gt;
        print &amp;quot;Cannot open $led_file, disabling LED indicator: $!\n&amp;quot;;&lt;br /&gt;
        $use_led = '0';&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    $ledf-&amp;gt;autoflush(1);&lt;br /&gt;
    my $base = time()*2.5;&lt;br /&gt;
    print $ledf '0 '.((frac($base)&amp;gt;0.7)?'on':'off').&amp;quot;\n&amp;quot;; # power&lt;br /&gt;
    if ($use_led eq 'all') { # battery -- we can't recover these&lt;br /&gt;
        print $ledf '1 '.((frac($base+0.50)&amp;gt;0.7)?'on':'off').&amp;quot;\n&amp;quot;; # battery, orange&lt;br /&gt;
        print $ledf '2 '.((frac($base+0.25)&amp;gt;0.7)?'on':'off').&amp;quot;\n&amp;quot;; # battery, yellow&lt;br /&gt;
    }&lt;br /&gt;
    print $ledf '4 '.((frac($base)&amp;gt;0.7)?'on':'off').&amp;quot;\n&amp;quot;; # bay&lt;br /&gt;
    print $ledf '7 '.((frac($base+0.725)&amp;gt;0.7)?'on':'off').&amp;quot;\n&amp;quot;; # standby&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Restore LEDs to normal state&lt;br /&gt;
sub led_restore {&lt;br /&gt;
    return if $use_led eq '0';&lt;br /&gt;
    my $ledf = new FileHandle($led_file,&amp;quot;&amp;gt;&amp;quot;) or die &amp;quot;Cannot open $led_file: $!\n&amp;quot;;&lt;br /&gt;
    $ledf-&amp;gt;autoflush(1);&lt;br /&gt;
    print $ledf &amp;quot;0 on\n&amp;quot;; # power=on&lt;br /&gt;
    if ($use_led eq 'all') { # battery -- we can't recover these&lt;br /&gt;
        print $ledf &amp;quot;1 on\n&amp;quot;;&lt;br /&gt;
        print $ledf &amp;quot;2 on\n&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    print $ledf &amp;quot;7 off\n&amp;quot;; # power=off&lt;br /&gt;
    if (my $baydata = slurp($bay_file)) {&lt;br /&gt;
        my $is_bay = ($baydata =~ m/^status:\s*occupied$/m)?'on':'off';&lt;br /&gt;
        print $ledf &amp;quot;4 $is_bay\n&amp;quot;; # reset to correct status&lt;br /&gt;
    } else {&lt;br /&gt;
        print $ledf &amp;quot;4 on\n&amp;quot;; # force bay on, we don't know correct status&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################&lt;br /&gt;
# ThinkLight blinking&lt;br /&gt;
&lt;br /&gt;
sub light_activate {&lt;br /&gt;
    return if $use_light eq '0';&lt;br /&gt;
    my $lightf = new FileHandle($light_file,&amp;quot;&amp;gt;&amp;quot;);&lt;br /&gt;
    if (!defined($lightf)) {&lt;br /&gt;
        print &amp;quot;Cannot open $light_file, disabling ThinkLight indicator: $!\n&amp;quot;;&lt;br /&gt;
        $use_light = '0';&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    my $base = time()/2;&lt;br /&gt;
    print $lightf (check_lid() eq 'open' &amp;amp;&amp;amp; ((frac($base)&amp;lt;0.1)?'on':'off')).&amp;quot;\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub light_restore {&lt;br /&gt;
    return if $use_light eq '0';&lt;br /&gt;
    my $lightf = new FileHandle($light_file,&amp;quot;&amp;gt;&amp;quot;) or die &amp;quot;Cannot open $light_file: $!\n&amp;quot;;&lt;br /&gt;
    print $lightf &amp;quot;off\n&amp;quot;; # ThinkLight&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
##############################&lt;br /&gt;
# BlueTooth token detection&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
    my $temporary_bt = 0;&lt;br /&gt;
    my $bt_pid;&lt;br /&gt;
    my $bt_pipe;&lt;br /&gt;
    my $bluetooth_last_seen = 0; # last time we saw the BlueTooth token&lt;br /&gt;
    my $bluetooth_last_read = 0;   # last time we polled the BlueTooth child process&lt;br /&gt;
    my $bluetooth_ignore_missing_until = time() + $bluetooth_reset_period; &lt;br /&gt;
&lt;br /&gt;
    if ($use_bluetooth) {&lt;br /&gt;
        # If BlueTooth is disabled, temporarily enable it&lt;br /&gt;
        slurp($bluetooth_file) or die &amp;quot;Can't control bluetooth via $bluetooth_file: $!&amp;quot;;&lt;br /&gt;
        my $bt_status = slurp($bluetooth_file);&lt;br /&gt;
        $temporary_bt = $bt_status =~ m/status:[\t]*disabled/;&lt;br /&gt;
        if ($temporary_bt) {&lt;br /&gt;
            say(1, 'BlueTooth was disabled, enabling');&lt;br /&gt;
            burp($bluetooth_file, &amp;quot;enable\n&amp;quot;);&lt;br /&gt;
            sleep(1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    sub bluetooth_reset {  # disregard recent (negative) history&lt;br /&gt;
        $bluetooth_ignore_missing_until = max($bluetooth_ignore_missing_until, time() + $bluetooth_reset_period);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    sub check_bluetooth {&lt;br /&gt;
        if (!defined($bt_pid)) {&lt;br /&gt;
            # Create new child process, which will loop checking&lt;br /&gt;
            # for the token. Each time it sees the token, it writes&lt;br /&gt;
            # the current time to a pipe that's read by the main process.&lt;br /&gt;
            $bt_pipe = new IO::Pipe;&lt;br /&gt;
            $bt_pid = fork();&lt;br /&gt;
            die &amp;quot;Cannot fork BlueTooth check: $!&amp;quot; unless defined($bt_pid);&lt;br /&gt;
            if (!$bt_pid) {&lt;br /&gt;
                # Child&lt;br /&gt;
                $bt_pipe-&amp;gt;writer();&lt;br /&gt;
                $bt_pipe-&amp;gt;autoflush(1);&lt;br /&gt;
                open(STDOUT, &amp;quot;&amp;gt;/dev/null&amp;quot;);&lt;br /&gt;
                open(STDERR, &amp;quot;&amp;gt;/dev/null&amp;quot;);&lt;br /&gt;
                while(1) {&lt;br /&gt;
                    # Is the BlueTooth token reachable?&lt;br /&gt;
                    my $res = system($l2ping,'-c','1','-t',1,$bluetooth_token_addr);&lt;br /&gt;
                    die &amp;quot;Failed invoking l2ping: $!\n&amp;quot; if $res&amp;amp;0xFF;&lt;br /&gt;
                    if ($res==0) {&lt;br /&gt;
                       # Is the BlueTooth sufficiently close, as judged by signal strength?&lt;br /&gt;
                       $res = `$hcitool rssi $bluetooth_token_addr`;&lt;br /&gt;
                       if ($?==0 &amp;amp;&amp;amp; $res =~ m/^RSSI return value: (-?[0-9]+)$/) {&lt;br /&gt;
                           my $rssi = $1;&lt;br /&gt;
                           printf $bt_pipe &amp;quot;%d\n&amp;quot;, time() if ($rssi &amp;gt; $bluetooth_min_rssi);&lt;br /&gt;
                       }&lt;br /&gt;
                    }&lt;br /&gt;
                    sleep($bluetooth_sleep);&lt;br /&gt;
                }&lt;br /&gt;
             }&lt;br /&gt;
             $bt_pipe-&amp;gt;reader();&lt;br /&gt;
             $bt_pipe-&amp;gt;blocking(0);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        while (1) { &lt;br /&gt;
            my $res = &amp;lt;$bt_pipe&amp;gt;;&lt;br /&gt;
            last if ($!==POSIX::EAGAIN); # busy&lt;br /&gt;
            die &amp;quot;Error reading from BlueTooth check child process\n&amp;quot; unless defined($res);&lt;br /&gt;
            $bluetooth_last_seen = $res;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        my $now = time();&lt;br /&gt;
        bluetooth_reset() if ($now &amp;gt; $bluetooth_last_read + $bluetooth_reset_period);&lt;br /&gt;
        $bluetooth_last_read = time();&lt;br /&gt;
        if ($now &amp;gt; max($bluetooth_last_seen + $bluetooth_activate_period, $bluetooth_ignore_missing_until)) {&lt;br /&gt;
            if ($bluetooth_lock_kde) {&lt;br /&gt;
                force_kde_lock();&lt;br /&gt;
                $bluetooth_ignore_missing_until = max($bluetooth_ignore_missing_until, time() + $bluetooth_lock_kde_interval);&lt;br /&gt;
            }&lt;br /&gt;
            return (1, &amp;quot;BlueTooth token not seen for $bluetooth_activate_period seconds, activating.&amp;quot;);&lt;br /&gt;
        } elsif ($now &amp;lt; $bluetooth_last_seen + $bluetooth_deactivate_period) {&lt;br /&gt;
            return (0, &amp;quot;BlueTooth token seen during last $bluetooth_deactivate_period seconds, deactivating.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        return ();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    sub bluetooth_restore {&lt;br /&gt;
        if ($temporary_bt) {&lt;br /&gt;
            say(1, 'Disabling BlueTooth');&lt;br /&gt;
            burp($bluetooth_file, &amp;quot;disable\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        if ($bt_pid) {&lt;br /&gt;
            kill(SIGTERM, $bt_pid);&lt;br /&gt;
            waitpid($bt_pid, 0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
##############################&lt;br /&gt;
# Main code&lt;br /&gt;
&lt;br /&gt;
my $state;       # See state machine in main loop&lt;br /&gt;
my %state_names=(0  =&amp;gt;'disabled    ',&lt;br /&gt;
                 0.5=&amp;gt;'activating  ',&lt;br /&gt;
                 1  =&amp;gt;'active+grace',&lt;br /&gt;
                 2  =&amp;gt;'active      ',&lt;br /&gt;
                 3  =&amp;gt;'hold+grace  ',&lt;br /&gt;
                 4  =&amp;gt;'armed+grace ',&lt;br /&gt;
                 5  =&amp;gt;'hold        ',&lt;br /&gt;
                 6  =&amp;gt;'armed       ',&lt;br /&gt;
                 7  =&amp;gt;'armed-force '  );&lt;br /&gt;
my $state_end = 0; &lt;br /&gt;
my $last_tilt = 0;&lt;br /&gt;
my $arm_forced = 0;&lt;br /&gt;
my (@XHIST, @YHIST); # sensor history&lt;br /&gt;
&lt;br /&gt;
sub set_state {&lt;br /&gt;
    my ($st,  $why) = @_;&lt;br /&gt;
    say(2, &amp;quot;state=[&amp;quot;.$state_names{$st}.&amp;quot;]  ($why)&amp;quot;);&lt;br /&gt;
    (@XHIST, @YHIST) = () if $st==0.5;&lt;br /&gt;
    led_restore() and light_restore() if defined($state) &amp;amp;&amp;amp; $st==0;&lt;br /&gt;
    $state = $st;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub get_pos {&lt;br /&gt;
    my $pos = slurp($pos_file);&lt;br /&gt;
    return undef if $!{EBUSY};&lt;br /&gt;
    die &amp;quot;Can't open HDAPS file $pos_file: $!\n&amp;quot; if (!defined($pos) || $!);&lt;br /&gt;
    $pos =~ m/^\((-?\d+),(-?\d+)\)$/ or die &amp;quot;Can't parse $pos_file content\n&amp;quot;;&lt;br /&gt;
    return ($1,$2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
for (@ARGV) {&lt;br /&gt;
    m/^--arm/ &amp;amp;&amp;amp; do { $arm_forced=1; $use_lid=0; $use_kde=0; last; };&lt;br /&gt;
    die &amp;quot;Unknown parameter\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
set_state( ($use_kde || $use_bluetooth)  ? 0 : 0.5, &amp;quot;init&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
eval {&lt;br /&gt;
&lt;br /&gt;
$SIG{'HUP'}=$SIG{'INT'}=$SIG{'ABRT'}=$SIG{'QUIT'}=$SIG{'SEGV'}=$SIG{'TERM'} = sub { die &amp;quot;signal\n&amp;quot; };&lt;br /&gt;
&lt;br /&gt;
while (1) {&lt;br /&gt;
    sleep(($state==0 &amp;amp;&amp;amp; $use_kde) ? $kde_check_interval : $interval);&lt;br /&gt;
&lt;br /&gt;
    check_lid() if $use_lid;&lt;br /&gt;
    # Check screensaver and BlueTooth. Activate if either says so,&lt;br /&gt;
    # otherwise deactivate if either says so.&lt;br /&gt;
    my ($op1, $why1); ($op1, $why1) = check_kde_lock() if $use_kde;&lt;br /&gt;
    my ($op2, $why2); ($op2, $why2) = check_bluetooth() if $use_bluetooth;&lt;br /&gt;
    my ($op, $why) = ( !defined($op1) || ( defined($op2) &amp;amp;&amp;amp; $op2&amp;gt;$op1 ) ) ? ($op2,$why2) : ($op1,$why1);&lt;br /&gt;
    if (defined($op)) {&lt;br /&gt;
        if ($op==1 &amp;amp;&amp;amp; $state==0) { set_state(0.5, $why); }&lt;br /&gt;
        if ($op==0 &amp;amp;&amp;amp; $state&amp;gt;0) { set_state(0, $why); bluetooth_reset(); }&lt;br /&gt;
    }&lt;br /&gt;
    next unless $state&amp;gt;0;&lt;br /&gt;
&lt;br /&gt;
    # Collect and analyze sensor data:&lt;br /&gt;
    my $now = time();&lt;br /&gt;
    my $tilted;&lt;br /&gt;
    my ($x,$y) = get_pos() or next; # Hopefully the error is transient&lt;br /&gt;
    push(@XHIST,$x); push(@YHIST,$y);&lt;br /&gt;
    if ($state&amp;gt;0.5) {&lt;br /&gt;
        shift(@XHIST); shift(@YHIST);&lt;br /&gt;
        my $xdev = stddev(@XHIST);&lt;br /&gt;
        my $ydev = stddev(@YHIST);&lt;br /&gt;
        say(3,&amp;quot;X: v=$xdev (&amp;quot;.join(',',@XHIST).&amp;quot;)  Y: v=$ydev (&amp;quot;.join(&amp;quot;,&amp;quot;,@YHIST).&amp;quot;)&amp;quot;);&lt;br /&gt;
        $tilted = ($xdev&amp;gt;$thresh || $ydev&amp;gt;$thresh);&lt;br /&gt;
        $last_tilt = $now if $tilted;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    # Decide: state machine transitions&lt;br /&gt;
    if ($state==0.5) { # ACTIVATING  (collecting motion data will soon activate)&lt;br /&gt;
        if ($#XHIST &amp;gt;= $depth &amp;amp;&amp;amp; $#YHIST &amp;gt;= $depth) {&lt;br /&gt;
            set_state($arm_forced?7:$use_lid?1:2, &amp;quot;finished data collection&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    } elsif ($state==1) { # ACTIVE+GRACE  (quiet for a long time, awaiting movement)&lt;br /&gt;
        if ($tilted) {&lt;br /&gt;
            set_state(3, &amp;quot;motion detected, holding for $lid_hold seconds, open lid for grace&amp;quot;);&lt;br /&gt;
            $state_end = $now + $lid_hold;&lt;br /&gt;
            sound_alarm(&amp;quot;WARNING&amp;quot;, $warn_volume, $acpi_volume, $warn_cmd);&lt;br /&gt;
        }&lt;br /&gt;
    } elsif ($state==2) { # ACTIVE  (short for a shorter time, awaiting movement)&lt;br /&gt;
        if ($tilted) {&lt;br /&gt;
            set_state(5, &amp;quot;motion detected, holding for $min_hold seconds&amp;quot;);&lt;br /&gt;
            $state_end = $now + $min_hold;&lt;br /&gt;
            sound_alarm(&amp;quot;WARNING&amp;quot;, $warn_volume, $acpi_volume, $warn_cmd);&lt;br /&gt;
        } else {&lt;br /&gt;
            if ($use_lid &amp;amp;&amp;amp; ($now &amp;gt; $last_tilt + $grace_relax )) { &lt;br /&gt;
                set_state(1, &amp;quot;$grace_relax seconds since last motion, so allowing grace again&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    } elsif ($state==3) { # HOLD+GRACE  (recent movemvent, but still holding off alarm; after long quiet)&lt;br /&gt;
        if ($now &amp;lt; $last_lid_open + $lid_grace) {&lt;br /&gt;
            set_state(5, &amp;quot;lid opened, holding for $lid_grace seconds grace period&amp;quot;);&lt;br /&gt;
            $state_end = $now + $lid_grace;&lt;br /&gt;
        } elsif ($now &amp;gt;= $state_end) {&lt;br /&gt;
            my $delta = $lid_grace_window - $lid_hold;&lt;br /&gt;
            $state_end = $now + $delta;&lt;br /&gt;
            set_state(4, &amp;quot;hold ended, arming but allowing grace for $delta more seconds&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    } elsif ($state==4) { # ARMED+GRACE  (armed, but recently quiet so allow grace if lid opened)&lt;br /&gt;
        if ($now &amp;lt; $last_lid_open + $lid_grace) {&lt;br /&gt;
            set_state(5, &amp;quot;lid opened, holding for $lid_grace seconds grace period&amp;quot;);&lt;br /&gt;
            $state_end = $now + $lid_grace;&lt;br /&gt;
        } elsif ($now &amp;gt;= $state_end) {&lt;br /&gt;
            set_state(6, &amp;quot;grace window ended&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    } elsif ($state==5) { # HOLD  (recent movement, but still holding off alarm; there was recent action)&lt;br /&gt;
        if ($now &amp;gt;= $state_end) {&lt;br /&gt;
            set_state(6, &amp;quot;hold ended, arming&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    } elsif ($state==6) { # ARMED  (sound alarm on any movement)&lt;br /&gt;
        if ($now &amp;gt; $last_tilt + $arm_persist) {&lt;br /&gt;
            set_state(2, &amp;quot;no motion for $arm_persist seconds, unarming&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    # LEDs:&lt;br /&gt;
    if ($state&amp;gt;0) {&lt;br /&gt;
        led_activate(); light_activate();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    # Alarm:&lt;br /&gt;
    if (($state==4 || $state==6 || $state==7) &amp;amp;&amp;amp; $tilted) {&lt;br /&gt;
        sound_alarm(&amp;quot;ALARM&amp;quot;, $alarm_volume, $acpi_volume, $alarm_cmd);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Shutting down.\n&amp;quot; if $verbose&amp;gt;1;&lt;br /&gt;
led_restore() and light_restore() if ($state&amp;gt;0);&lt;br /&gt;
bluetooth_restore();&lt;br /&gt;
die &amp;quot;$@&amp;quot; if $@;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Newacct</name></author>
		
	</entry>
	<entry>
		<id>https://www.thinkwiki.org/w/index.php?title=Sample_Fn-F7_script&amp;diff=49303</id>
		<title>Sample Fn-F7 script</title>
		<link rel="alternate" type="text/html" href="https://www.thinkwiki.org/w/index.php?title=Sample_Fn-F7_script&amp;diff=49303"/>
		<updated>2010-08-08T15:44:13Z</updated>

		<summary type="html">&lt;p&gt;Newacct: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide will help you configure Fn-F7 key combination to toggle between internal, mirror, external, or both screens.  This was tested on ThinkPad X60s running Fedora 8, please comment if it works or does not work for you.&lt;br /&gt;
&lt;br /&gt;
Works like a charm on X61s with Xubuntu 7.10.&lt;br /&gt;
Working with R60e with some modifications noted below.&lt;br /&gt;
&lt;br /&gt;
The script does not work when using [[fglrx]] or a version of XRandR &amp;lt; 1.2, because there is no dynamic display switching support then. When fglrx is used, aticonfig can be used for the switching in this [[Script for Dynamic Display Management with fglrx]].&lt;br /&gt;
&lt;br /&gt;
{{NOTE|On a modern distribution like Fedora 12, the Fn-F7 key works out-of-the-box, and no additional scripts are needed to switch between external display modes}}&lt;br /&gt;
&lt;br /&gt;
==configuring the virtual screen size==&lt;br /&gt;
Add a &amp;quot;Virtual&amp;quot; statement to your /etc/X11/xorg.conf, the total resolution should be large enough to fit all your screens in the configuration you want, for example if you have 1600x1200 monitor to the left of your internal 1024x768 monitor, your total max resolution is 2624x1200 (See [[Xorg RandR 1.2]] for more details):&lt;br /&gt;
&lt;br /&gt;
 Section &amp;quot;Screen&amp;quot;&lt;br /&gt;
        Identifier &amp;quot;Screen0&amp;quot;&lt;br /&gt;
        Device     &amp;quot;Videocard0&amp;quot;&lt;br /&gt;
        DefaultDepth     24&lt;br /&gt;
         SubSection &amp;quot;Display&amp;quot;&lt;br /&gt;
                Viewport   0 0&lt;br /&gt;
                Depth     24&lt;br /&gt;
                &amp;lt;b&amp;gt;Virtual   2624 1200&amp;lt;/b&amp;gt;&lt;br /&gt;
        EndSubSection&lt;br /&gt;
 EndSection&lt;br /&gt;
&lt;br /&gt;
Restart X server at this point (i.e. logout and login).&lt;br /&gt;
&lt;br /&gt;
== configuring acpi ==&lt;br /&gt;
Create /etc/acpi/events/thinkpad.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bash&amp;gt;&lt;br /&gt;
event=ibm/hotkey HKEY 00000080 00001007&lt;br /&gt;
action=/usr/local/sbin/thinkpad-fn-f7&lt;br /&gt;
&amp;lt;/bash&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you may (eg Ubuntu 7.10) already have /etc/acpi/events/ibm-videobtn&lt;br /&gt;
&amp;lt;bash&amp;gt;&lt;br /&gt;
# /etc/acpi/events/ibm-videobtn&lt;br /&gt;
# This is called when the user presses the video button. It is currently&lt;br /&gt;
# a placeholder.&lt;br /&gt;
event=ibm/hotkey HKEY 00000080 00001007&lt;br /&gt;
action=/bin/true&lt;br /&gt;
&amp;lt;/bash&amp;gt;&lt;br /&gt;
in which case modify the line 'action=/bin/true' to run the script as above.&lt;br /&gt;
&lt;br /&gt;
It may also be necessary to enable acpi events as per [[How to get special keys to work]] with (in root terminal)&lt;br /&gt;
{{cmdroot|echo enable,0x084e &amp;gt; /proc/acpi/ibm/hotkey}}&lt;br /&gt;
Note this command isn't persistent. so you will also need to add the line to /etc/rc.local to enable hotkeys at boot, and to re-enable the hotkeys after suspend to disk or RAM, create the file&lt;br /&gt;
/etc/acpi/resume.d/91-ibm-hotkey-enable.sh consisting of&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bash&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# enable ibm-hotkeys (specifically Fn2, Fn7)&lt;br /&gt;
# 12 bit mask, little end is F1 default 0x080c = F12+F4+F3&lt;br /&gt;
echo enable,0x084e &amp;gt; /proc/acpi/ibm/hotkey&lt;br /&gt;
&amp;lt;/bash&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: [[http://tilmanfrosch.de/wp/index.php/2007/05/05/howto-make-a-ubuntu-linux-on-an-ibm-t41-thinkpad-work-with-an-external-widescreen-wxga-display/  frosch.org.uk]] and [[http://ibm-acpi.sourceforge.net/README ibm-acpi.sourceforge]]&lt;br /&gt;
&lt;br /&gt;
==identify output devices==&lt;br /&gt;
Note the names of your output devices as you will have to change EXTERNAL_OUTPUT and INTERNAL_OUTPUT to what xrandr shows, for example VGA and LVDS in this case:&lt;br /&gt;
&lt;br /&gt;
 $ xrandr -q&lt;br /&gt;
 '''VGA''' connected 1600x1200+0+0 (normal left inverted right x axis y axis) 432mm x 324mm&lt;br /&gt;
 ...&lt;br /&gt;
 '''LVDS''' connected (normal left inverted right x axis y axis)&lt;br /&gt;
&lt;br /&gt;
==The bash script==&lt;br /&gt;
Create /usr/local/sbin/thinkpad-fn-f7, you can set EXTERNAL_LOCATION to one of: left, right, above, or below.&lt;br /&gt;
&amp;lt;bash&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
# External output may be &amp;quot;VGA&amp;quot; or &amp;quot;VGA-0&amp;quot; or &amp;quot;DVI-0&amp;quot; or &amp;quot;TMDS-1&amp;quot;&lt;br /&gt;
EXTERNAL_OUTPUT=&amp;quot;VGA&amp;quot;&lt;br /&gt;
INTERNAL_OUTPUT=&amp;quot;LVDS&amp;quot;&lt;br /&gt;
EXTERNAL_LOCATION=&amp;quot;left&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Figure out which user and X11 display to work on&lt;br /&gt;
# TODO there has to be a better way to do this?&lt;br /&gt;
X_USER=$(w -h -s | grep &amp;quot;:[0-9]\W&amp;quot; | head -1 | awk '{print $1}')&lt;br /&gt;
export DISPLAY=$(w -h -s | grep &amp;quot;:[0-9]\W&amp;quot; | head -1 | awk '{print $3}')&lt;br /&gt;
&lt;br /&gt;
# Switch to X user if necessary&lt;br /&gt;
if [ &amp;quot;$X_USER&amp;quot; != &amp;quot;$USER&amp;quot; ]; then&lt;br /&gt;
       SU=&amp;quot;su $X_USER -c&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
       SU=&amp;quot;sh -c&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$EXTERNAL_LOCATION&amp;quot; in&lt;br /&gt;
       left|LEFT)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--left-of $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       right|RIGHT)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--right-of $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       top|TOP|above|ABOVE)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--above $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       bottom|BOTTOM|below|BELOW)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--below $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       *)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--left-of $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
# Figure out current state&lt;br /&gt;
INTERNAL_STATE=$($SU xrandr | grep ^$INTERNAL_OUTPUT | grep &amp;quot; con&amp;quot; | sed &amp;quot;s/.*connected//&amp;quot; | sed &amp;quot;s/ //&amp;quot; | sed &amp;quot;s/ .*//g&amp;quot;)&lt;br /&gt;
EXTERNAL_STATE=$($SU xrandr | grep ^$EXTERNAL_OUTPUT | grep &amp;quot; con&amp;quot; | sed &amp;quot;s/.*connected//&amp;quot; | sed &amp;quot;s/ //&amp;quot; | sed &amp;quot;s/ .*//g&amp;quot;)&lt;br /&gt;
# I recommend to replace these prior two statements, since otherwise with  xrandr 1.2 it produces wrong results:&lt;br /&gt;
# a textportion &amp;quot;(normal&amp;quot; otherwise still remains when a screen is connected, but switched off (by e.g. toggling!)&lt;br /&gt;
# (comment out the prior two lines, and uncomment the following two lines:)&lt;br /&gt;
# INTERNAL_STATE=$($SU xrandr | grep ^$INTERNAL_OUTPUT | grep &amp;quot; con&amp;quot; | sed &amp;quot;s/.*connected//&amp;quot; | sed &amp;quot;s/ //&amp;quot; | sed &amp;quot;s/ .*//g&amp;quot;| sed &amp;quot;s/(normal//g&amp;quot; )&lt;br /&gt;
# EXTERNAL_STATE=$($SU xrandr | grep ^$EXTERNAL_OUTPUT | grep &amp;quot; con&amp;quot; | sed &amp;quot;s/.*connected//&amp;quot; | sed &amp;quot;s/ //&amp;quot; | sed &amp;quot;s/ .*//g&amp;quot;| sed &amp;quot;s/(normal//g&amp;quot; )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if [ -z &amp;quot;$INTERNAL_STATE&amp;quot; ]; then&lt;br /&gt;
       STATE=&amp;quot;external&amp;quot;&lt;br /&gt;
elif [ -z &amp;quot;$EXTERNAL_STATE&amp;quot; ]; then&lt;br /&gt;
       STATE=&amp;quot;internal&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
       INTERNAL_STATE=$(echo $INTERNAL_STATE | sed &amp;quot;s/[0-9]*x[0-9]*//&amp;quot;)&lt;br /&gt;
       EXTERNAL_STATE=$(echo $EXTERNAL_STATE | sed &amp;quot;s/[0-9]*x[0-9]*//&amp;quot;)&lt;br /&gt;
       if [ &amp;quot;$INTERNAL_STATE&amp;quot; = &amp;quot;$EXTERNAL_STATE&amp;quot; ]; then&lt;br /&gt;
               STATE=&amp;quot;mirror&amp;quot;&lt;br /&gt;
       else&lt;br /&gt;
               STATE=&amp;quot;both&amp;quot;&lt;br /&gt;
       fi&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
function screen_external(){&lt;br /&gt;
# recommend exchange the order, since otherwise doesn't work&lt;br /&gt;
# with my ati adapter (please uncomment if needed, and&lt;br /&gt;
#comment out the other two):&lt;br /&gt;
#       $SU &amp;quot;xrandr --output $EXTERNAL_OUTPUT --auto&amp;quot;&lt;br /&gt;
#       $SU &amp;quot;xrandr --output $INTERNAL_OUTPUT --off&amp;quot;&lt;br /&gt;
       $SU &amp;quot;xrandr --output $INTERNAL_OUTPUT --off&amp;quot;&lt;br /&gt;
       $SU &amp;quot;xrandr --output $EXTERNAL_OUTPUT --auto&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_internal(){&lt;br /&gt;
       $SU &amp;quot;xrandr --output $EXTERNAL_OUTPUT --off&amp;quot;&lt;br /&gt;
       $SU &amp;quot;xrandr --output $INTERNAL_OUTPUT --auto&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_mirror(){&lt;br /&gt;
       $SU &amp;quot;xrandr --output $INTERNAL_OUTPUT --auto&amp;quot;&lt;br /&gt;
       $SU &amp;quot;xrandr --output $EXTERNAL_OUTPUT --auto --same-as $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_both(){&lt;br /&gt;
       $SU &amp;quot;xrandr --output $INTERNAL_OUTPUT --auto&amp;quot;&lt;br /&gt;
       $SU &amp;quot;xrandr --output $EXTERNAL_OUTPUT --auto $EXTERNAL_LOCATION&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_toggle(){&lt;br /&gt;
       case &amp;quot;$STATE&amp;quot; in&lt;br /&gt;
               internal)&lt;br /&gt;
                       screen_mirror&lt;br /&gt;
                       ;;&lt;br /&gt;
               mirror)&lt;br /&gt;
                       screen_external&lt;br /&gt;
                       ;;&lt;br /&gt;
               external)&lt;br /&gt;
                       screen_both&lt;br /&gt;
                       ;;&lt;br /&gt;
               both)&lt;br /&gt;
                       screen_internal&lt;br /&gt;
                       ;;&lt;br /&gt;
               *)&lt;br /&gt;
                       screen_internal&lt;br /&gt;
                       ;;&lt;br /&gt;
       esac&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# What should we do?&lt;br /&gt;
DO=&amp;quot;$1&amp;quot;&lt;br /&gt;
if [ -z &amp;quot;$DO&amp;quot; ]; then&lt;br /&gt;
       if [ $(basename $0) = &amp;quot;thinkpad-fn-f7&amp;quot; ]; then&lt;br /&gt;
               DO=&amp;quot;toggle&amp;quot;&lt;br /&gt;
       fi&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$DO&amp;quot; in&lt;br /&gt;
       toggle)&lt;br /&gt;
               screen_toggle&lt;br /&gt;
               ;;&lt;br /&gt;
       internal)&lt;br /&gt;
               screen_internal&lt;br /&gt;
               ;;&lt;br /&gt;
       external)&lt;br /&gt;
               screen_external&lt;br /&gt;
               ;;&lt;br /&gt;
       mirror)&lt;br /&gt;
               screen_mirror&lt;br /&gt;
               ;;&lt;br /&gt;
       both)&lt;br /&gt;
               screen_both&lt;br /&gt;
               ;;&lt;br /&gt;
       status)&lt;br /&gt;
               echo &amp;quot;Current Fn-F7 state is: $STATE&amp;quot;&lt;br /&gt;
               echo&lt;br /&gt;
               echo &amp;quot;Attached monitors:&amp;quot;&lt;br /&gt;
               $SU xrandr | grep &amp;quot;\Wconnected&amp;quot; | sed &amp;quot;s/^/ /&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       *)&lt;br /&gt;
               echo &amp;quot;usage: $0 &amp;lt;command&amp;gt;&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;quot;  commands:&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;quot;          status&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;quot;          internal&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;quot;          external&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;quot;          mirror&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;quot;          both&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;quot;          toggle&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;gt;&amp;amp;2&lt;br /&gt;
               ;;&lt;br /&gt;
esac&lt;br /&gt;
&amp;lt;/bash&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== set permissions and restart acpi ==&lt;br /&gt;
As root, or using sudo run the following commands,&lt;br /&gt;
&lt;br /&gt;
 {{cmduser|sudo chmod 755 /usr/local/sbin/thinkpad-fn-f7}}&lt;br /&gt;
 {{cmduser|sudo service acpid restart}}&lt;br /&gt;
 OR&lt;br /&gt;
 {{cmduser|sudo /etc/init.d/acpid restart}}&lt;br /&gt;
&lt;br /&gt;
You should be ready to go, just press Fn-F7 to try.&lt;br /&gt;
&lt;br /&gt;
==Alternative script using .Xauthority rather than su ==&lt;br /&gt;
On systems where the previous script has trouble with the &amp;quot;su&amp;quot; command (I was getting &amp;quot;Can't open display -&amp;quot; errors in /var/log/acpid on Ubuntu 8.04), you can try getting the magic cookie out of the .Xauthority file.&lt;br /&gt;
&lt;br /&gt;
Each user has an ~/.Xauthority file with one line for each X display containing a 'magic cookie' (Run {{cmduser| xauth list}} to see the contents).  The Xserver reads the record in  ~/.Xauthority matching its display. When an X client application starts it also looks for that record and passes the magic cookie to the server. If it matches, the connection to the Xserver is allowed. Use the following script as an alternative &lt;br /&gt;
 action=/usr/local/sbin/toggle-display.sh&lt;br /&gt;
for /etc/acpi/events/ibm-videobtn&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bash&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# From: http://www.thinkwiki.org/wiki/Sample_Fn-F7_script&lt;br /&gt;
#&lt;br /&gt;
# External output may be &amp;quot;VGA&amp;quot; or &amp;quot;VGA-0&amp;quot; or &amp;quot;DVI-0&amp;quot; or &amp;quot;TMDS-1&amp;quot;&lt;br /&gt;
EXTERNAL_OUTPUT=&amp;quot;VGA&amp;quot;&lt;br /&gt;
INTERNAL_OUTPUT=&amp;quot;LVDS&amp;quot;&lt;br /&gt;
# EXTERNAL_LOCATION may be one of: left, right, above, or below&lt;br /&gt;
EXTERNAL_LOCATION=&amp;quot;right&amp;quot;&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$EXTERNAL_LOCATION&amp;quot; in&lt;br /&gt;
       left|LEFT)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--left-of $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       right|RIGHT)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--right-of $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       top|TOP|above|ABOVE)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--above $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       bottom|BOTTOM|below|BELOW)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--below $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       *)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--left-of $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
function screen_external(){&lt;br /&gt;
       xrandr --output $INTERNAL_OUTPUT --off&lt;br /&gt;
       xrandr --output $EXTERNAL_OUTPUT --auto&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_internal(){&lt;br /&gt;
       xrandr --output $EXTERNAL_OUTPUT --off&lt;br /&gt;
       xrandr --output $INTERNAL_OUTPUT --auto&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_mirror(){&lt;br /&gt;
       xrandr --output $INTERNAL_OUTPUT --auto&lt;br /&gt;
       xrandr --output $EXTERNAL_OUTPUT --auto --same-as $INTERNAL_OUTPUT&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_both(){&lt;br /&gt;
       xrandr --output $INTERNAL_OUTPUT --auto&lt;br /&gt;
       xrandr --output $EXTERNAL_OUTPUT --auto $EXTERNAL_LOCATION&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_toggle(){&lt;br /&gt;
       # Figure out current state&lt;br /&gt;
       INTERNAL_STATE=$(xrandr | grep ^$INTERNAL_OUTPUT | grep con | sed &amp;quot;s/.*connected //&amp;quot; | sed &amp;quot;s/(.*//&amp;quot;)&lt;br /&gt;
       EXTERNAL_STATE=$(xrandr | grep ^$EXTERNAL_OUTPUT | grep con | sed &amp;quot;s/.*connected //&amp;quot; | sed &amp;quot;s/(.*//&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
       if [ -z &amp;quot;$INTERNAL_STATE&amp;quot; ]; then&lt;br /&gt;
         STATE=&amp;quot;external&amp;quot;&lt;br /&gt;
       elif [ -z &amp;quot;$EXTERNAL_STATE&amp;quot; ]; then&lt;br /&gt;
         STATE=&amp;quot;internal&amp;quot;&lt;br /&gt;
       else&lt;br /&gt;
         INTERNAL_STATE=$(echo $INTERNAL_STATE | sed &amp;quot;s/[0-9]*x[0-9]*//&amp;quot;)&lt;br /&gt;
         EXTERNAL_STATE=$(echo $EXTERNAL_STATE | sed &amp;quot;s/[0-9]*x[0-9]*//&amp;quot;)&lt;br /&gt;
         if [ &amp;quot;$INTERNAL_STATE&amp;quot; = &amp;quot;$EXTERNAL_STATE&amp;quot; ]; then&lt;br /&gt;
           STATE=&amp;quot;mirror&amp;quot;&lt;br /&gt;
         else&lt;br /&gt;
           STATE=&amp;quot;both&amp;quot;&lt;br /&gt;
         fi&lt;br /&gt;
       fi&lt;br /&gt;
&lt;br /&gt;
       case &amp;quot;$STATE&amp;quot; in&lt;br /&gt;
               internal)&lt;br /&gt;
                       screen_mirror&lt;br /&gt;
                       ;;&lt;br /&gt;
               mirror)&lt;br /&gt;
                       screen_external&lt;br /&gt;
                       ;;&lt;br /&gt;
               external)&lt;br /&gt;
                       screen_both&lt;br /&gt;
                       ;;&lt;br /&gt;
               both)&lt;br /&gt;
                       screen_internal&lt;br /&gt;
                       ;;&lt;br /&gt;
               *)&lt;br /&gt;
                       screen_internal&lt;br /&gt;
                       ;;&lt;br /&gt;
       esac&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# based on /etc/acpi/screenblank.sh (Ubuntu 7.10)&lt;br /&gt;
# . /usr/share/acpi-support/power-funcs         # for getXuser&lt;br /&gt;
getXuser() {&lt;br /&gt;
       user=`finger| grep -m1 &amp;quot;:$displaynum &amp;quot; | awk '{print $1}'`&lt;br /&gt;
       if [ x&amp;quot;$user&amp;quot; = x&amp;quot;&amp;quot; ]; then&lt;br /&gt;
               user=`finger| grep -m1 &amp;quot;:$displaynum&amp;quot; | awk '{print $1}'`&lt;br /&gt;
       fi&lt;br /&gt;
       if [ x&amp;quot;$user&amp;quot; != x&amp;quot;&amp;quot; ]; then&lt;br /&gt;
               userhome=`getent passwd $user | cut -d: -f6`&lt;br /&gt;
               export XAUTHORITY=$userhome/.Xauthority&lt;br /&gt;
       else&lt;br /&gt;
               export XAUTHORITY=&amp;quot;&amp;quot;&lt;br /&gt;
       fi&lt;br /&gt;
}&lt;br /&gt;
# end of getXuser from /usr/share/acpi-support/power-funcs&lt;br /&gt;
#&lt;br /&gt;
for x in /tmp/.X11-unix/*; do&lt;br /&gt;
   displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`&lt;br /&gt;
   getXuser;&lt;br /&gt;
   if [ x&amp;quot;$XAUTHORITY&amp;quot; != x&amp;quot;&amp;quot; ]; then&lt;br /&gt;
       export DISPLAY=&amp;quot;:$displaynum&amp;quot;&lt;br /&gt;
      screen_toggle&lt;br /&gt;
   fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/bash&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script to switch between Internal, VGA and S-video==&lt;br /&gt;
This highly overdone script allows to switch between all combinations of Internal, VGA and S-video out. VGA and and S-video at the same time are not allowed on my hardware (I have a T41 with Radeon 7500), so I masked these combinations out. Instead of disabling the internal display with xrandr, I turn off the backlight. One of the allowed combinations is all displays off, and xorg crashes if turning off all displays with xrandr. The script depends on the debian package acpi-support, which is also found in ubuntu and crunchbang (which is what I am using). The dependency can easily be broken out though. Can easily be modified to fulfill other needs, i.e. if you turn off your backlight with something else than radeontool. There is also an OSD displayed in the upper left corner of all active displays.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bash&amp;gt;&lt;br /&gt;
#/bin/sh&lt;br /&gt;
&lt;br /&gt;
. /usr/share/acpi-support/power-funcs         # for getXuser&lt;br /&gt;
. /etc/default/acpi-support                   # for RADEON_LIGHT&lt;br /&gt;
&lt;br /&gt;
# First prevent concurrent execution&lt;br /&gt;
&lt;br /&gt;
LOCK_FILE=/tmp/swapscreenslock&lt;br /&gt;
WAITING_TIME=1&lt;br /&gt;
LOGGER=&amp;quot;`which logger 2&amp;gt;/dev/null` -i&amp;quot;&lt;br /&gt;
if (set -C; : &amp;gt; $LOCK_FILE) 2&amp;gt;/dev/null; then : ; else&lt;br /&gt;
    # Lock file exists - wait as long as theoretically is needed for the other script to finish and retry&lt;br /&gt;
    sleep $WAITING_TIME&lt;br /&gt;
    if (set -C; : &amp;gt; $LOCK_FILE) 2&amp;gt;/dev/null; then : ; else&lt;br /&gt;
        # Lock file still exists - we should never end up here! Consider removing the lock file.&lt;br /&gt;
        $LOGGER &amp;quot;Lock file exists - earlier call to script stalled? Consider removing lock file \&amp;quot;$LOCK_FILE\&amp;quot;. Exiting.&amp;quot;&lt;br /&gt;
        exit 1&lt;br /&gt;
    fi&lt;br /&gt;
fi&lt;br /&gt;
trap 'rm $LOCK_FILE' EXIT&lt;br /&gt;
&lt;br /&gt;
XRANDR=`which xrandr 2&amp;gt;/dev/null`&lt;br /&gt;
OSD_CAT=`which osd_cat 2&amp;gt;/dev/null`&lt;br /&gt;
LAPTOP=&amp;quot;LVDS&amp;quot;&lt;br /&gt;
VGA=&amp;quot;VGA-0&amp;quot;&lt;br /&gt;
SVIDEO=&amp;quot;S-video&amp;quot;&lt;br /&gt;
VGA_POSITION=&amp;quot;--right-of $LAPTOP&amp;quot;&lt;br /&gt;
#VGA_POSITION=&amp;quot;--same-as $LAPTOP&amp;quot;    # Mirror&lt;br /&gt;
SVIDEO_POSITION=&amp;quot;--right-of $LAPTOP&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OSD_GENERICARGS=&amp;quot;--delay=3 --age=0 --font=-adobe-helvetica-bold-r-normal-*-*-180-*-*-p-*-*-* --colour=green --shadow=1&amp;quot;&lt;br /&gt;
OSD_HOFFSET=25&lt;br /&gt;
OSD_VOFFSET=25&lt;br /&gt;
&lt;br /&gt;
function screen_toggle {&lt;br /&gt;
    # Figure out current state&lt;br /&gt;
    XRANDR_STATUS=`su $user -c &amp;quot;$XRANDR -q&amp;quot;`&lt;br /&gt;
&lt;br /&gt;
    # Laptop is of course always connected, however I'll leave the script this&lt;br /&gt;
    # way for making it easier to make the script a little more generic.&lt;br /&gt;
    LAPTOP_CONN=`echo &amp;quot;$XRANDR_STATUS&amp;quot; | grep ^$LAPTOP | grep &amp;quot; connected&amp;quot;`&lt;br /&gt;
    VGA_CONN=`echo &amp;quot;$XRANDR_STATUS&amp;quot; | grep ^$VGA | grep &amp;quot; connected&amp;quot;`&lt;br /&gt;
    SVIDEO_CONN=`echo &amp;quot;$XRANDR_STATUS&amp;quot; | grep ^$SVIDEO | grep &amp;quot; connected&amp;quot;`&lt;br /&gt;
&lt;br /&gt;
    LAPTOP_STATE=`radeontool light | grep 'looks on'`&lt;br /&gt;
    VGA_STATE=`echo $VGA_CONN | sed 's/.*connected\s\([0-9x+-]*\).*/\1/'`&lt;br /&gt;
    SVIDEO_STATE=`echo $SVIDEO_CONN | sed 's/.*connected\s\([0-9x+-]*\).*/\1/'`&lt;br /&gt;
&lt;br /&gt;
    CONNMASK=0&lt;br /&gt;
    [ -n &amp;quot;$LAPTOP_CONN&amp;quot; ] &amp;amp;&amp;amp; CONNMASK=$(( CONNMASK + 1 ))&lt;br /&gt;
    if [ -n &amp;quot;$VGA_CONN&amp;quot; ]; then &lt;br /&gt;
        CONNMASK=$(( CONNMASK + 2 ))&lt;br /&gt;
        [ -n &amp;quot;$SVIDEO_CONN&amp;quot; ] &amp;amp;&amp;amp; CONNMASK=$(( CONNMASK + 4 ))&lt;br /&gt;
    else&lt;br /&gt;
        # If VGA is not connected, TV will overtake its bit&lt;br /&gt;
        [ -n &amp;quot;$SVIDEO_CONN&amp;quot; ] &amp;amp;&amp;amp; CONNMASK=$(( CONNMASK + 2 ))&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    STATE=0&lt;br /&gt;
    if [ -n &amp;quot;$LAPTOP_STATE&amp;quot; ]; then STATE=$(( STATE + 1 )); fi&lt;br /&gt;
    if [ -n &amp;quot;$VGA_CONN&amp;quot; ]; then &lt;br /&gt;
        [ -n &amp;quot;$VGA_STATE&amp;quot; ] &amp;amp;&amp;amp; STATE=$(( STATE + 2 ))&lt;br /&gt;
        [ -n &amp;quot;$SVIDEO_STATE&amp;quot; ] &amp;amp;&amp;amp; STATE=$(( STATE + 4 ))&lt;br /&gt;
    else&lt;br /&gt;
        # If VGA is not connected, TV will overtake its bit&lt;br /&gt;
        [ -n &amp;quot;$SVIDEO_STATE&amp;quot; ] &amp;amp;&amp;amp; STATE=$(( STATE + 2 ))&lt;br /&gt;
    fi&lt;br /&gt;
  &lt;br /&gt;
    # Go to next state&lt;br /&gt;
    STATE=$(( (STATE+1) % (CONNMASK+1) ))&lt;br /&gt;
&lt;br /&gt;
    # Forbidden states are TV and VGA at the same time, regardless of internal state&lt;br /&gt;
    STATE=$(( STATE % 6 ))&lt;br /&gt;
&lt;br /&gt;
    # If no screen is listed as connected, probably xrandr failed - do nothing.&lt;br /&gt;
    if [ $CONNMASK -ne 0 ]; then&lt;br /&gt;
        OSDTEXT=&lt;br /&gt;
&lt;br /&gt;
        if [ -n &amp;quot;$VGA_CONN&amp;quot; ]; then &lt;br /&gt;
            # Turn on or off external VGA&lt;br /&gt;
            if [ $(( (STATE &amp;gt;&amp;gt; 1) % 2 )) -ne 0 ]; then &lt;br /&gt;
                OSDTEXT=&amp;quot;$OSDTEXT $VGA&amp;quot;&lt;br /&gt;
                su $user -c &amp;quot;$XRANDR --output $VGA $VGA_POSITION --auto&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                su $user -c &amp;quot;$XRANDR --output $VGA --off&amp;quot;&lt;br /&gt;
            fi&lt;br /&gt;
&lt;br /&gt;
            # Turn on or off S-Video output&lt;br /&gt;
            if [ $(( (STATE &amp;gt;&amp;gt; 2) % 2 )) -ne 0 ]; then &lt;br /&gt;
                OSDTEXT=&amp;quot;$OSDTEXT $SVIDEO&amp;quot;&lt;br /&gt;
                su $user -c &amp;quot;$XRANDR --output $SVIDEO $SVIDEO_POSITION --auto&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                [ -n &amp;quot;$SVIDEO_CONN&amp;quot; ] &amp;amp;&amp;amp; su $user -c &amp;quot;$XRANDR --output $SVIDEO --off&amp;quot;&lt;br /&gt;
            fi&lt;br /&gt;
        else&lt;br /&gt;
            # If VGA is not connected, TV will overtake its bit&lt;br /&gt;
&lt;br /&gt;
            # Turn on or off S-Video output&lt;br /&gt;
            if [ $(( (STATE &amp;gt;&amp;gt; 1) % 2 )) -ne 0 ]; then &lt;br /&gt;
                OSDTEXT=&amp;quot;$OSDTEXT $SVIDEO&amp;quot;&lt;br /&gt;
                su $user -c &amp;quot;$XRANDR --output $SVIDEO $SVIDEO_POSITION --auto&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                [ -n &amp;quot;$SVIDEO_CONN&amp;quot; ] &amp;amp;&amp;amp; su $user -c &amp;quot;$XRANDR --output $SVIDEO --off&amp;quot;&lt;br /&gt;
            fi&lt;br /&gt;
        fi&lt;br /&gt;
&lt;br /&gt;
        # Never turn on or off internal screen - only turn on or off the backlight.&lt;br /&gt;
        # Do this after the xrandr calls above, during which the backlight&lt;br /&gt;
        # might go on.&lt;br /&gt;
        if [ $(( STATE % 2 )) -ne 0 ]; then&lt;br /&gt;
            if pidof xscreensaver &amp;gt;/dev/null; then &lt;br /&gt;
                su $user -c &amp;quot;xscreensaver-command -unthrottle&amp;quot;&lt;br /&gt;
            fi  &lt;br /&gt;
            if [ x$RADEON_LIGHT = xtrue ]; then&lt;br /&gt;
                [ -x /usr/sbin/radeontool ] &amp;amp;&amp;amp; radeontool light on&lt;br /&gt;
            fi  &lt;br /&gt;
            if pidof xscreensaver &amp;gt;/dev/null; then&lt;br /&gt;
                su $user -c &amp;quot;xscreensaver-command -deactivate&amp;quot;&lt;br /&gt;
            fi  &lt;br /&gt;
            su $user -c &amp;quot;xset dpms force on&amp;quot;&lt;br /&gt;
            OSDTEXT=&amp;quot;$OSDTEXT $LAPTOP&amp;quot;&lt;br /&gt;
        else&lt;br /&gt;
            if [ `pidof xscreensaver` ]; then&lt;br /&gt;
                su $user -c &amp;quot;(xscreensaver-command -throttle)&amp;quot;&lt;br /&gt;
            fi&lt;br /&gt;
            # Not calling xset to turn off dpms prohibits key presses from&lt;br /&gt;
            # turning the backlight back on all the time. Do make sure to have&lt;br /&gt;
            # RADEON_LIGHT enabled though. The rest of the script works even&lt;br /&gt;
            # though RADEON_LIGHT left disabled, the only effect is that the&lt;br /&gt;
            # laptop panel will always be considered &amp;quot;on&amp;quot;.&lt;br /&gt;
            #su $user -c &amp;quot;xset dpms force off&amp;quot;&lt;br /&gt;
            if [ x$RADEON_LIGHT = xtrue ]; then&lt;br /&gt;
                [ -x /usr/sbin/radeontool ] &amp;amp;&amp;amp; radeontool light off&lt;br /&gt;
            fi&lt;br /&gt;
        fi&lt;br /&gt;
&lt;br /&gt;
        $LOGGER Currently active GPU outputs: $OSDTEXT&lt;br /&gt;
&lt;br /&gt;
        # Wait a little for the hardware to reach the new state&lt;br /&gt;
        #sleep $WAITING_TIME&lt;br /&gt;
&lt;br /&gt;
        # Figure out current state again, to put the OSD on the right places.&lt;br /&gt;
        XRANDR_STATUS=`su $user -c &amp;quot;$XRANDR -q&amp;quot;`&lt;br /&gt;
&lt;br /&gt;
        VGA_CONN=`echo &amp;quot;$XRANDR_STATUS&amp;quot; | grep ^$VGA | grep &amp;quot; connected&amp;quot;`&lt;br /&gt;
        SVIDEO_CONN=`echo &amp;quot;$XRANDR_STATUS&amp;quot; | grep ^$SVIDEO | grep &amp;quot; connected&amp;quot;`&lt;br /&gt;
&lt;br /&gt;
        VGA_STATE=`echo $VGA_CONN | sed 's/.*connected\s\([0-9x+-]*\).*/\1/'`&lt;br /&gt;
        SVIDEO_STATE=`echo $SVIDEO_CONN | sed 's/.*connected\s\([0-9x+-]*\).*/\1/'`&lt;br /&gt;
&lt;br /&gt;
        VGA_HOFFSET=$(( `echo $VGA_STATE | sed 's/[0-9x]*\([+-][0-9]*\).*/\1/'` + OSD_HOFFSET ))&lt;br /&gt;
        VGA_VOFFSET=$(( `echo $VGA_STATE | sed 's/[0-9x]*[+-][0-9]*\([+-][0-9]*\)/\1/'` + OSD_VOFFSET ))&lt;br /&gt;
        SVIDEO_HOFFSET=$(( `echo $SVIDEO_STATE | sed 's/[0-9x]*\([+-][0-9]*\).*/\1/'` + OSD_HOFFSET ))&lt;br /&gt;
        SVIDEO_VOFFSET=$(( `echo $SVIDEO_STATE | sed 's/[0-9x]*[+-][0-9]*\([+-][0-9]*\)/\1/'` + OSD_VOFFSET ))&lt;br /&gt;
&lt;br /&gt;
        # On screen display. &lt;br /&gt;
        if [ -n &amp;quot;$OSD_CAT&amp;quot; ] ; then &lt;br /&gt;
            su $user -c &amp;quot;echo $OSDTEXT | $OSD_CAT $OSD_GENERICARGS --offset=$OSD_HOFFSET --indent=$OSD_VOFFSET - &amp;amp;&amp;quot;&lt;br /&gt;
            [ -n &amp;quot;$VGA_CONN&amp;quot; ] &amp;amp;&amp;amp; su $user -c &amp;quot;echo $OSDTEXT | $OSD_CAT $OSD_GENERICARGS --offset=$VGA_VOFFSET --indent=$VGA_HOFFSET - &amp;amp;&amp;quot;&lt;br /&gt;
            [ -n &amp;quot;$SVIDEO_CONN&amp;quot; ] &amp;amp;&amp;amp; su $user -c &amp;quot;echo $OSDTEXT | $OSD_CAT $OSD_GENERICARGS --offset=$SVIDEO_HOFFSET --indent=$SVIDEO_VOFFSET - &amp;amp;&amp;quot;&lt;br /&gt;
        fi&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Snippet borrowed from /etc/acpi/lid.sh&lt;br /&gt;
for x in /tmp/.X11-unix/*; do&lt;br /&gt;
   displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`&lt;br /&gt;
   getXuser;&lt;br /&gt;
   if [ x&amp;quot;$XAUTHORITY&amp;quot; != x&amp;quot;&amp;quot; ]; then&lt;br /&gt;
       export DISPLAY=&amp;quot;:$displaynum&amp;quot;&lt;br /&gt;
      screen_toggle&lt;br /&gt;
   fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/bash&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If neither VGA nor S-video are connected, the script will only flip on and off the backlight. If one output is connected, be it VGA or S-video, the sequence will be 1) Internal, 2) VGA/S-video (backlight off), 3) Internal+VGA/S-video, 0) all off. If both a monitor and a TV are connected, the sequence will be 1) Internal, 2) VGA (backlight off), 3) Internal+VGA, 4) S-video (backlight off), 5) Internal+S-video, 0) all off.&lt;br /&gt;
&lt;br /&gt;
== A Python Toggle script ==&lt;br /&gt;
This is a somewhat over-elaborate script which could be cut down when run by the /usr/local/sbin/toggle-display.sh script above. It was written to explore all the possibilities rather than economy of execution. The functions 'toggle_full', 'position', 'toggle_limited' and the OptionParser in 'main'  may be omitted with suitable changes to function7. The appropriate outputs can be specified on the command line and it is not necessary to call it via acpi.&lt;br /&gt;
eg you can run it as {{cmduser|/usr/local/bin/toggle.py --help}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
 #! /usr/bin/python&lt;br /&gt;
 # -*- coding: utf-8 -*-&lt;br /&gt;
 #&lt;br /&gt;
 # stinkpad(a)blueyonder.co.uk	2007-11-26&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;Toggle internal and external displays (equivalent to ThinkPad Fn7)&lt;br /&gt;
 Simple; cloned: on+off, on+on, off+on. &lt;br /&gt;
 Full; as simple plus xinerama: right, below,  left, above. &lt;br /&gt;
 Limited; as full but display will overlap if virtual screen is too small. &lt;br /&gt;
 Use 'xrandr -q' to determine output names. &lt;br /&gt;
 Further information: http://www.thinkwiki.org/wiki/Xorg_RandR_1.2 &lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 __usage__ = &amp;quot;usage: %prog [--help]|[[-i internal][-e external][-d displays]]&amp;quot;&lt;br /&gt;
 __version__ = &amp;quot;toggle [djclark.eu 2007-11-26]&amp;quot;&lt;br /&gt;
 #&lt;br /&gt;
 # Output names; Intel: LVDS VGA TV TMDS-1 TMDS-2&lt;br /&gt;
 #               ATI:   LVDS VGA-0 S-video DVI-0&lt;br /&gt;
 LAPTOP = 'LVDS' &lt;br /&gt;
 MONITOR = 'VGA'&lt;br /&gt;
 SEQUENCE = 'simple'&lt;br /&gt;
 #&lt;br /&gt;
 import sys&lt;br /&gt;
 import os&lt;br /&gt;
 import re&lt;br /&gt;
&lt;br /&gt;
 # &amp;quot;LVDS connected 1024x768+0+0 (normal left inverted right) 304mm x 228mm&amp;quot;&lt;br /&gt;
 REGEX_OUTPUT = re.compile(r&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 	(?x)					# ignore whitespace&lt;br /&gt;
 	^					# start of string&lt;br /&gt;
 	(?P&amp;lt;output&amp;gt;[A-Za-z0-9\-]*)[ ] 		# LVDS VGA etc&lt;br /&gt;
 	(?P&amp;lt;connect&amp;gt;(dis)?connected)[ ]		# dis/connected&lt;br /&gt;
 	((					# a group&lt;br /&gt;
  	(?P&amp;lt;width&amp;gt;\d+)x 			# either 1024x768+0+0&lt;br /&gt;
 	(?P&amp;lt;height&amp;gt;\d+)[+]  &lt;br /&gt;
  	(?P&amp;lt;horizontal&amp;gt;\d+)[+]&lt;br /&gt;
 	(?P&amp;lt;vertical&amp;gt;\d+)&lt;br /&gt;
 	)|[\D])					# or not a digit&lt;br /&gt;
 	.*					# ignore rest of line&lt;br /&gt;
 	&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 # &amp;quot;Screen 0: minimum 320 x 200, current 1024 x 768, maximum 2624 x 1968&amp;quot;&lt;br /&gt;
 REGEX_SCREEN = re.compile(r&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 	(?x) 				# ignore whitespace&lt;br /&gt;
 	^				# start of string&lt;br /&gt;
 	Screen[ ]			&lt;br /&gt;
 	(?P&amp;lt;screen&amp;gt;\d)[: ]+&lt;br /&gt;
 	minimum[ ]&lt;br /&gt;
 	(?P&amp;lt;minWidth&amp;gt;\d+)[ x]+&lt;br /&gt;
 	(?P&amp;lt;minHeight&amp;gt;\d+)[, ]+&lt;br /&gt;
 	current[ ]+&lt;br /&gt;
 	(?P&amp;lt;curWidth&amp;gt;\d+)[ x]+&lt;br /&gt;
 	(?P&amp;lt;curHeight&amp;gt;\d+)[, ]+&lt;br /&gt;
 	maximum[ ]+&lt;br /&gt;
 	(?P&amp;lt;maxWidth&amp;gt;\d+)[ x]+&lt;br /&gt;
 	(?P&amp;lt;maxHeight&amp;gt;\d+)&lt;br /&gt;
 	&amp;quot;&amp;quot;&amp;quot;)	&lt;br /&gt;
&lt;br /&gt;
 def toggle_simple(d0, d1):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Toggle display states: on+off, on+on, off+on&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if d1['connect'] == 'disconnected': 	# external unplugged&lt;br /&gt;
        return ('auto','off',&amp;quot;&amp;quot;) 		#     switch off external&lt;br /&gt;
    if d1['width'] is 0: 			# external off&lt;br /&gt;
        return ('auto','auto',&amp;quot;&amp;quot;) 		#     both on&lt;br /&gt;
    if d0['width'] is 0: 			# laptop off&lt;br /&gt;
        return ('auto','off',&amp;quot;&amp;quot;) 		#    laptop on&lt;br /&gt;
    return ('off','auto',&amp;quot;&amp;quot;) 			# both on, laptop off&lt;br /&gt;
&lt;br /&gt;
 def toggle_full(d0, d1):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Toggle display states: 1+0, 1+1, 0+1, 1+E, 1+S, 1+W, 1+N&amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    if d1['connect'] == 'disconnected': 	# external unplugged&lt;br /&gt;
        return ('auto','off',&amp;quot;&amp;quot;) 		#     switch off external&lt;br /&gt;
    place = '--%s ' + d0['output']&lt;br /&gt;
    if d1['width'] == 0: 			# external off&lt;br /&gt;
        return ('auto','auto',place%'same-as') 	#     external on&lt;br /&gt;
    if d0['width'] == 0: 			# laptop off&lt;br /&gt;
        return ('auto','off',&amp;quot;&amp;quot;) 		#    laptop on&lt;br /&gt;
    if d1['horizontal'] &amp;gt; 0: 			# external to right&lt;br /&gt;
        return ('auto','auto',place%'below') 	#     make below&lt;br /&gt;
    if d1['vertical'] &amp;gt; 0: 			# external below&lt;br /&gt;
        return ('auto','auto',place%'left-of') 	#     make left&lt;br /&gt;
    if d0['horizontal'] &amp;gt; 0: 			# external left&lt;br /&gt;
        return ('auto','auto',place%'above') 	#     make above&lt;br /&gt;
    if d0['vertical'] &amp;gt; 0: 			# external above&lt;br /&gt;
        return ('off','auto',&amp;quot;&amp;quot;)  		#     laptop off&lt;br /&gt;
    return ('auto','auto',place%'right-of') 	# is same, make right&lt;br /&gt;
&lt;br /&gt;
 def position(orientation, da, db, screen):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Calculate offset position of second display&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    p = 'auto --pos %sx%s'&lt;br /&gt;
    if orientation == 'V':&lt;br /&gt;
        if da['height'] + db['height'] &amp;lt;= screen['maxHeight']:&lt;br /&gt;
            return p%(0, da['height'])&lt;br /&gt;
        return p%(0, screen['maxHeight'] - db['height'])&lt;br /&gt;
    else:&lt;br /&gt;
        if da['width'] + db['width'] &amp;lt;= screen['maxWidth']:&lt;br /&gt;
            return p%(da['width'],0)&lt;br /&gt;
        return p%(screen['maxWidth'] - db['width'],0)&lt;br /&gt;
&lt;br /&gt;
 def toggle_limited(d0, d1, sz):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Toggle display states (overlapped): 1+0,1+1,0+1,1+E,1+S,1+W,1+N&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if d1['connect'] == 'disconnected': 	# external unplugged&lt;br /&gt;
        return ('auto','off') 			#     switch off external&lt;br /&gt;
    if d1['width'] == 0: 				# external off&lt;br /&gt;
        return ('auto --pos 0x0','auto --pos 0x0') 	#     both on&lt;br /&gt;
    if d0['width'] == 0: 				# laptop off&lt;br /&gt;
        return ('auto --pos 0x0','off') 		#     laptop on&lt;br /&gt;
    if d1['horizontal'] &amp;gt; 0: 				# external to right&lt;br /&gt;
        return ('auto --pos 0x0',position('V',d0,d1,sz)) #     put *below&lt;br /&gt;
    if d1['vertical'] &amp;gt; 0: 				# external below&lt;br /&gt;
        return (position('H',d1,d0,sz),'auto --pos 0x0') #     put *left&lt;br /&gt;
    if d0['horizontal'] &amp;gt; 0: 				# external left&lt;br /&gt;
        return (position('V',d1,d0,sz),'auto --pos 0x0') #     put *above&lt;br /&gt;
    if d0['vertical'] &amp;gt; 0: 				# external above&lt;br /&gt;
        return ('off','auto --pos 0x0')  		#     laptop off&lt;br /&gt;
    return ('auto --pos 0x0',position('H',d0,d1,sz)) 	# both, put*right&lt;br /&gt;
&lt;br /&gt;
 class DisplayNameError(UnboundLocalError):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Internal or External Display Name not found by xrandr -q &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 def function7(disp0=LAPTOP, disp1=MONITOR, seq=SEQUENCE):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Use xrandr to read current display state and change state&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    for line in os.popen('xrandr -q'):&lt;br /&gt;
        if line.startswith(disp0,0) :&lt;br /&gt;
            d0_state = REGEX_OUTPUT.match(line).groupdict()&lt;br /&gt;
        elif line.startswith(disp1,0):&lt;br /&gt;
            d1_state = REGEX_OUTPUT.match(line).groupdict()&lt;br /&gt;
        elif line.startswith('Screen',0):&lt;br /&gt;
            screen_size = REGEX_SCREEN.match(line).groupdict()&lt;br /&gt;
    for i in ('width','height','horizontal','vertical'):&lt;br /&gt;
        try:&lt;br /&gt;
            d0_state[i] = int(d0_state[i])&lt;br /&gt;
        except TypeError:&lt;br /&gt;
            d0_state[i] = 0&lt;br /&gt;
        except UnboundLocalError:&lt;br /&gt;
            raise DisplayNameError, 'Internal Display: %s not found'% disp0&lt;br /&gt;
        try:&lt;br /&gt;
            d1_state[i] = int(d1_state[i])&lt;br /&gt;
        except TypeError:&lt;br /&gt;
            d1_state[i] = 0&lt;br /&gt;
        except UnboundLocalError:&lt;br /&gt;
            raise DisplayNameError, 'External Display: %s not found'% disp1&lt;br /&gt;
    for i in screen_size:&lt;br /&gt;
        try:&lt;br /&gt;
            screen_size[i] = int(screen_size[i])&lt;br /&gt;
        except TypeError:&lt;br /&gt;
            screen_size[i] = 0&lt;br /&gt;
    #&lt;br /&gt;
    toggle = toggle_simple&lt;br /&gt;
    xrandr ='xrandr --output '+disp0+' --%s --output '+disp1+' --%s %s'&lt;br /&gt;
    if seq == 'full':&lt;br /&gt;
        toggle = toggle_full&lt;br /&gt;
    if seq == 'limited':&lt;br /&gt;
        toggle = toggle_limited&lt;br /&gt;
        xrandr ='xrandr --output '+disp0+' --%s --output '+disp1+' --%s'&lt;br /&gt;
        os.popen(xrandr % toggle(d0_state, d1_state, screen_size))&lt;br /&gt;
    else:&lt;br /&gt;
        os.popen(xrandr % toggle(d0_state, d1_state))&lt;br /&gt;
&lt;br /&gt;
 def main():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Command line options &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    from optparse import OptionParser&lt;br /&gt;
    p = OptionParser(usage=__usage__, version=__version__, description=__doc__)  &lt;br /&gt;
    p.set_defaults(internal=LAPTOP, external=MONITOR, displays=SEQUENCE)&lt;br /&gt;
    p.add_option('-i','--internal', dest=&amp;quot;internal&amp;quot;, metavar=LAPTOP,&lt;br /&gt;
 	help=&amp;quot;internal display&amp;quot;)&lt;br /&gt;
    p.add_option('-e','--external', dest=&amp;quot;external&amp;quot;, metavar=MONITOR,&lt;br /&gt;
  	help=&amp;quot;external display&amp;quot;)&lt;br /&gt;
    p.add_option('-d','--displays', dest=&amp;quot;displays&amp;quot;, action=&amp;quot;store&amp;quot;,&lt;br /&gt;
 	choices=('simple', 'limited', 'full'), metavar=SEQUENCE,&lt;br /&gt;
 	help='simple/limited/full')&lt;br /&gt;
    (opt, args) = p.parse_args()&lt;br /&gt;
    try:&lt;br /&gt;
        function7(opt.internal, opt.external, opt.displays)&lt;br /&gt;
    except DisplayNameError, err:&lt;br /&gt;
        print '\n'+str(err)+'\n'&lt;br /&gt;
        print os.popen('xrandr -q').read()&lt;br /&gt;
 #&lt;br /&gt;
 if __name__ == '__main__': 	#only when run from cmd line&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This modified thinkpad-fn-f7 calls the toggle python script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bash&amp;gt;&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 # usr/local/sbin/toggle-display.sh &lt;br /&gt;
 # based on /etc/acpi/screenblank.sh (Ubuntu 7.10)&lt;br /&gt;
 #&lt;br /&gt;
 # . /usr/share/acpi-support/power-funcs         # for getXuser&lt;br /&gt;
 umask 022;&lt;br /&gt;
 PATH=&amp;quot;$PATH:/usr/bin/X11&amp;quot;&lt;br /&gt;
 getXuser() {&lt;br /&gt;
        user=`finger| grep -m1 &amp;quot;:$displaynum &amp;quot; | awk '{print $1}'`&lt;br /&gt;
        if [ x&amp;quot;$user&amp;quot; = x&amp;quot;&amp;quot; ]; then&lt;br /&gt;
                user=`finger| grep -m1 &amp;quot;:$displaynum&amp;quot; | awk '{print $1}'`&lt;br /&gt;
        fi&lt;br /&gt;
        if [ x&amp;quot;$user&amp;quot; != x&amp;quot;&amp;quot; ]; then&lt;br /&gt;
                userhome=`getent passwd $user | cut -d: -f6`&lt;br /&gt;
                export XAUTHORITY=$userhome/.Xauthority&lt;br /&gt;
        else&lt;br /&gt;
                export XAUTHORITY=&amp;quot;&amp;quot;&lt;br /&gt;
        fi&lt;br /&gt;
 }&lt;br /&gt;
 # end of getXuser from /usr/share/acpi-support/power-funcs&lt;br /&gt;
 #&lt;br /&gt;
 for x in /tmp/.X11-unix/*; do&lt;br /&gt;
    displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`&lt;br /&gt;
    getXuser;&lt;br /&gt;
    if [ x&amp;quot;$XAUTHORITY&amp;quot; != x&amp;quot;&amp;quot; ]; then&lt;br /&gt;
        export DISPLAY=&amp;quot;:$displaynum&amp;quot;&lt;br /&gt;
 ##     . /usr/share/acpi-support/screenblank.sh&lt;br /&gt;
        /usr/local/bin/toggle.py&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/bash&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Python XRandR===&lt;br /&gt;
[[http://www.glatzor.de/blog/blog-details/article/initial-release-of-python-xrandr Python XRandR]] is a set of python bindings to xrandr. The code is currently in development and the following code though much simpler than the python code above may not work reliably.&lt;br /&gt;
&lt;br /&gt;
  from xrandr import xrandr&lt;br /&gt;
  def toggle_simple():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Toggle display states: on+off, off+on, on+on off+off&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    screen = xrandr.get_current_screen()&lt;br /&gt;
    outputs = screen.get_outputs()&lt;br /&gt;
    for o in outputs:&lt;br /&gt;
        if o.is_connected():&lt;br /&gt;
            if o.is_active():&lt;br /&gt;
                o.disable()&lt;br /&gt;
                print 'disable %s'% o.name&lt;br /&gt;
            else:&lt;br /&gt;
                o.set_to_preferred_mode()&lt;br /&gt;
                print 'set to preferred mode %s'% o.name&lt;br /&gt;
                break&lt;br /&gt;
    screen.apply_output_config()&lt;br /&gt;
&lt;br /&gt;
== Having Fn-F7 run a RandR GUI ==&lt;br /&gt;
Instead of using it to toggle various screen(s) configurations, one may want to have it run a RandR GUI, such as grandr.&lt;br /&gt;
&lt;br /&gt;
The following Debian wishlist bugs against the acpi-support package have patches attached that implement this behaviour using acpid; these patches are not Debian-specific, and actually provide example configuration for anyone interested into this:&lt;br /&gt;
 &lt;br /&gt;
* http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=515794&lt;br /&gt;
* http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=515796&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
[[http://gitweb.freedesktop.org/?p=xorg/app/grandr.git grandr]] graphical interface to xrandr  using GTK+ libraries.&lt;br /&gt;
&lt;br /&gt;
[[https://edge.launchpad.net/python-xrandr python-xrandr]] Python bindings to xrandr which should enable a less clunky version of the python script above. Under development.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>Newacct</name></author>
		
	</entry>
	<entry>
		<id>https://www.thinkwiki.org/w/index.php?title=Battery.rb&amp;diff=48734</id>
		<title>Battery.rb</title>
		<link rel="alternate" type="text/html" href="https://www.thinkwiki.org/w/index.php?title=Battery.rb&amp;diff=48734"/>
		<updated>2010-06-07T22:55:22Z</updated>

		<summary type="html">&lt;p&gt;Newacct: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==How to use it==&lt;br /&gt;
The following ruby script can generates the following output&lt;br /&gt;
&lt;br /&gt;
./battery.rb&lt;br /&gt;
 [+] 01:02 (90%)&lt;br /&gt;
&lt;br /&gt;
./battery.rb -v&lt;br /&gt;
 The battery is charging&lt;br /&gt;
 Current Status		90%&lt;br /&gt;
 Remaining Charging Time	01h02m&lt;br /&gt;
 Charging Till		22:52&lt;br /&gt;
 &lt;br /&gt;
 After 91 cycles the battery has 90% of its design capacity&lt;br /&gt;
&lt;br /&gt;
./battery.rb -b&lt;br /&gt;
 [######### ]&lt;br /&gt;
&lt;br /&gt;
./battery.rb -h&lt;br /&gt;
 This is a very small script for getting some useful information about your battery&lt;br /&gt;
 Please notice that this script requires tp_smapi which is only available on ThinkPads&lt;br /&gt;
 &lt;br /&gt;
 Version 0.1 written by futejia during the 24C3 in Berlin&lt;br /&gt;
 The script is published under the 'Beer License' which means you can do whatever you want, and when you like the script you buy me a beer&lt;br /&gt;
 &lt;br /&gt;
 Command line options:&lt;br /&gt;
     All information you usually need in one single line&lt;br /&gt;
 -h  Prints this help&lt;br /&gt;
 -b  Prints a nice ascii battery (Single line)&lt;br /&gt;
 -v  Gives some more information about the battery&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==The script itself==&lt;br /&gt;
Simple safe this as battery.rb (Of course you need ruby and tp_smapi installed)&lt;br /&gt;
 &lt;br /&gt;
 #!/usr/bin/ruby &lt;br /&gt;
 def getFileValue(filename)&lt;br /&gt;
   file = File.new(filename,&amp;quot;r&amp;quot;)&lt;br /&gt;
   content = file.gets&lt;br /&gt;
   file.close&lt;br /&gt;
   content = content.delete &amp;quot;\n&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 def addLeadingZero(value)&lt;br /&gt;
   &amp;quot;%02d&amp;quot; % value&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 begin&lt;br /&gt;
   state = getFileValue(&amp;quot;/sys/devices/platform/smapi/BAT0/state&amp;quot;)&lt;br /&gt;
   if state == &amp;quot;charging&amp;quot; &lt;br /&gt;
     remaning_time = getFileValue(&amp;quot;/sys/devices/platform/smapi/BAT0/remaining_charging_time&amp;quot;).to_i&lt;br /&gt;
     symbol = &amp;quot;[+]&amp;quot;&lt;br /&gt;
     descriptingword = &amp;quot;Charging&amp;quot;&lt;br /&gt;
   elsif state == &amp;quot;discharging&amp;quot;&lt;br /&gt;
     remaning_time = getFileValue(&amp;quot;/sys/devices/platform/smapi/BAT0/remaining_running_time&amp;quot;).to_i&lt;br /&gt;
     symbol = &amp;quot;[-]&amp;quot;&lt;br /&gt;
     descriptingword = &amp;quot;Running&amp;quot;&lt;br /&gt;
   elsif state == &amp;quot;idle&amp;quot;&lt;br /&gt;
     remaning_time = 0&lt;br /&gt;
     symbol = &amp;quot;[ ]&amp;quot;&lt;br /&gt;
     descriptingword = &amp;quot;Idle&amp;quot;&lt;br /&gt;
   else&lt;br /&gt;
     puts &amp;quot;Unknown value: '&amp;quot;+state+&amp;quot;'&amp;quot;&lt;br /&gt;
   end&lt;br /&gt;
   percent = getFileValue(&amp;quot;/sys/devices/platform/smapi/BAT0/remaining_percent&amp;quot;).to_i&lt;br /&gt;
   batterybar = (percent.to_f / 10).round&lt;br /&gt;
   hours = remaning_time / 60&lt;br /&gt;
   minutes = remaning_time % 60&lt;br /&gt;
 &lt;br /&gt;
   if ARGV[0] == &amp;quot;-v&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
     puts &amp;quot;The battery is &amp;quot; + state&lt;br /&gt;
     #getting some information about the current capacity&lt;br /&gt;
     design_capacity = getFileValue(&amp;quot;/sys/devices/platform/smapi/BAT0/design_capacity&amp;quot;).to_i&lt;br /&gt;
     last_full_capacity = getFileValue(&amp;quot;/sys/devices/platform/smapi/BAT0/last_full_capacity&amp;quot;).to_i&lt;br /&gt;
     capacity = last_full_capacity * 100 / design_capacity&lt;br /&gt;
 &lt;br /&gt;
     cycles = getFileValue(&amp;quot;/sys/devices/platform/smapi/BAT0/cycle_count&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
     d = Time::now()&lt;br /&gt;
     d += remaning_time * 60&lt;br /&gt;
     puts &amp;quot;Current Status\t\t#{percent}%&amp;quot;&lt;br /&gt;
     puts &amp;quot;Remaining &amp;quot; + descriptingword + &amp;quot; Time\t&amp;quot; +   addLeadingZero(hours) + &amp;quot;h&amp;quot; + addLeadingZero(minutes) + &amp;quot;m&amp;quot;&lt;br /&gt;
     if state != &amp;quot;idle&amp;quot;&lt;br /&gt;
       puts descriptingword + &amp;quot; Till\t\t&amp;quot; + addLeadingZero(d.hour()) + &amp;quot;:&amp;quot; + addLeadingZero(d.min())&lt;br /&gt;
     end&lt;br /&gt;
     puts &amp;quot;&amp;quot;&lt;br /&gt;
     puts &amp;quot;After #{cycles} cycles the battery has #{capacity}% of its design capacity&amp;quot;&lt;br /&gt;
   elsif ARGV[0] == &amp;quot;-b&amp;quot;&lt;br /&gt;
     battery = &amp;quot;&amp;quot;&lt;br /&gt;
     batterybar.downto(1) { battery += &amp;quot;#&amp;quot; }&lt;br /&gt;
     batterybar.upto(9) { battery += &amp;quot; &amp;quot; }&lt;br /&gt;
     puts &amp;quot;[&amp;quot; + battery + &amp;quot;]&amp;quot;&lt;br /&gt;
   elsif ARGV[0] == &amp;quot;-h&amp;quot;&lt;br /&gt;
     puts &amp;quot;This is a very small script for getting some useful information about your battery&amp;quot;&lt;br /&gt;
     puts &amp;quot;Please notice that this script requires tp_smapi which is only available on ThinkPads&amp;quot;&lt;br /&gt;
     puts&lt;br /&gt;
     puts &amp;quot;Version 0.1 written by futejia during the 24C3 in Berlin&amp;quot;&lt;br /&gt;
     puts &amp;quot;The script is published under the 'Beer License' which means you can do whatever you want, and when you like the script you buy me a beer&amp;quot;&lt;br /&gt;
     puts &lt;br /&gt;
     puts &amp;quot;Command line options:&amp;quot;&lt;br /&gt;
     puts &amp;quot;    All information you usually need in one single line&amp;quot;&lt;br /&gt;
     puts &amp;quot;-h  Prints this help&amp;quot;&lt;br /&gt;
     puts &amp;quot;-b  Prints a nice ascii battery (Single line)&amp;quot;&lt;br /&gt;
     puts &amp;quot;-v  Gives some more information about the battery&amp;quot;&lt;br /&gt;
   else&lt;br /&gt;
     puts symbol + &amp;quot; &amp;quot; + addLeadingZero(hours) + &amp;quot;:&amp;quot; + addLeadingZero(minutes) + &amp;quot; (#{percent}%)&amp;quot;&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Newacct</name></author>
		
	</entry>
	<entry>
		<id>https://www.thinkwiki.org/w/index.php?title=Sample_Fn-F7_script&amp;diff=46575</id>
		<title>Sample Fn-F7 script</title>
		<link rel="alternate" type="text/html" href="https://www.thinkwiki.org/w/index.php?title=Sample_Fn-F7_script&amp;diff=46575"/>
		<updated>2010-02-27T10:37:22Z</updated>

		<summary type="html">&lt;p&gt;Newacct: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide will help you configure Fn-F7 key combination to toggle between internal, mirror, external, or both screens.  This was tested on ThinkPad X60s running Fedora 8, please comment if it works or does not work for you.&lt;br /&gt;
&lt;br /&gt;
Works like a charm on X61s with Xubuntu 7.10.&lt;br /&gt;
Working with R60e with some modifications noted below.&lt;br /&gt;
&lt;br /&gt;
The script does not work when using [[fglrx]] or a version of XRandR &amp;lt; 1.2, because there is no dynamic display switching support then. When fglrx is used, aticonfig can be used for the switching in this [[Script for Dynamic Display Management with fglrx]].&lt;br /&gt;
&lt;br /&gt;
{{NOTE|On a modern distribution like Fedora 12, the Fn-F7 key works out-of-the-box, and no additional scripts are needed to switch between external display modes}}&lt;br /&gt;
&lt;br /&gt;
==configuring the virtual screen size==&lt;br /&gt;
Add a &amp;quot;Virtual&amp;quot; statement to your /etc/X11/xorg.conf, the total resolution should be large enough to fit all your screens in the configuration you want, for example if you have 1600x1200 monitor to the left of your internal 1024x768 monitor, your total max resolution is 2624x1200 (See [[Xorg RandR 1.2]] for more details):&lt;br /&gt;
&lt;br /&gt;
 Section &amp;quot;Screen&amp;quot;&lt;br /&gt;
        Identifier &amp;quot;Screen0&amp;quot;&lt;br /&gt;
        Device     &amp;quot;Videocard0&amp;quot;&lt;br /&gt;
        DefaultDepth     24&lt;br /&gt;
         SubSection &amp;quot;Display&amp;quot;&lt;br /&gt;
                Viewport   0 0&lt;br /&gt;
                Depth     24&lt;br /&gt;
                &amp;lt;b&amp;gt;Virtual   2624 1200&amp;lt;/b&amp;gt;&lt;br /&gt;
        EndSubSection&lt;br /&gt;
 EndSection&lt;br /&gt;
&lt;br /&gt;
Restart X server at this point (i.e. logout and login).&lt;br /&gt;
&lt;br /&gt;
== configuring acpi ==&lt;br /&gt;
Create /etc/acpi/events/thinkpad.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bash&amp;gt;&lt;br /&gt;
event=ibm/hotkey HKEY 00000080 00001007&lt;br /&gt;
action=/usr/local/sbin/thinkpad-fn-f7&lt;br /&gt;
&amp;lt;/bash&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you may (eg Ubuntu 7.10) already have /etc/acpi/events/ibm-videobtn&lt;br /&gt;
&amp;lt;bash&amp;gt;&lt;br /&gt;
# /etc/acpi/events/ibm-videobtn&lt;br /&gt;
# This is called when the user presses the video button. It is currently&lt;br /&gt;
# a placeholder.&lt;br /&gt;
event=ibm/hotkey HKEY 00000080 00001007&lt;br /&gt;
action=/bin/true&lt;br /&gt;
&amp;lt;/bash&amp;gt;&lt;br /&gt;
in which case modify the line 'action=/bin/true' to run the script as above.&lt;br /&gt;
&lt;br /&gt;
It may also be necessary to enable acpi events as per [[How to get special keys to work]] with (in root terminal)&lt;br /&gt;
{{cmdroot|echo enable,0x084e &amp;gt; /proc/acpi/ibm/hotkey}}&lt;br /&gt;
Note this command isn't persistent. so you will also need to add the line to /etc/rc.local to enable hotkeys at boot, and to re-enable the hotkeys after suspend to disk or RAM, create the file&lt;br /&gt;
/etc/acpi/resume.d/91-ibm-hotkey-enable.sh consisting of&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bash&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# enable ibm-hotkeys (specifically Fn2, Fn7)&lt;br /&gt;
# 12 bit mask, little end is F1 default 0x080c = F12+F4+F3&lt;br /&gt;
echo enable,0x084e &amp;gt; /proc/acpi/ibm/hotkey&lt;br /&gt;
&amp;lt;/bash&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: [[http://tilmanfrosch.de/wp/index.php/2007/05/05/howto-make-a-ubuntu-linux-on-an-ibm-t41-thinkpad-work-with-an-external-widescreen-wxga-display/  frosch.org.uk]] and [[http://ibm-acpi.sourceforge.net/README ibm-acpi.sourceforge]]&lt;br /&gt;
&lt;br /&gt;
==identify output devices==&lt;br /&gt;
Note the names of your output devices as you will have to change EXTERNAL_OUTPUT and INTERNAL_OUTPUT to what xrandr shows, for example VGA and LVDS in this case:&lt;br /&gt;
&lt;br /&gt;
 $ xrandr -q&lt;br /&gt;
 '''VGA''' connected 1600x1200+0+0 (normal left inverted right x axis y axis) 432mm x 324mm&lt;br /&gt;
 ...&lt;br /&gt;
 '''LVDS''' connected (normal left inverted right x axis y axis)&lt;br /&gt;
&lt;br /&gt;
==The bash script==&lt;br /&gt;
Create /usr/local/sbin/thinkpad-fn-f7, you can set EXTERNAL_LOCATION to one of: left, right, above, or below.&lt;br /&gt;
&amp;lt;bash&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
# External output may be &amp;quot;VGA&amp;quot; or &amp;quot;VGA-0&amp;quot; or &amp;quot;DVI-0&amp;quot; or &amp;quot;TMDS-1&amp;quot;&lt;br /&gt;
EXTERNAL_OUTPUT=&amp;quot;VGA&amp;quot;&lt;br /&gt;
INTERNAL_OUTPUT=&amp;quot;LVDS&amp;quot;&lt;br /&gt;
EXTERNAL_LOCATION=&amp;quot;left&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Figure out which user and X11 display to work on&lt;br /&gt;
# TODO there has to be a better way to do this?&lt;br /&gt;
X_USER=$(w -h -s | grep &amp;quot;:[0-9]\W&amp;quot; | head -1 | awk '{print $1}')&lt;br /&gt;
export DISPLAY=$(w -h -s | grep &amp;quot;:[0-9]\W&amp;quot; | head -1 | awk '{print $3}')&lt;br /&gt;
&lt;br /&gt;
# Switch to X user if necessary&lt;br /&gt;
if [ &amp;quot;$X_USER&amp;quot; != &amp;quot;$USER&amp;quot; ]; then&lt;br /&gt;
       SU=&amp;quot;su $X_USER -c&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
       SU=&amp;quot;sh -c&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$EXTERNAL_LOCATION&amp;quot; in&lt;br /&gt;
       left|LEFT)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--left-of $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       right|RIGHT)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--right-of $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       top|TOP|above|ABOVE)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--above $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       bottom|BOTTOM|below|BELOW)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--below $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       *)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--left-of $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
# Figure out current state&lt;br /&gt;
INTERNAL_STATE=$($SU xrandr | grep ^$INTERNAL_OUTPUT | grep &amp;quot; con&amp;quot; | sed &amp;quot;s/.*connected//&amp;quot; | sed &amp;quot;s/ //&amp;quot; | sed &amp;quot;s/ .*//g&amp;quot;)&lt;br /&gt;
EXTERNAL_STATE=$($SU xrandr | grep ^$EXTERNAL_OUTPUT | grep &amp;quot; con&amp;quot; | sed &amp;quot;s/.*connected//&amp;quot; | sed &amp;quot;s/ //&amp;quot; | sed &amp;quot;s/ .*//g&amp;quot;)&lt;br /&gt;
# I recommend to replace these prior two statements, since otherwise with  xrandr 1.2 it produces wrong results:&lt;br /&gt;
# a textportion &amp;quot;(normal&amp;quot; otherwise still remains when a screen is connected, but switched off (by e.g. toggling!)&lt;br /&gt;
# (comment out the prior two lines, and uncomment the following two lines:)&lt;br /&gt;
# INTERNAL_STATE=$($SU xrandr | grep ^$INTERNAL_OUTPUT | grep &amp;quot; con&amp;quot; | sed &amp;quot;s/.*connected//&amp;quot; | sed &amp;quot;s/ //&amp;quot; | sed &amp;quot;s/ .*//g&amp;quot;| sed &amp;quot;s/(normal//g&amp;quot; )&lt;br /&gt;
# EXTERNAL_STATE=$($SU xrandr | grep ^$EXTERNAL_OUTPUT | grep &amp;quot; con&amp;quot; | sed &amp;quot;s/.*connected//&amp;quot; | sed &amp;quot;s/ //&amp;quot; | sed &amp;quot;s/ .*//g&amp;quot;| sed &amp;quot;s/(normal//g&amp;quot; )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if [ -z &amp;quot;$INTERNAL_STATE&amp;quot; ]; then&lt;br /&gt;
       STATE=&amp;quot;external&amp;quot;&lt;br /&gt;
elif [ -z &amp;quot;$EXTERNAL_STATE&amp;quot; ]; then&lt;br /&gt;
       STATE=&amp;quot;internal&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
       INTERNAL_STATE=$(echo $INTERNAL_STATE | sed &amp;quot;s/[0-9]*x[0-9]*//&amp;quot;)&lt;br /&gt;
       EXTERNAL_STATE=$(echo $EXTERNAL_STATE | sed &amp;quot;s/[0-9]*x[0-9]*//&amp;quot;)&lt;br /&gt;
       if [ &amp;quot;$INTERNAL_STATE&amp;quot; = &amp;quot;$EXTERNAL_STATE&amp;quot; ]; then&lt;br /&gt;
               STATE=&amp;quot;mirror&amp;quot;&lt;br /&gt;
       else&lt;br /&gt;
               STATE=&amp;quot;both&amp;quot;&lt;br /&gt;
       fi&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
function screen_external(){&lt;br /&gt;
# recommend exchange the order, since otherwise doesn't work&lt;br /&gt;
# with my ati adapter (please uncomment if needed, and&lt;br /&gt;
#comment out the other two):&lt;br /&gt;
#       $SU &amp;quot;xrandr --output $EXTERNAL_OUTPUT --auto&amp;quot;&lt;br /&gt;
#       $SU &amp;quot;xrandr --output $INTERNAL_OUTPUT --off&amp;quot;&lt;br /&gt;
       $SU &amp;quot;xrandr --output $INTERNAL_OUTPUT --off&amp;quot;&lt;br /&gt;
       $SU &amp;quot;xrandr --output $EXTERNAL_OUTPUT --auto&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_internal(){&lt;br /&gt;
       $SU &amp;quot;xrandr --output $EXTERNAL_OUTPUT --off&amp;quot;&lt;br /&gt;
       $SU &amp;quot;xrandr --output $INTERNAL_OUTPUT --auto&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_mirror(){&lt;br /&gt;
       $SU &amp;quot;xrandr --output $INTERNAL_OUTPUT --auto&amp;quot;&lt;br /&gt;
       $SU &amp;quot;xrandr --output $EXTERNAL_OUTPUT --auto --same-as $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_both(){&lt;br /&gt;
       $SU &amp;quot;xrandr --output $INTERNAL_OUTPUT --auto&amp;quot;&lt;br /&gt;
       $SU &amp;quot;xrandr --output $EXTERNAL_OUTPUT --auto $EXTERNAL_LOCATION&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_toggle(){&lt;br /&gt;
       case &amp;quot;$STATE&amp;quot; in&lt;br /&gt;
               internal)&lt;br /&gt;
                       screen_mirror&lt;br /&gt;
                       ;;&lt;br /&gt;
               mirror)&lt;br /&gt;
                       screen_external&lt;br /&gt;
                       ;;&lt;br /&gt;
               external)&lt;br /&gt;
                       screen_both&lt;br /&gt;
                       ;;&lt;br /&gt;
               both)&lt;br /&gt;
                       screen_internal&lt;br /&gt;
                       ;;&lt;br /&gt;
               *)&lt;br /&gt;
                       screen_internal&lt;br /&gt;
                       ;;&lt;br /&gt;
       esac&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# What should we do?&lt;br /&gt;
DO=&amp;quot;$1&amp;quot;&lt;br /&gt;
if [ -z &amp;quot;$DO&amp;quot; ]; then&lt;br /&gt;
       if [ $(basename $0) = &amp;quot;thinkpad-fn-f7&amp;quot; ]; then&lt;br /&gt;
               DO=&amp;quot;toggle&amp;quot;&lt;br /&gt;
       fi&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$DO&amp;quot; in&lt;br /&gt;
       toggle)&lt;br /&gt;
               screen_toggle&lt;br /&gt;
               ;;&lt;br /&gt;
       internal)&lt;br /&gt;
               screen_internal&lt;br /&gt;
               ;;&lt;br /&gt;
       external)&lt;br /&gt;
               screen_external&lt;br /&gt;
               ;;&lt;br /&gt;
       mirror)&lt;br /&gt;
               screen_mirror&lt;br /&gt;
               ;;&lt;br /&gt;
       both)&lt;br /&gt;
               screen_both&lt;br /&gt;
               ;;&lt;br /&gt;
       status)&lt;br /&gt;
               echo &amp;quot;Current Fn-F7 state is: $STATE&amp;quot;&lt;br /&gt;
               echo&lt;br /&gt;
               echo &amp;quot;Attached monitors:&amp;quot;&lt;br /&gt;
               $SU xrandr | grep &amp;quot;\Wconnected&amp;quot; | sed &amp;quot;s/^/ /&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       *)&lt;br /&gt;
               echo &amp;quot;usage: $0 &amp;lt;command&amp;gt;&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;quot;  commands:&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;quot;          status&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;quot;          internal&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;quot;          external&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;quot;          mirror&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;quot;          both&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;quot;          toggle&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
               echo &amp;gt;&amp;amp;2&lt;br /&gt;
               ;;&lt;br /&gt;
esac&lt;br /&gt;
&amp;lt;/bash&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== set permissions and restart acpi ==&lt;br /&gt;
As root, or using sudo run the following commands,&lt;br /&gt;
&lt;br /&gt;
 {{cmduser|sudo chmod 755 /usr/local/sbin/thinkpad-fn-f7}}&lt;br /&gt;
 {{cmduser|sudo service acpid restart}}&lt;br /&gt;
 OR&lt;br /&gt;
 {{cmduser|sudo /etc/init.d/acpid restart}}&lt;br /&gt;
&lt;br /&gt;
You should be ready to go, just press Fn-F7 to try.&lt;br /&gt;
&lt;br /&gt;
==Alternative script using .Xauthority rather than su ==&lt;br /&gt;
On systems where the previous script has trouble with the &amp;quot;su&amp;quot; command (I was getting &amp;quot;Can't open display -&amp;quot; errors in /var/log/acpid on Ubuntu 8.04), you can try getting the magic cookie out of the .Xauthority file.&lt;br /&gt;
&lt;br /&gt;
Each user has an ~/.Xauthority file with one line for each X display containing a 'magic cookie' (Run {{cmduser| xauth list}} to see the contents).  The Xserver reads the record in  ~/.Xauthority matching its display. When an X client application starts it also looks for that record and passes the magic cookie to the server. If it matches, the connection to the Xserver is allowed. Use the following script as an alternative &lt;br /&gt;
 action=/usr/local/sbin/toggle-display.sh&lt;br /&gt;
for /etc/acpi/events/ibm-videobtn&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bash&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# From: http://www.thinkwiki.org/wiki/Sample_Fn-F7_script&lt;br /&gt;
#&lt;br /&gt;
# External output may be &amp;quot;VGA&amp;quot; or &amp;quot;VGA-0&amp;quot; or &amp;quot;DVI-0&amp;quot; or &amp;quot;TMDS-1&amp;quot;&lt;br /&gt;
EXTERNAL_OUTPUT=&amp;quot;VGA&amp;quot;&lt;br /&gt;
INTERNAL_OUTPUT=&amp;quot;LVDS&amp;quot;&lt;br /&gt;
# EXTERNAL_LOCATION may be one of: left, right, above, or below&lt;br /&gt;
EXTERNAL_LOCATION=&amp;quot;right&amp;quot;&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$EXTERNAL_LOCATION&amp;quot; in&lt;br /&gt;
       left|LEFT)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--left-of $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       right|RIGHT)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--right-of $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       top|TOP|above|ABOVE)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--above $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       bottom|BOTTOM|below|BELOW)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--below $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
       *)&lt;br /&gt;
               EXTERNAL_LOCATION=&amp;quot;--left-of $INTERNAL_OUTPUT&amp;quot;&lt;br /&gt;
               ;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
function screen_external(){&lt;br /&gt;
       xrandr --output $INTERNAL_OUTPUT --off&lt;br /&gt;
       xrandr --output $EXTERNAL_OUTPUT --auto&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_internal(){&lt;br /&gt;
       xrandr --output $EXTERNAL_OUTPUT --off&lt;br /&gt;
       xrandr --output $INTERNAL_OUTPUT --auto&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_mirror(){&lt;br /&gt;
       xrandr --output $INTERNAL_OUTPUT --auto&lt;br /&gt;
       xrandr --output $EXTERNAL_OUTPUT --auto --same-as $INTERNAL_OUTPUT&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_both(){&lt;br /&gt;
       xrandr --output $INTERNAL_OUTPUT --auto&lt;br /&gt;
       xrandr --output $EXTERNAL_OUTPUT --auto $EXTERNAL_LOCATION&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function screen_toggle(){&lt;br /&gt;
       # Figure out current state&lt;br /&gt;
       INTERNAL_STATE=$(xrandr | grep ^$INTERNAL_OUTPUT | grep con | sed &amp;quot;s/.*connected //&amp;quot; | sed &amp;quot;s/(.*//&amp;quot;)&lt;br /&gt;
       EXTERNAL_STATE=$(xrandr | grep ^$EXTERNAL_OUTPUT | grep con | sed &amp;quot;s/.*connected //&amp;quot; | sed &amp;quot;s/(.*//&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
       if [ -z &amp;quot;$INTERNAL_STATE&amp;quot; ]; then&lt;br /&gt;
         STATE=&amp;quot;external&amp;quot;&lt;br /&gt;
       elif [ -z &amp;quot;$EXTERNAL_STATE&amp;quot; ]; then&lt;br /&gt;
         STATE=&amp;quot;internal&amp;quot;&lt;br /&gt;
       else&lt;br /&gt;
         INTERNAL_STATE=$(echo $INTERNAL_STATE | sed &amp;quot;s/[0-9]*x[0-9]*//&amp;quot;)&lt;br /&gt;
         EXTERNAL_STATE=$(echo $EXTERNAL_STATE | sed &amp;quot;s/[0-9]*x[0-9]*//&amp;quot;)&lt;br /&gt;
         if [ &amp;quot;$INTERNAL_STATE&amp;quot; = &amp;quot;$EXTERNAL_STATE&amp;quot; ]; then&lt;br /&gt;
           STATE=&amp;quot;mirror&amp;quot;&lt;br /&gt;
         else&lt;br /&gt;
           STATE=&amp;quot;both&amp;quot;&lt;br /&gt;
         fi&lt;br /&gt;
       fi&lt;br /&gt;
&lt;br /&gt;
       case &amp;quot;$STATE&amp;quot; in&lt;br /&gt;
               internal)&lt;br /&gt;
                       screen_mirror&lt;br /&gt;
                       ;;&lt;br /&gt;
               mirror)&lt;br /&gt;
                       screen_external&lt;br /&gt;
                       ;;&lt;br /&gt;
               external)&lt;br /&gt;
                       screen_both&lt;br /&gt;
                       ;;&lt;br /&gt;
               both)&lt;br /&gt;
                       screen_internal&lt;br /&gt;
                       ;;&lt;br /&gt;
               *)&lt;br /&gt;
                       screen_internal&lt;br /&gt;
                       ;;&lt;br /&gt;
       esac&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# based on /etc/acpi/screenblank.sh (Ubuntu 7.10)&lt;br /&gt;
# . /usr/share/acpi-support/power-funcs         # for getXuser&lt;br /&gt;
getXuser() {&lt;br /&gt;
       user=`finger| grep -m1 &amp;quot;:$displaynum &amp;quot; | awk '{print $1}'`&lt;br /&gt;
       if [ x&amp;quot;$user&amp;quot; = x&amp;quot;&amp;quot; ]; then&lt;br /&gt;
               user=`finger| grep -m1 &amp;quot;:$displaynum&amp;quot; | awk '{print $1}'`&lt;br /&gt;
       fi&lt;br /&gt;
       if [ x&amp;quot;$user&amp;quot; != x&amp;quot;&amp;quot; ]; then&lt;br /&gt;
               userhome=`getent passwd $user | cut -d: -f6`&lt;br /&gt;
               export XAUTHORITY=$userhome/.Xauthority&lt;br /&gt;
       else&lt;br /&gt;
               export XAUTHORITY=&amp;quot;&amp;quot;&lt;br /&gt;
       fi&lt;br /&gt;
}&lt;br /&gt;
# end of getXuser from /usr/share/acpi-support/power-funcs&lt;br /&gt;
#&lt;br /&gt;
for x in /tmp/.X11-unix/*; do&lt;br /&gt;
   displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`&lt;br /&gt;
   getXuser;&lt;br /&gt;
   if [ x&amp;quot;$XAUTHORITY&amp;quot; != x&amp;quot;&amp;quot; ]; then&lt;br /&gt;
       export DISPLAY=&amp;quot;:$displaynum&amp;quot;&lt;br /&gt;
      screen_toggle&lt;br /&gt;
   fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/bash&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script to switch between Internal, VGA and S-video==&lt;br /&gt;
This highly overdone script allows to switch between all combinations of Internal, VGA and S-video out. VGA and and S-video at the same time are not allowed on my hardware (I have a T41 with Radeon 7500), so I masked these combinations out. Instead of disabling the internal display with xrandr, I turn off the backlight. One of the allowed combinations is all displays off, and xorg crashes if turning off all displays with xrandr. The script depends on the debian package acpi-support, which is also found in ubuntu and crunchbang (which is what I am using). The dependency can easily be broken out though. Can easily be modified to fulfill other needs, i.e. if you turn off your backlight with something else than radeontool. There is also an OSD displayed in the upper left corner of all active displays.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bash&amp;gt;&lt;br /&gt;
#/bin/sh&lt;br /&gt;
&lt;br /&gt;
. /usr/share/acpi-support/power-funcs         # for getXuser&lt;br /&gt;
. /etc/default/acpi-support                   # for RADEON_LIGHT&lt;br /&gt;
&lt;br /&gt;
# First prevent concurrent execution&lt;br /&gt;
&lt;br /&gt;
LOCK_FILE=/tmp/swapscreenslock&lt;br /&gt;
WAITING_TIME=1&lt;br /&gt;
LOGGER=&amp;quot;`which logger 2&amp;gt;/dev/null` -i&amp;quot;&lt;br /&gt;
if (set -C; : &amp;gt; $LOCK_FILE) 2&amp;gt;/dev/null; then : ; else&lt;br /&gt;
    # Lock file exists - wait as long as theoretically is needed for the other script to finish and retry&lt;br /&gt;
    sleep $WAITING_TIME&lt;br /&gt;
    if (set -C; : &amp;gt; $LOCK_FILE) 2&amp;gt;/dev/null; then : ; else&lt;br /&gt;
        # Lock file still exists - we should never end up here! Consider removing the lock file.&lt;br /&gt;
        $LOGGER &amp;quot;Lock file exists - earlier call to script stalled? Consider removing lock file \&amp;quot;$LOCK_FILE\&amp;quot;. Exiting.&amp;quot;&lt;br /&gt;
        exit 1&lt;br /&gt;
    fi&lt;br /&gt;
fi&lt;br /&gt;
trap 'rm $LOCK_FILE' EXIT&lt;br /&gt;
&lt;br /&gt;
XRANDR=`which xrandr 2&amp;gt;/dev/null`&lt;br /&gt;
OSD_CAT=`which osd_cat 2&amp;gt;/dev/null`&lt;br /&gt;
LAPTOP=&amp;quot;LVDS&amp;quot;&lt;br /&gt;
VGA=&amp;quot;VGA-0&amp;quot;&lt;br /&gt;
SVIDEO=&amp;quot;S-video&amp;quot;&lt;br /&gt;
VGA_POSITION=&amp;quot;--right-of $LAPTOP&amp;quot;&lt;br /&gt;
#VGA_POSITION=&amp;quot;--same-as $LAPTOP&amp;quot;    # Mirror&lt;br /&gt;
SVIDEO_POSITION=&amp;quot;--right-of $LAPTOP&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OSD_GENERICARGS=&amp;quot;--delay=3 --age=0 --font=-adobe-helvetica-bold-r-normal-*-*-180-*-*-p-*-*-* --colour=green --shadow=1&amp;quot;&lt;br /&gt;
OSD_HOFFSET=25&lt;br /&gt;
OSD_VOFFSET=25&lt;br /&gt;
&lt;br /&gt;
function screen_toggle {&lt;br /&gt;
    # Figure out current state&lt;br /&gt;
    XRANDR_STATUS=`su $user -c &amp;quot;$XRANDR -q&amp;quot;`&lt;br /&gt;
&lt;br /&gt;
    # Laptop is of course always connected, however I'll leave the script this&lt;br /&gt;
    # way for making it easier to make the script a little more generic.&lt;br /&gt;
    LAPTOP_CONN=`echo &amp;quot;$XRANDR_STATUS&amp;quot; | grep ^$LAPTOP | grep &amp;quot; connected&amp;quot;`&lt;br /&gt;
    VGA_CONN=`echo &amp;quot;$XRANDR_STATUS&amp;quot; | grep ^$VGA | grep &amp;quot; connected&amp;quot;`&lt;br /&gt;
    SVIDEO_CONN=`echo &amp;quot;$XRANDR_STATUS&amp;quot; | grep ^$SVIDEO | grep &amp;quot; connected&amp;quot;`&lt;br /&gt;
&lt;br /&gt;
    LAPTOP_STATE=`radeontool light | grep 'looks on'`&lt;br /&gt;
    VGA_STATE=`echo $VGA_CONN | sed 's/.*connected\s\([0-9x+-]*\).*/\1/'`&lt;br /&gt;
    SVIDEO_STATE=`echo $SVIDEO_CONN | sed 's/.*connected\s\([0-9x+-]*\).*/\1/'`&lt;br /&gt;
&lt;br /&gt;
    CONNMASK=0&lt;br /&gt;
    [ -n &amp;quot;$LAPTOP_CONN&amp;quot; ] &amp;amp;&amp;amp; CONNMASK=$(( CONNMASK + 1 ))&lt;br /&gt;
    if [ -n &amp;quot;$VGA_CONN&amp;quot; ]; then &lt;br /&gt;
        CONNMASK=$(( CONNMASK + 2 ))&lt;br /&gt;
        [ -n &amp;quot;$SVIDEO_CONN&amp;quot; ] &amp;amp;&amp;amp; CONNMASK=$(( CONNMASK + 4 ))&lt;br /&gt;
    else&lt;br /&gt;
        # If VGA is not connected, TV will overtake its bit&lt;br /&gt;
        [ -n &amp;quot;$SVIDEO_CONN&amp;quot; ] &amp;amp;&amp;amp; CONNMASK=$(( CONNMASK + 2 ))&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    STATE=0&lt;br /&gt;
    if [ -n &amp;quot;$LAPTOP_STATE&amp;quot; ]; then STATE=$(( STATE + 1 )); fi&lt;br /&gt;
    if [ -n &amp;quot;$VGA_CONN&amp;quot; ]; then &lt;br /&gt;
        [ -n &amp;quot;$VGA_STATE&amp;quot; ] &amp;amp;&amp;amp; STATE=$(( STATE + 2 ))&lt;br /&gt;
        [ -n &amp;quot;$SVIDEO_STATE&amp;quot; ] &amp;amp;&amp;amp; STATE=$(( STATE + 4 ))&lt;br /&gt;
    else&lt;br /&gt;
        # If VGA is not connected, TV will overtake its bit&lt;br /&gt;
        [ -n &amp;quot;$SVIDEO_STATE&amp;quot; ] &amp;amp;&amp;amp; STATE=$(( STATE + 2 ))&lt;br /&gt;
    fi&lt;br /&gt;
  &lt;br /&gt;
    # Go to next state&lt;br /&gt;
    STATE=$(( (STATE+1) % (CONNMASK+1) ))&lt;br /&gt;
&lt;br /&gt;
    # Forbidden states are TV and VGA at the same time, regardless of internal state&lt;br /&gt;
    STATE=$(( STATE % 6 ))&lt;br /&gt;
&lt;br /&gt;
    # If no screen is listed as connected, probably xrandr failed - do nothing.&lt;br /&gt;
    if [ $CONNMASK -ne 0 ]; then&lt;br /&gt;
        OSDTEXT=&lt;br /&gt;
&lt;br /&gt;
        if [ -n &amp;quot;$VGA_CONN&amp;quot; ]; then &lt;br /&gt;
            # Turn on or off external VGA&lt;br /&gt;
            if [ $(( (STATE &amp;gt;&amp;gt; 1) % 2 )) -ne 0 ]; then &lt;br /&gt;
                OSDTEXT=&amp;quot;$OSDTEXT $VGA&amp;quot;&lt;br /&gt;
                su $user -c &amp;quot;$XRANDR --output $VGA $VGA_POSITION --auto&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                su $user -c &amp;quot;$XRANDR --output $VGA --off&amp;quot;&lt;br /&gt;
            fi&lt;br /&gt;
&lt;br /&gt;
            # Turn on or off S-Video output&lt;br /&gt;
            if [ $(( (STATE &amp;gt;&amp;gt; 2) % 2 )) -ne 0 ]; then &lt;br /&gt;
                OSDTEXT=&amp;quot;$OSDTEXT $SVIDEO&amp;quot;&lt;br /&gt;
                su $user -c &amp;quot;$XRANDR --output $SVIDEO $SVIDEO_POSITION --auto&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                [ -n &amp;quot;$SVIDEO_CONN&amp;quot; ] &amp;amp;&amp;amp; su $user -c &amp;quot;$XRANDR --output $SVIDEO --off&amp;quot;&lt;br /&gt;
            fi&lt;br /&gt;
        else&lt;br /&gt;
            # If VGA is not connected, TV will overtake its bit&lt;br /&gt;
&lt;br /&gt;
            # Turn on or off S-Video output&lt;br /&gt;
            if [ $(( (STATE &amp;gt;&amp;gt; 1) % 2 )) -ne 0 ]; then &lt;br /&gt;
                OSDTEXT=&amp;quot;$OSDTEXT $SVIDEO&amp;quot;&lt;br /&gt;
                su $user -c &amp;quot;$XRANDR --output $SVIDEO $SVIDEO_POSITION --auto&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
                [ -n &amp;quot;$SVIDEO_CONN&amp;quot; ] &amp;amp;&amp;amp; su $user -c &amp;quot;$XRANDR --output $SVIDEO --off&amp;quot;&lt;br /&gt;
            fi&lt;br /&gt;
        fi&lt;br /&gt;
&lt;br /&gt;
        # Never turn on or off internal screen - only turn on or off the backlight.&lt;br /&gt;
        # Do this after the xrandr calls above, during which the backlight&lt;br /&gt;
        # might go on.&lt;br /&gt;
        if [ $(( STATE % 2 )) -ne 0 ]; then&lt;br /&gt;
            if pidof xscreensaver &amp;gt;/dev/null; then &lt;br /&gt;
                su $user -c &amp;quot;xscreensaver-command -unthrottle&amp;quot;&lt;br /&gt;
            fi  &lt;br /&gt;
            if [ x$RADEON_LIGHT = xtrue ]; then&lt;br /&gt;
                [ -x /usr/sbin/radeontool ] &amp;amp;&amp;amp; radeontool light on&lt;br /&gt;
            fi  &lt;br /&gt;
            if pidof xscreensaver &amp;gt;/dev/null; then&lt;br /&gt;
                su $user -c &amp;quot;xscreensaver-command -deactivate&amp;quot;&lt;br /&gt;
            fi  &lt;br /&gt;
            su $user -c &amp;quot;xset dpms force on&amp;quot;&lt;br /&gt;
            OSDTEXT=&amp;quot;$OSDTEXT $LAPTOP&amp;quot;&lt;br /&gt;
        else&lt;br /&gt;
            if [ `pidof xscreensaver` ]; then&lt;br /&gt;
                su $user -c &amp;quot;(xscreensaver-command -throttle)&amp;quot;&lt;br /&gt;
            fi&lt;br /&gt;
            # Not calling xset to turn off dpms prohibits key presses from&lt;br /&gt;
            # turning the backlight back on all the time. Do make sure to have&lt;br /&gt;
            # RADEON_LIGHT enabled though. The rest of the script works even&lt;br /&gt;
            # though RADEON_LIGHT left disabled, the only effect is that the&lt;br /&gt;
            # laptop panel will always be considered &amp;quot;on&amp;quot;.&lt;br /&gt;
            #su $user -c &amp;quot;xset dpms force off&amp;quot;&lt;br /&gt;
            if [ x$RADEON_LIGHT = xtrue ]; then&lt;br /&gt;
                [ -x /usr/sbin/radeontool ] &amp;amp;&amp;amp; radeontool light off&lt;br /&gt;
            fi&lt;br /&gt;
        fi&lt;br /&gt;
&lt;br /&gt;
        $LOGGER Currently active GPU outputs: $OSDTEXT&lt;br /&gt;
&lt;br /&gt;
        # Wait a little for the hardware to reach the new state&lt;br /&gt;
        #sleep $WAITING_TIME&lt;br /&gt;
&lt;br /&gt;
        # Figure out current state again, to put the OSD on the right places.&lt;br /&gt;
        XRANDR_STATUS=`su $user -c &amp;quot;$XRANDR -q&amp;quot;`&lt;br /&gt;
&lt;br /&gt;
        VGA_CONN=`echo &amp;quot;$XRANDR_STATUS&amp;quot; | grep ^$VGA | grep &amp;quot; connected&amp;quot;`&lt;br /&gt;
        SVIDEO_CONN=`echo &amp;quot;$XRANDR_STATUS&amp;quot; | grep ^$SVIDEO | grep &amp;quot; connected&amp;quot;`&lt;br /&gt;
&lt;br /&gt;
        VGA_STATE=`echo $VGA_CONN | sed 's/.*connected\s\([0-9x+-]*\).*/\1/'`&lt;br /&gt;
        SVIDEO_STATE=`echo $SVIDEO_CONN | sed 's/.*connected\s\([0-9x+-]*\).*/\1/'`&lt;br /&gt;
&lt;br /&gt;
        VGA_HOFFSET=$(( `echo $VGA_STATE | sed 's/[0-9x]*\([+-][0-9]*\).*/\1/'` + OSD_HOFFSET ))&lt;br /&gt;
        VGA_VOFFSET=$(( `echo $VGA_STATE | sed 's/[0-9x]*[+-][0-9]*\([+-][0-9]*\)/\1/'` + OSD_VOFFSET ))&lt;br /&gt;
        SVIDEO_HOFFSET=$(( `echo $SVIDEO_STATE | sed 's/[0-9x]*\([+-][0-9]*\).*/\1/'` + OSD_HOFFSET ))&lt;br /&gt;
        SVIDEO_VOFFSET=$(( `echo $SVIDEO_STATE | sed 's/[0-9x]*[+-][0-9]*\([+-][0-9]*\)/\1/'` + OSD_VOFFSET ))&lt;br /&gt;
&lt;br /&gt;
        # On screen display. &lt;br /&gt;
        if [ -n &amp;quot;$OSD_CAT&amp;quot; ] ; then &lt;br /&gt;
            su $user -c &amp;quot;echo $OSDTEXT | $OSD_CAT $OSD_GENERICARGS --offset=$OSD_HOFFSET --indent=$OSD_VOFFSET - &amp;amp;&amp;quot;&lt;br /&gt;
            [ -n &amp;quot;$VGA_CONN&amp;quot; ] &amp;amp;&amp;amp; su $user -c &amp;quot;echo $OSDTEXT | $OSD_CAT $OSD_GENERICARGS --offset=$VGA_VOFFSET --indent=$VGA_HOFFSET - &amp;amp;&amp;quot;&lt;br /&gt;
            [ -n &amp;quot;$SVIDEO_CONN&amp;quot; ] &amp;amp;&amp;amp; su $user -c &amp;quot;echo $OSDTEXT | $OSD_CAT $OSD_GENERICARGS --offset=$SVIDEO_HOFFSET --indent=$SVIDEO_VOFFSET - &amp;amp;&amp;quot;&lt;br /&gt;
        fi&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Snippet borrowed from /etc/acpi/lid.sh&lt;br /&gt;
for x in /tmp/.X11-unix/*; do&lt;br /&gt;
   displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`&lt;br /&gt;
   getXuser;&lt;br /&gt;
   if [ x&amp;quot;$XAUTHORITY&amp;quot; != x&amp;quot;&amp;quot; ]; then&lt;br /&gt;
       export DISPLAY=&amp;quot;:$displaynum&amp;quot;&lt;br /&gt;
      screen_toggle&lt;br /&gt;
   fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/bash&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If neither VGA nor S-video are connected, the script will only flip on and off the backlight. If one output is connected, be it VGA or S-video, the sequence will be 1) Internal, 2) VGA/S-video (backlight off), 3) Internal+VGA/S-video, 0) all off. If both a monitor and a TV are connected, the sequence will be 1) Internal, 2) VGA (backlight off), 3) Internal+VGA, 4) S-video (backlight off), 5) Internal+S-video, 0) all off.&lt;br /&gt;
&lt;br /&gt;
== A Python Toggle script ==&lt;br /&gt;
This is a somewhat over-elaborate script which could be cut down when run by the /usr/local/sbin/toggle-display.sh script above. It was written to explore all the possibilities rather than economy of execution. The functions 'toggle_full', 'position', 'toggle_limited' and the OptionParser in 'main'  may be omitted with suitable changes to function7. The appropriate outputs can be specified on the command line and it is not necessary to call it via acpi.&lt;br /&gt;
eg you can run it as {{cmduser|/usr/local/bin/toggle.py --help}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
 #! /usr/bin/python&lt;br /&gt;
 # -*- coding: utf-8 -*-&lt;br /&gt;
 #&lt;br /&gt;
 # stinkpad(a)blueyonder.co.uk	2007-11-26&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;Toggle internal and external displays (equivalent to ThinkPad Fn7)&lt;br /&gt;
 Simple; cloned: on+off, on+on, off+on. &lt;br /&gt;
 Full; as simple plus xinerama: right, below,  left, above. &lt;br /&gt;
 Limited; as full but display will overlap if virtual screen is too small. &lt;br /&gt;
 Use 'xrandr -q' to determine output names. &lt;br /&gt;
 Further information: http://www.thinkwiki.org/wiki/Xorg_RandR_1.2 &lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 __usage__ = &amp;quot;usage: %prog [--help]|[[-i internal][-e external][-d displays]]&amp;quot;&lt;br /&gt;
 __version__ = &amp;quot;toggle [djclark.eu 2007-11-26]&amp;quot;&lt;br /&gt;
 #&lt;br /&gt;
 # Output names; Intel: LVDS VGA TV TMDS-1 TMDS-2&lt;br /&gt;
 #               ATI:   LVDS VGA-0 S-video DVI-0&lt;br /&gt;
 LAPTOP = 'LVDS' &lt;br /&gt;
 MONITOR = 'VGA'&lt;br /&gt;
 SEQUENCE = 'simple'&lt;br /&gt;
 #&lt;br /&gt;
 import sys&lt;br /&gt;
 import os&lt;br /&gt;
 import re&lt;br /&gt;
&lt;br /&gt;
 # &amp;quot;LVDS connected 1024x768+0+0 (normal left inverted right) 304mm x 228mm&amp;quot;&lt;br /&gt;
 REGEX_OUTPUT = re.compile(r&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 	(?x)					# ignore whitespace&lt;br /&gt;
 	^					# start of string&lt;br /&gt;
 	(?P&amp;lt;output&amp;gt;[A-Za-z0-9\-]*)[ ] 		# LVDS VGA etc&lt;br /&gt;
 	(?P&amp;lt;connect&amp;gt;(dis)?connected)[ ]		# dis/connected&lt;br /&gt;
 	((					# a group&lt;br /&gt;
  	(?P&amp;lt;width&amp;gt;\d+)x 			# either 1024x768+0+0&lt;br /&gt;
 	(?P&amp;lt;height&amp;gt;\d+)[+]  &lt;br /&gt;
  	(?P&amp;lt;horizontal&amp;gt;\d+)[+]&lt;br /&gt;
 	(?P&amp;lt;vertical&amp;gt;\d+)&lt;br /&gt;
 	)|[\D])					# or not a digit&lt;br /&gt;
 	.*					# ignore rest of line&lt;br /&gt;
 	&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 # &amp;quot;Screen 0: minimum 320 x 200, current 1024 x 768, maximum 2624 x 1968&amp;quot;&lt;br /&gt;
 REGEX_SCREEN = re.compile(r&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 	(?x) 				# ignore whitespace&lt;br /&gt;
 	^				# start of string&lt;br /&gt;
 	Screen[ ]			&lt;br /&gt;
 	(?P&amp;lt;screen&amp;gt;\d)[: ]+&lt;br /&gt;
 	minimum[ ]&lt;br /&gt;
 	(?P&amp;lt;minWidth&amp;gt;\d+)[ x]+&lt;br /&gt;
 	(?P&amp;lt;minHeight&amp;gt;\d+)[, ]+&lt;br /&gt;
 	current[ ]+&lt;br /&gt;
 	(?P&amp;lt;curWidth&amp;gt;\d+)[ x]+&lt;br /&gt;
 	(?P&amp;lt;curHeight&amp;gt;\d+)[, ]+&lt;br /&gt;
 	maximum[ ]+&lt;br /&gt;
 	(?P&amp;lt;maxWidth&amp;gt;\d+)[ x]+&lt;br /&gt;
 	(?P&amp;lt;maxHeight&amp;gt;\d+)&lt;br /&gt;
 	&amp;quot;&amp;quot;&amp;quot;)	&lt;br /&gt;
&lt;br /&gt;
 def toggle_simple(d0, d1):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Toggle display states: on+off, on+on, off+on&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if d1['connect'] == 'disconnected': 	# external unplugged&lt;br /&gt;
        return ('auto','off',&amp;quot;&amp;quot;) 		#     switch off external&lt;br /&gt;
    if d1['width'] is 0: 			# external off&lt;br /&gt;
        return ('auto','auto',&amp;quot;&amp;quot;) 		#     both on&lt;br /&gt;
    if d0['width'] is 0: 			# laptop off&lt;br /&gt;
        return ('auto','off',&amp;quot;&amp;quot;) 		#    laptop on&lt;br /&gt;
    return ('off','auto',&amp;quot;&amp;quot;) 			# both on, laptop off&lt;br /&gt;
&lt;br /&gt;
 def toggle_full(d0, d1):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Toggle display states: 1+0, 1+1, 0+1, 1+E, 1+S, 1+W, 1+N&amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    if d1['connect'] == 'disconnected': 	# external unplugged&lt;br /&gt;
        return ('auto','off',&amp;quot;&amp;quot;) 		#     switch off external&lt;br /&gt;
    place = '--%s ' + d0['output']&lt;br /&gt;
    if d1['width'] == 0: 			# external off&lt;br /&gt;
        return ('auto','auto',place%'same-as') 	#     external on&lt;br /&gt;
    if d0['width'] == 0: 			# laptop off&lt;br /&gt;
        return ('auto','off',&amp;quot;&amp;quot;) 		#    laptop on&lt;br /&gt;
    if d1['horizontal'] &amp;gt; 0: 			# external to right&lt;br /&gt;
        return ('auto','auto',place%'below') 	#     make below&lt;br /&gt;
    if d1['vertical'] &amp;gt; 0: 			# external below&lt;br /&gt;
        return ('auto','auto',place%'left-of') 	#     make left&lt;br /&gt;
    if d0['horizontal'] &amp;gt; 0: 			# external left&lt;br /&gt;
        return ('auto','auto',place%'above') 	#     make above&lt;br /&gt;
    if d0['vertical'] &amp;gt; 0: 			# external above&lt;br /&gt;
        return ('off','auto',&amp;quot;&amp;quot;)  		#     laptop off&lt;br /&gt;
    return ('auto','auto',place%'right-of') 	# is same, make right&lt;br /&gt;
&lt;br /&gt;
 def position(orientation, da, db, screen):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Calculate offset position of second display&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    p = 'auto --pos %sx%s'&lt;br /&gt;
    if orientation == 'V':&lt;br /&gt;
        if (da['height'] + db['height']) &amp;lt;= screen['maxHeight']:&lt;br /&gt;
            return p%(0, da['height'])&lt;br /&gt;
        return p%(0, screen['maxHeight'] - db['height'])&lt;br /&gt;
    else:&lt;br /&gt;
        if (da['width'] + db['width']) &amp;lt;= screen['maxWidth']:&lt;br /&gt;
            return p%(da['width'],0)&lt;br /&gt;
        return p%(screen['maxWidth'] - db['width'],0)&lt;br /&gt;
&lt;br /&gt;
 def toggle_limited(d0, d1, sz):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Toggle display states (overlapped): 1+0,1+1,0+1,1+E,1+S,1+W,1+N&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if d1['connect'] == 'disconnected': 	# external unplugged&lt;br /&gt;
        return ('auto','off') 			#     switch off external&lt;br /&gt;
    if d1['width'] == 0: 				# external off&lt;br /&gt;
        return ('auto --pos 0x0','auto --pos 0x0') 	#     both on&lt;br /&gt;
    if d0['width'] == 0: 				# laptop off&lt;br /&gt;
        return ('auto --pos 0x0','off') 		#     laptop on&lt;br /&gt;
    if d1['horizontal'] &amp;gt; 0: 				# external to right&lt;br /&gt;
        return ('auto --pos 0x0',position('V',d0,d1,sz)) #     put *below&lt;br /&gt;
    if d1['vertical'] &amp;gt; 0: 				# external below&lt;br /&gt;
        return (position('H',d1,d0,sz),'auto --pos 0x0') #     put *left&lt;br /&gt;
    if d0['horizontal'] &amp;gt; 0: 				# external left&lt;br /&gt;
        return (position('V',d1,d0,sz),'auto --pos 0x0') #     put *above&lt;br /&gt;
    if d0['vertical'] &amp;gt; 0: 				# external above&lt;br /&gt;
        return ('off','auto --pos 0x0')  		#     laptop off&lt;br /&gt;
    return ('auto --pos 0x0',position('H',d0,d1,sz)) 	# both, put*right&lt;br /&gt;
&lt;br /&gt;
 class DisplayNameError(UnboundLocalError):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Internal or External Display Name not found by xrandr -q &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 def function7(disp0=LAPTOP, disp1=MONITOR, seq=SEQUENCE):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Use xrandr to read current display state and change state&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    for line in os.popen('xrandr -q').read().splitlines():&lt;br /&gt;
        if line.startswith(disp0,0) :&lt;br /&gt;
            d0_state = REGEX_OUTPUT.match(line).groupdict()&lt;br /&gt;
        elif line.startswith(disp1,0):&lt;br /&gt;
            d1_state = REGEX_OUTPUT.match(line).groupdict()&lt;br /&gt;
        elif line.startswith('Screen',0):&lt;br /&gt;
            screen_size = REGEX_SCREEN.match(line).groupdict()&lt;br /&gt;
    for i in ('width','height','horizontal','vertical'):&lt;br /&gt;
        try:&lt;br /&gt;
            d0_state[i] = int(d0_state[i])&lt;br /&gt;
        except TypeError:&lt;br /&gt;
            d0_state[i] = 0&lt;br /&gt;
        except UnboundLocalError:&lt;br /&gt;
            raise DisplayNameError, 'Internal Display: %s not found'% disp0&lt;br /&gt;
        try:&lt;br /&gt;
            d1_state[i] = int(d1_state[i])&lt;br /&gt;
        except TypeError:&lt;br /&gt;
            d1_state[i] = 0&lt;br /&gt;
        except UnboundLocalError:&lt;br /&gt;
            raise DisplayNameError, 'External Display: %s not found'% disp1&lt;br /&gt;
    for i in screen_size.keys():&lt;br /&gt;
        try:&lt;br /&gt;
            screen_size[i] = int(screen_size[i])&lt;br /&gt;
        except TypeError:&lt;br /&gt;
            screen_size[i] = 0&lt;br /&gt;
    #&lt;br /&gt;
    toggle = toggle_simple&lt;br /&gt;
    xrandr ='xrandr --output '+disp0+' --%s --output '+disp1+' --%s %s'&lt;br /&gt;
    if seq == 'full':&lt;br /&gt;
        toggle = toggle_full&lt;br /&gt;
    if seq == 'limited':&lt;br /&gt;
        toggle = toggle_limited&lt;br /&gt;
        xrandr ='xrandr --output '+disp0+' --%s --output '+disp1+' --%s'&lt;br /&gt;
        os.popen(xrandr % toggle(d0_state, d1_state, screen_size))&lt;br /&gt;
    else:&lt;br /&gt;
        os.popen(xrandr % toggle(d0_state, d1_state))&lt;br /&gt;
&lt;br /&gt;
 def main():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Command line options &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    global LAPTOP,MONITOR,SEQUENCE&lt;br /&gt;
    from optparse import OptionParser&lt;br /&gt;
    p = OptionParser(usage=__usage__, version=__version__, description=__doc__)  &lt;br /&gt;
    p.set_defaults(internal=LAPTOP, external=MONITOR, displays=SEQUENCE)&lt;br /&gt;
    p.add_option('-i','--internal', dest=&amp;quot;internal&amp;quot;, metavar=LAPTOP,&lt;br /&gt;
 	help=&amp;quot;internal display&amp;quot;)&lt;br /&gt;
    p.add_option('-e','--external', dest=&amp;quot;external&amp;quot;, metavar=MONITOR,&lt;br /&gt;
  	help=&amp;quot;external display&amp;quot;)&lt;br /&gt;
    p.add_option('-d','--displays', dest=&amp;quot;displays&amp;quot;, action=&amp;quot;store&amp;quot;,&lt;br /&gt;
 	choices=('simple', 'limited', 'full'), metavar=SEQUENCE,&lt;br /&gt;
 	help='simple/limited/full')&lt;br /&gt;
    (opt, args) = p.parse_args()&lt;br /&gt;
    try:&lt;br /&gt;
        function7(opt.internal, opt.external, opt.displays)&lt;br /&gt;
    except DisplayNameError, err:&lt;br /&gt;
        print '\n'+str(err)+'\n'&lt;br /&gt;
        print os.popen('xrandr -q').read()&lt;br /&gt;
 #&lt;br /&gt;
 if __name__ == '__main__': 	#only when run from cmd line&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This modified thinkpad-fn-f7 calls the toggle python script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bash&amp;gt;&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 # usr/local/sbin/toggle-display.sh &lt;br /&gt;
 # based on /etc/acpi/screenblank.sh (Ubuntu 7.10)&lt;br /&gt;
 #&lt;br /&gt;
 # . /usr/share/acpi-support/power-funcs         # for getXuser&lt;br /&gt;
 umask 022;&lt;br /&gt;
 PATH=&amp;quot;$PATH:/usr/bin/X11&amp;quot;&lt;br /&gt;
 getXuser() {&lt;br /&gt;
        user=`finger| grep -m1 &amp;quot;:$displaynum &amp;quot; | awk '{print $1}'`&lt;br /&gt;
        if [ x&amp;quot;$user&amp;quot; = x&amp;quot;&amp;quot; ]; then&lt;br /&gt;
                user=`finger| grep -m1 &amp;quot;:$displaynum&amp;quot; | awk '{print $1}'`&lt;br /&gt;
        fi&lt;br /&gt;
        if [ x&amp;quot;$user&amp;quot; != x&amp;quot;&amp;quot; ]; then&lt;br /&gt;
                userhome=`getent passwd $user | cut -d: -f6`&lt;br /&gt;
                export XAUTHORITY=$userhome/.Xauthority&lt;br /&gt;
        else&lt;br /&gt;
                export XAUTHORITY=&amp;quot;&amp;quot;&lt;br /&gt;
        fi&lt;br /&gt;
 }&lt;br /&gt;
 # end of getXuser from /usr/share/acpi-support/power-funcs&lt;br /&gt;
 #&lt;br /&gt;
 for x in /tmp/.X11-unix/*; do&lt;br /&gt;
    displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`&lt;br /&gt;
    getXuser;&lt;br /&gt;
    if [ x&amp;quot;$XAUTHORITY&amp;quot; != x&amp;quot;&amp;quot; ]; then&lt;br /&gt;
        export DISPLAY=&amp;quot;:$displaynum&amp;quot;&lt;br /&gt;
 ##     . /usr/share/acpi-support/screenblank.sh&lt;br /&gt;
        /usr/local/bin/toggle.py&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/bash&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Python XRandR===&lt;br /&gt;
[[http://www.glatzor.de/blog/blog-details/article/initial-release-of-python-xrandr Python XRandR]] is a set of python bindings to xrandr. The code is currently in development and the following code though much simpler than the python code above may not work reliably.&lt;br /&gt;
&lt;br /&gt;
  from xrandr import xrandr&lt;br /&gt;
  def toggle_simple():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Toggle display states: on+off, off+on, on+on off+off&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    screen = xrandr.get_current_screen()&lt;br /&gt;
    outputs = screen.get_outputs()&lt;br /&gt;
    for o in outputs:&lt;br /&gt;
        if o.is_connected():&lt;br /&gt;
            if o.is_active():&lt;br /&gt;
                o.disable()&lt;br /&gt;
                print 'disable %s'% o.name&lt;br /&gt;
            else:&lt;br /&gt;
                o.set_to_preferred_mode()&lt;br /&gt;
                print 'set to preferred mode %s'% o.name&lt;br /&gt;
                break&lt;br /&gt;
    screen.apply_output_config()&lt;br /&gt;
&lt;br /&gt;
== Having Fn-F7 run a RandR GUI ==&lt;br /&gt;
Instead of using it to toggle various screen(s) configurations, one may want to have it run a RandR GUI, such as grandr.&lt;br /&gt;
&lt;br /&gt;
The following Debian wishlist bugs against the acpi-support package have patches attached that implement this behaviour using acpid; these patches are not Debian-specific, and actually provide example configuration for anyone interested into this:&lt;br /&gt;
 &lt;br /&gt;
* http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=515794&lt;br /&gt;
* http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=515796&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
[[http://gitweb.freedesktop.org/?p=xorg/app/grandr.git grandr]] graphical interface to xrandr  using GTK+ libraries.&lt;br /&gt;
&lt;br /&gt;
[[https://edge.launchpad.net/python-xrandr python-xrandr]] Python bindings to xrandr which should enable a less clunky version of the python script above. Under development.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>Newacct</name></author>
		
	</entry>
</feed>