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
|
# Copyright (C) 2023 Tomasz Kramkowski <tomasz@kramkow.ski>
# SPDX-License-Identifier: MIT
import argparse
import math
import sys
from pathlib import Path
from typing import Type, TypeVar
T = TypeVar("T", bound="LogFloat")
class LogFloat(float):
@classmethod
def from_val(cls: Type[T], val: int) -> T:
return cls(math.log(val + 1))
@classmethod
def from_pct(cls: Type[T], pct: float, log_max: "LogFloat") -> T:
return cls(pct / 100.0 * log_max)
def to_val(self) -> int:
return round(math.e**self) - 1
def __add__(self, other: "LogFloat") -> "LogFloat":
return LogFloat(super().__add__(other))
def _parse_limit(limit: str, log_max_brightness: LogFloat) -> int:
if limit[-1] == "%":
return LogFloat.from_pct(float(limit[:-1]), log_max_brightness).to_val()
return int(limit)
def main(argv: list[str] = sys.argv) -> int:
ap = argparse.ArgumentParser(description="Adjust sysfs backlight with a log scale")
ap.add_argument(
"-m",
"--min",
help="An artificial minimum brightness (percentage or raw value) limit",
default="0",
)
ap.add_argument(
"-M",
"--max",
help="An artificial maximum brightness (percentage or raw value) limit",
)
ap.add_argument(
"backlight",
help="Path to sysfs backlight (e.g. /sys/class/backlight/amdgpu_bl0)",
)
ap.add_argument(
"adjustment",
help="Percentage adjustment (e.g. +10 or -6.25) or absolute value (e.g. 50)",
)
args = ap.parse_args(argv[1:])
backlight = Path(args.backlight)
with open(backlight / "brightness") as f:
brightness = int(f.read().rstrip())
log_brightness = LogFloat.from_val(brightness)
with open(backlight / "max_brightness") as f:
max_brightness = int(f.read().rstrip())
log_max_brightness = LogFloat.from_val(max_brightness)
if args.adjustment[0] in {"-", "+"}:
diff = LogFloat.from_pct(float(args.adjustment), log_max_brightness)
new_brightness = (log_brightness + diff).to_val()
if diff != 0 and new_brightness == brightness:
new_brightness += int(math.copysign(1, diff))
else:
new_brightness = LogFloat.from_pct(
float(args.adjustment), log_max_brightness
).to_val()
max_limit = max_brightness
if args.max is not None:
max_limit = _parse_limit(args.max, log_max_brightness)
min_limit = _parse_limit(args.min, log_max_brightness)
new_brightness = max(min_limit, min(new_brightness, max_limit))
with open(backlight / "brightness", "w") as f:
f.write(str(new_brightness))
return 0
|