|
@ -31,12 +31,12 @@ Date: 2023 Mar 04 |
|
|
import Xlib.display |
|
|
import Xlib.display |
|
|
import Xlib.ext.randr |
|
|
import Xlib.ext.randr |
|
|
import configparser |
|
|
import configparser |
|
|
from operator import itemgetter |
|
|
|
|
|
from util import edit_distance |
|
|
from util import edit_distance |
|
|
from util.egalax import get_egalax_drm_pure_name |
|
|
from util.egalax import get_egalax_drm_pure_name |
|
|
|
|
|
import subprocess |
|
|
|
|
|
|
|
|
CONFIG_NAME = "conf/desktop.conf" |
|
|
CONFIG_NAME = "conf/desktop.conf" |
|
|
|
|
|
XRANDR = "/usr/bin/xrandr" |
|
|
|
|
|
|
|
|
def read_config(): |
|
|
def read_config(): |
|
|
"""Reads config file of desktop setup |
|
|
"""Reads config file of desktop setup |
|
@ -69,7 +69,11 @@ def all_connected_monitor(): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_edid_name(drm_name: str): |
|
|
def get_edid_name(drm_name: str): |
|
|
"""Change eGalax DRM name to atom name""" |
|
|
"""Change eGalax DRM name to atom name |
|
|
|
|
|
|
|
|
|
|
|
This function is very sensitive to kernel version and might not work |
|
|
|
|
|
with some kernels. |
|
|
|
|
|
""" |
|
|
card_num, name = drm_name[4:].split("-", maxsplit=1) |
|
|
card_num, name = drm_name[4:].split("-", maxsplit=1) |
|
|
first, second = name.rsplit("-", maxsplit=1) |
|
|
first, second = name.rsplit("-", maxsplit=1) |
|
|
return first + "-" + card_num + "-" + second |
|
|
return first + "-" + card_num + "-" + second |
|
@ -101,7 +105,7 @@ def prepare_monitors(config): |
|
|
main = config["DEFAULT"]["MainDisplay"] |
|
|
main = config["DEFAULT"]["MainDisplay"] |
|
|
all_monitors = list(all_connected_monitor()) |
|
|
all_monitors = list(all_connected_monitor()) |
|
|
egalax_drm = get_egalax_drm_pure_name() |
|
|
egalax_drm = get_egalax_drm_pure_name() |
|
|
egalax_name = get_edid_name(egalax_drm) |
|
|
egalax_name = get_edid_name(egalax_drm) if egalax_drm else None |
|
|
egalax_monitor = None |
|
|
egalax_monitor = None |
|
|
main_monitor = None |
|
|
main_monitor = None |
|
|
for mon in all_monitors: |
|
|
for mon in all_monitors: |
|
@ -126,6 +130,80 @@ def prepare_monitors(config): |
|
|
return main_monitor, egalax_monitor, all_monitors |
|
|
return main_monitor, egalax_monitor, all_monitors |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def baseline(main, egalax): |
|
|
|
|
|
"""Base of xrandr arguments |
|
|
|
|
|
|
|
|
|
|
|
Both main and egalax are monitor tuples mentioned in prepare_monitors""" |
|
|
|
|
|
if not main and not egalax: |
|
|
|
|
|
return [], None |
|
|
|
|
|
elif not main and egalax: |
|
|
|
|
|
return ["--output", egalax[0], "--primary", |
|
|
|
|
|
"--mode", f"{egalax[1]}x{egalax[2]}"], None |
|
|
|
|
|
elif main and not egalax: |
|
|
|
|
|
return ["--output", main[0], "--primary", |
|
|
|
|
|
"--mode", f"{main[1]}x{main[2]}"], main[0] |
|
|
|
|
|
else: |
|
|
|
|
|
return ["--output", main[0], "--primary", |
|
|
|
|
|
"--mode", f"{main[1]}x{main[2]}", |
|
|
|
|
|
"--output", egalax[0], "--right-of", main[0], |
|
|
|
|
|
"--mode", f"{egalax[1]}x{egalax[1]}"], egalax[0] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def mirror_displays(main, egalax, others: list): |
|
|
|
|
|
base, should_mirror = baseline(main, egalax) |
|
|
|
|
|
if should_mirror: |
|
|
|
|
|
for name, width, height in others: |
|
|
|
|
|
base.extend(["--output", name, "--mode", f"{width}x{height}", |
|
|
|
|
|
"--same-as", main[0], |
|
|
|
|
|
"--scale-from", f"{main[1]}x{main[2]}"]) |
|
|
|
|
|
return base |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def off_displays(main, egalax, others: list): |
|
|
|
|
|
base, should_off = baseline(main, egalax) |
|
|
|
|
|
if should_off: |
|
|
|
|
|
for name, width, height in others: |
|
|
|
|
|
base.extend(["--output", name, "--off"]) |
|
|
|
|
|
return base |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def stand_alone_displays(main, egalax, others: list): |
|
|
|
|
|
base, rightmost = baseline(main, egalax) |
|
|
|
|
|
if rightmost: |
|
|
|
|
|
for name, width, height in others: |
|
|
|
|
|
base.extend(["--output", name, "--mode", f"{width}x{height}", |
|
|
|
|
|
"--right-of", rightmost]) |
|
|
|
|
|
rightmost = name |
|
|
|
|
|
return base |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
POLICY = { |
|
|
|
|
|
'Off': off_displays, |
|
|
|
|
|
'Mirror': mirror_displays, |
|
|
|
|
|
'StandAlone': stand_alone_displays |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def config_xrandr(conf, main, egalax, others: list): |
|
|
|
|
|
"""Executes xrandr with policy in the conf |
|
|
|
|
|
|
|
|
|
|
|
Policies: |
|
|
|
|
|
Policies are about monitors other than main and touch panel monitors. |
|
|
|
|
|
There are three supported policies: |
|
|
|
|
|
- Off: Disables other monitors (default policy if not in config) |
|
|
|
|
|
- Mirror: Mirror other displays from main monitor. |
|
|
|
|
|
- StandAlone: Each monitor is mapped to the right of each other |
|
|
|
|
|
""" |
|
|
|
|
|
try: |
|
|
|
|
|
policy = conf['DEFAULT']['Policy'] |
|
|
|
|
|
except: |
|
|
|
|
|
policy = 'Off' |
|
|
|
|
|
args = POLICY[policy](main, egalax, others) |
|
|
|
|
|
cmd = [XRANDR] + args |
|
|
|
|
|
subprocess.run(cmd) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
if __name__ == "__main__": |
|
|
conf = read_config() |
|
|
conf = read_config() |
|
|
print(prepare_monitors(conf)) |
|
|
main, egalax, others = prepare_monitors(conf) |
|
|
|
|
|
config_xrandr(conf, main, egalax, others) |
|
|