forked from TillmannBerg/Ubuntu-Dell-XPS-15-2019
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathicc-brightness
executable file
·157 lines (123 loc) · 4.97 KB
/
icc-brightness
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#! /usr/bin/env python3
"""Control OLED display brightness by applying ICC color profiles.
icc-brightness brightness max-brightness - set brightness manually
icc-brightness apply - apply brightness from system setting
icc-brightness watch - continuously update to system setting
icc-brightness clean - remove all profiles generated by us
"""
import sys
import os
import subprocess
import time
import fcntl
import signal
import threading
import logging
TEMP_FOLDER = '/tmp'
BACKLIGHT_PATH = '/sys/class/backlight/intel_backlight'
BRIGHTNESS_PATH = os.path.join(BACKLIGHT_PATH, 'brightness')
MAX_BRIGHTNESS_PATH = os.path.join(BACKLIGHT_PATH, 'max_brightness')
CWD = os.path.dirname(__file__)
ICC_BRIGHTNESS_GEN = os.path.join(CWD, 'icc-brightness-gen')
LOCK = threading.Lock()
def clean():
"""Find all profile generated by us and remove them."""
out = subprocess.check_output(['colormgr', 'get-profiles'])
object_path = None
filename = None
for line in out.decode('utf8').split('\n'):
if line.startswith('Object Path:'):
object_path = line.split(':')[1].lstrip()
continue
if line.startswith('Filename:'):
filename = line.split(':')[1].lstrip()
if filename.find('/brightness_') < 0:
continue
logging.info('Removing: %s', filename)
subprocess.run(['colormgr', 'delete-profile', object_path],
check=True)
subprocess.run(['rm', filename], check=True)
def get_object_path(out):
object_path = None
for line in out.decode('utf8').split('\n'):
if line.startswith('Object Path:'):
object_path = line.split(':')[1].lstrip()
break
return object_path
def find_profile(filename):
try:
out = subprocess.check_output(
['colormgr', 'find-profile-by-filename', filename])
except subprocess.CalledProcessError:
return None
return get_object_path(out)
def get_device_id():
out = subprocess.check_output(['colormgr', 'get-devices-by-kind',
'display'])
return get_object_path(out)
last_icc_filename = None
def icc_brightness(brightness, max_brightness):
icc_filename = 'brightness_%d_%d.icc' % (brightness, max_brightness)
logging.debug('Apply profile %s', icc_filename)
object_path = find_profile(icc_filename)
if object_path is None:
icc_filepath = os.path.join(TEMP_FOLDER, icc_filename)
subprocess.run([ICC_BRIGHTNESS_GEN, icc_filepath,
str(brightness), str(max_brightness)], check=True)
subprocess.check_output(['colormgr', 'import-profile', icc_filepath])
object_path = find_profile(icc_filename)
try:
subprocess.run(['colormgr', 'device-add-profile',
get_device_id(), object_path], check=True)
except subprocess.CalledProcessError as ex:
logging.warning('Failed to add profile: %s', ex.stdout)
subprocess.run(['colormgr', 'device-make-profile-default',
get_device_id(), object_path], check=True)
global last_icc_filename
if last_icc_filename is not None and last_icc_filename != icc_filename:
object_path = find_profile(last_icc_filename)
subprocess.run(['colormgr', 'delete-profile', object_path], check=True)
last_icc_filename = icc_filename
def icc_brightness_apply():
with open(BRIGHTNESS_PATH) as infile:
brightness = int(infile.readline())
with open(MAX_BRIGHTNESS_PATH) as infile:
max_brightness = int(infile.readline())
icc_brightness(brightness, max_brightness)
def handler(signum, frame):
if LOCK.acquire(blocking=False):
try:
icc_brightness_apply()
except subprocess.CalledProcessError as ex:
logging.exception('Error during call to icc_brightness')
logging.error(ex.stdout)
except BaseException:
logging.exception('Error during call to icc_brightness')
finally:
LOCK.release()
def main():
logging.basicConfig(level=logging.INFO,
format='%(levelname)s: %(message)s')
if len(sys.argv) == 2 and sys.argv[1] == 'clean':
clean()
elif len(sys.argv) == 2 and sys.argv[1] == 'apply':
icc_brightness_apply()
elif len(sys.argv) == 2 and sys.argv[1] == 'watch':
try:
icc_brightness_apply()
except BaseException:
logging.exception('device-make-profile-default')
signal.signal(signal.SIGIO, handler)
fd = os.open(BACKLIGHT_PATH, os.O_RDONLY)
fcntl.fcntl(fd, fcntl.F_SETSIG, 0)
fcntl.fcntl(fd, fcntl.F_NOTIFY, fcntl.DN_MODIFY| fcntl.DN_MULTISHOT)
while True:
time.sleep(1000000)
elif len(sys.argv) == 3:
brightness = int(sys.argv[1])
max_brightness = int(sys.argv[2])
icc_brightness(brightness, max_brightness)
else:
print(__doc__)
if __name__ == '__main__':
main()