#!/usr/bin/python
# Brightness changer script for Linux systems that don't really support brightness.
# Created by Oleh 'BlaXpirit' Prypin.
# Tested with Python 2.7 and 3.2, but Python 3 is recommended.
usage= """
brightness
- get current brightness setting
brightness restore
- set the brightness to the last used value
brightness <value>
- set the brightness to *value*
brightness inc [step]
brightness dec [step]
- increase or decrease the brightness by *step* (if it's not specified, a default value is used from the configuration file, usually 10% of maximal brightness)
"""
config_file= '/etc/bx_brightness.conf'
########################################
import sys , os , collections , subprocess
def find_backlight_device( ) :
path= '/sys/class/backlight/'
try :
return os .path .join ( path, os .listdir ( path) [ 0 ] )
except :
print ( 'No backlight device found!' )
exit( 2 )
# Settings: (name,(type,default))
s= collections .OrderedDict ( (
( 'device_path' , ( str , find_backlight_device) ) ,
( 'min_brightness' , ( int , lambda :0 ) ) ,
( 'max_brightness' , ( int , lambda :int ( open ( os .path .join ( s[ 'device_path' ] , 'max_brightness' ) ) .read ( ) ) ) ) ,
( 'step' , ( int , lambda :max ( 1 , ( s[ 'max_brightness' ] -s[ 'min_brightness' ] ) //10 ) ) ) ,
( 'brightness' , ( int , lambda :int ( open ( os .path .join ( s[ 'device_path' ] , 'brightness' ) ) .read ( ) ) ) ) ,
) )
# Read settings from config file
try :
for l in open ( config_file) .read ( ) .split ( '\n ' ) :
l= l.split ( '=' , 1 )
if len ( l) == 2 and l[ 0 ] in s:
s[ l[ 0 ] ] = s[ l[ 0 ] ] [ 0 ] ( l[ 1 ] )
except :
pass
# Replace the settings that couldn't be read with defaults
for k, v in s.items ( ) :
if isinstance ( v, tuple ) :
s[ k] = v[ 1 ] ( )
# Makes the number *v* be in range [*minv*, *maxv*]
def btw( minv, v, maxv) :
if v< minv: v= minv
if v> maxv: v= maxv
return v
# Sets the brightess setting and writes it to the 'brightness' file
def set_brightness( b) :
s[ 'brightness' ] = btw( s[ 'min_brightness' ] , b, s[ 'max_brightness' ] )
with open ( os .path .join ( s[ 'device_path' ] , 'brightness' ) , 'w' ) as f:
f.write ( str ( s[ 'brightness' ] ) )
p= sys .argv [ 1 :]
# brightness
if len ( p) == 0 :
print ( '{}/{}' .format ( s[ 'brightness' ] , s[ 'max_brightness' ] ) )
exit( 0 )
# brightness restore
elif len ( p) == 1 and p[ 0 ] == 'restore' :
subprocess .call ( [ 'chmod' , '666' , os .path .join ( s[ 'device_path' ] , 'brightness' ) ] )
set_brightness( s[ 'brightness' ] )
# brightness <value>
elif len ( p) == 1 and p[ 0 ] .isdigit ( ) :
set_brightness( int ( p[ 0 ] ) )
# brightness inc [step]
# brightness dec [step]
elif p[ 0 ] in ( 'inc' , 'dec' ) :
try :
step= int ( p[ 1 ] )
except :
step= s[ 'step' ]
set_brightness( s[ 'brightness' ] +step*( 1 if p[ 0 ] == 'inc' else -1 ) )
else :
print ( usage)
exit( 1 )
# Save settings
e= os .path .exists ( config_file)
with open ( config_file, 'w' ) as f:
f.write ( '\n ' .join ( '{}={}' .format ( *i) for i in s.items ( ) ) )
if not e: subprocess .call ( [ 'chmod' , '666' , config_file] )
IyEvdXNyL2Jpbi9weXRob24KCiMgQnJpZ2h0bmVzcyBjaGFuZ2VyIHNjcmlwdCBmb3IgTGludXggc3lzdGVtcyB0aGF0IGRvbid0IHJlYWxseSBzdXBwb3J0IGJyaWdodG5lc3MuCiMgQ3JlYXRlZCBieSBPbGVoICdCbGFYcGlyaXQnIFByeXBpbi4KCiMgVGVzdGVkIHdpdGggUHl0aG9uIDIuNyBhbmQgMy4yLCBidXQgUHl0aG9uIDMgaXMgcmVjb21tZW5kZWQuCgp1c2FnZT0iIiIKYnJpZ2h0bmVzcwogICAgLSBnZXQgY3VycmVudCBicmlnaHRuZXNzIHNldHRpbmcKCmJyaWdodG5lc3MgcmVzdG9yZQogICAgLSBzZXQgdGhlIGJyaWdodG5lc3MgdG8gdGhlIGxhc3QgdXNlZCB2YWx1ZQoKYnJpZ2h0bmVzcyA8dmFsdWU+CiAgICAtIHNldCB0aGUgYnJpZ2h0bmVzcyB0byAqdmFsdWUqCgpicmlnaHRuZXNzIGluYyBbc3RlcF0KYnJpZ2h0bmVzcyBkZWMgW3N0ZXBdCiAgICAtIGluY3JlYXNlIG9yIGRlY3JlYXNlIHRoZSBicmlnaHRuZXNzIGJ5ICpzdGVwKiAoaWYgaXQncyBub3Qgc3BlY2lmaWVkLCBhIGRlZmF1bHQgdmFsdWUgaXMgdXNlZCBmcm9tIHRoZSBjb25maWd1cmF0aW9uIGZpbGUsIHVzdWFsbHkgMTAlIG9mIG1heGltYWwgYnJpZ2h0bmVzcykKIiIiCgpjb25maWdfZmlsZT0nL2V0Yy9ieF9icmlnaHRuZXNzLmNvbmYnCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgppbXBvcnQgc3lzLG9zLGNvbGxlY3Rpb25zLHN1YnByb2Nlc3MKCmRlZiBmaW5kX2JhY2tsaWdodF9kZXZpY2UoKToKICAgIHBhdGg9Jy9zeXMvY2xhc3MvYmFja2xpZ2h0LycKICAgIHRyeToKICAgICAgICByZXR1cm4gb3MucGF0aC5qb2luKHBhdGgsb3MubGlzdGRpcihwYXRoKVswXSkKICAgIGV4Y2VwdDoKICAgICAgICBwcmludCgnTm8gYmFja2xpZ2h0IGRldmljZSBmb3VuZCEnKQogICAgICAgIGV4aXQoMikKCiMgU2V0dGluZ3M6IChuYW1lLCh0eXBlLGRlZmF1bHQpKQpzPWNvbGxlY3Rpb25zLk9yZGVyZWREaWN0KCgKICAgICgnZGV2aWNlX3BhdGgnICAgLChzdHIsZmluZF9iYWNrbGlnaHRfZGV2aWNlKSksCiAgICAoJ21pbl9icmlnaHRuZXNzJywoaW50LGxhbWJkYTowKSksCiAgICAoJ21heF9icmlnaHRuZXNzJywoaW50LGxhbWJkYTppbnQob3Blbihvcy5wYXRoLmpvaW4oc1snZGV2aWNlX3BhdGgnXSwnbWF4X2JyaWdodG5lc3MnKSkucmVhZCgpKSkpLAogICAgKCdzdGVwJyAgICAgICAgICAsKGludCxsYW1iZGE6bWF4KDEsKHNbJ21heF9icmlnaHRuZXNzJ10tc1snbWluX2JyaWdodG5lc3MnXSkvLzEwKSkpLAogICAgKCdicmlnaHRuZXNzJyAgICAsKGludCxsYW1iZGE6aW50KG9wZW4ob3MucGF0aC5qb2luKHNbJ2RldmljZV9wYXRoJ10sJ2JyaWdodG5lc3MnKSkucmVhZCgpKSkpLAopKQoKIyBSZWFkIHNldHRpbmdzIGZyb20gY29uZmlnIGZpbGUKdHJ5OgogICAgZm9yIGwgaW4gb3Blbihjb25maWdfZmlsZSkucmVhZCgpLnNwbGl0KCdcbicpOgogICAgICAgIGw9bC5zcGxpdCgnPScsMSkKICAgICAgICBpZiBsZW4obCk9PTIgYW5kIGxbMF0gaW4gczoKICAgICAgICAgICAgc1tsWzBdXT1zW2xbMF1dWzBdKGxbMV0pCmV4Y2VwdDoKICAgIHBhc3MKCiMgUmVwbGFjZSB0aGUgc2V0dGluZ3MgdGhhdCBjb3VsZG4ndCBiZSByZWFkIHdpdGggZGVmYXVsdHMKZm9yIGssdiBpbiBzLml0ZW1zKCk6CiAgICBpZiBpc2luc3RhbmNlKHYsdHVwbGUpOgogICAgICAgIHNba109dlsxXSgpCgoKIyBNYWtlcyB0aGUgbnVtYmVyICp2KiBiZSBpbiByYW5nZSBbKm1pbnYqLCAqbWF4dipdCmRlZiBidHcobWludix2LG1heHYpOgogICAgaWYgdjxtaW52OiB2PW1pbnYKICAgIGlmIHY+bWF4djogdj1tYXh2CiAgICByZXR1cm4gdgojIFNldHMgdGhlIGJyaWdodGVzcyBzZXR0aW5nIGFuZCB3cml0ZXMgaXQgdG8gdGhlICdicmlnaHRuZXNzJyBmaWxlCmRlZiBzZXRfYnJpZ2h0bmVzcyhiKToKICAgIHNbJ2JyaWdodG5lc3MnXT1idHcoc1snbWluX2JyaWdodG5lc3MnXSxiLHNbJ21heF9icmlnaHRuZXNzJ10pCiAgICB3aXRoIG9wZW4ob3MucGF0aC5qb2luKHNbJ2RldmljZV9wYXRoJ10sJ2JyaWdodG5lc3MnKSwndycpIGFzIGY6CiAgICAgICAgZi53cml0ZShzdHIoc1snYnJpZ2h0bmVzcyddKSkKCnA9c3lzLmFyZ3ZbMTpdCiMgYnJpZ2h0bmVzcwppZiBsZW4ocCk9PTA6CiAgICBwcmludCgne30ve30nLmZvcm1hdChzWydicmlnaHRuZXNzJ10sc1snbWF4X2JyaWdodG5lc3MnXSkpCiAgICBleGl0KDApCiMgYnJpZ2h0bmVzcyByZXN0b3JlCmVsaWYgbGVuKHApPT0xIGFuZCBwWzBdPT0ncmVzdG9yZSc6CiAgICBzdWJwcm9jZXNzLmNhbGwoWydjaG1vZCcsJzY2Nicsb3MucGF0aC5qb2luKHNbJ2RldmljZV9wYXRoJ10sJ2JyaWdodG5lc3MnKV0pCiAgICBzZXRfYnJpZ2h0bmVzcyhzWydicmlnaHRuZXNzJ10pCiMgYnJpZ2h0bmVzcyA8dmFsdWU+CmVsaWYgbGVuKHApPT0xIGFuZCBwWzBdLmlzZGlnaXQoKToKICAgIHNldF9icmlnaHRuZXNzKGludChwWzBdKSkKIyBicmlnaHRuZXNzIGluYyBbc3RlcF0KIyBicmlnaHRuZXNzIGRlYyBbc3RlcF0KZWxpZiBwWzBdIGluICgnaW5jJywnZGVjJyk6CiAgICB0cnk6CiAgICAgICAgc3RlcD1pbnQocFsxXSkKICAgIGV4Y2VwdDoKICAgICAgICBzdGVwPXNbJ3N0ZXAnXQogICAgc2V0X2JyaWdodG5lc3Moc1snYnJpZ2h0bmVzcyddK3N0ZXAqKDEgaWYgcFswXT09J2luYycgZWxzZSAtMSkpCmVsc2U6CiAgICBwcmludCh1c2FnZSkKICAgIGV4aXQoMSkKCgojIFNhdmUgc2V0dGluZ3MKZT1vcy5wYXRoLmV4aXN0cyhjb25maWdfZmlsZSkKd2l0aCBvcGVuKGNvbmZpZ19maWxlLCd3JykgYXMgZjoKICAgIGYud3JpdGUoJ1xuJy5qb2luKCd7fT17fScuZm9ybWF0KCppKSBmb3IgaSBpbiBzLml0ZW1zKCkpKQppZiBub3QgZTogc3VicHJvY2Vzcy5jYWxsKFsnY2htb2QnLCc2NjYnLGNvbmZpZ19maWxlXSk=