From 62eebad3a3ebf33bc82fdf0f5ae67f6ced60a41e Mon Sep 17 00:00:00 2001 From: Ali Hatami Tajik Date: Mon, 3 Apr 2023 11:10:57 +0330 Subject: [PATCH] Add prepare monitor This function will return setup of the monitor systems. --- conf/desktop.conf | 3 + setup.sh | 5 ++ src/scripts/python/setupmonitor.py | 98 ++++++++++++++++++++++++++++- src/scripts/python/util/__init__.py | 1 + src/scripts/python/util/common.py | 28 +++++++++ src/scripts/python/util/egalax.py | 4 +- 6 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 conf/desktop.conf create mode 100644 src/scripts/python/util/__init__.py diff --git a/conf/desktop.conf b/conf/desktop.conf new file mode 100644 index 0000000..11d68f1 --- /dev/null +++ b/conf/desktop.conf @@ -0,0 +1,3 @@ +[DEFAULT] +MainDisplay=HDMI-3 +Policy=Mirror diff --git a/setup.sh b/setup.sh index ac18cdc..1904692 100755 --- a/setup.sh +++ b/setup.sh @@ -21,6 +21,11 @@ log '.: Setting up sono-os v0.1.0 :.' sleep 1 draw_progress_bar 5 +log 'Installing dependancies ...' +# TODO +sleep 1 + +draw_progress_bar 15 log 'Installing scripts ...' # TODO sleep 1 diff --git a/src/scripts/python/setupmonitor.py b/src/scripts/python/setupmonitor.py index aa43d9e..e054156 100644 --- a/src/scripts/python/setupmonitor.py +++ b/src/scripts/python/setupmonitor.py @@ -28,6 +28,102 @@ Date: 2023 Mar 04 """ +import Xlib.display +import Xlib.ext.randr +import configparser +from operator import itemgetter +from util import edit_distance +from util.egalax import get_egalax_drm_pure_name + +CONFIG_NAME = "conf/desktop.conf" + + +def read_config(): + """Reads config file of desktop setup + + This function will reeds the config file of desktop. Config file contins + a default monitor port name which will be the main Monitor display. + + NOTE: eGalax devide will be detected automatically from the /dev mountings. + """ + config = configparser.ConfigParser() + read = config.read(CONFIG_NAME) + if not read: + raise FileNotFoundError("Desktop config file not found") + return config + + +def all_connected_monitor(): + """Generates all connected monitors + + as a tuple of (atom name: str, width, height) + """ + display = Xlib.display.Display() + root = display.screen().root + for m in root.xrandr_get_monitors().monitors: + yield ( + display.get_atom_name(m.name), + m.width_in_pixels, + m.height_in_pixels, + ) + + +def get_edid_name(drm_name): + """Change eGalax DRM name to atom name""" + return "#TODO" + + +def prepare_monitors(config): + """Prepare monitor names + + + Rules: + - Use default monitor port as the main monitor if it is connected + - If default monitor is not connected then use a monitor with + minimum edit distance. + + - Use eGalax as touchpanel and if it's not connected return None. + + - other connected monitors will be returned as a list + + each monitor is returen as a + + Returns + tuple: of + - main monitor -> tuple | None if no monitor available other than + touchpanel + - touchpanel -> tuple | None if touchpanel did not exist + - other -> list: this list may be empty if there is no other + monitor connected + """ + main = config["DEFAULT"]["MainDisplay"] + all_monitors = list(all_connected_monitor()) + egalax_drm = get_egalax_drm_pure_name() + egalax_name = get_edid_name(egalax_drm) + egalax_monitor = None + main_monitor = None + for mon in all_monitors: + if egalax_name == mon[0]: + egalax_monitor = mon + if main == mon[0]: + main_monitor = mon + if egalax_monitor: + all_monitors.remove(egalax_monitor) + if not main_monitor: + try: + min_monitor = min( + all_monitors, + key=lambda x: edit_distance(main, x, len(main), len(x)), + ) + main_monitor = min_monitor + except: + main_monitor = None + assert len(all_monitors) == 0 + if main_monitor: + all_monitors.remove(main_monitor) + return main_monitor, egalax_monitor, all_monitors + if __name__ == "__main__": - pass + conf = read_config() + print(prepare_monitors(conf)) diff --git a/src/scripts/python/util/__init__.py b/src/scripts/python/util/__init__.py new file mode 100644 index 0000000..7d9dd68 --- /dev/null +++ b/src/scripts/python/util/__init__.py @@ -0,0 +1 @@ +from .common import edit_distance, max_match diff --git a/src/scripts/python/util/common.py b/src/scripts/python/util/common.py index 6e2bd91..2ee76e4 100644 --- a/src/scripts/python/util/common.py +++ b/src/scripts/python/util/common.py @@ -33,3 +33,31 @@ def max_match(a: str, b: str) -> str: i += 1 else: return a[0:i] + + +def edit_distance(str1, str2, m, n): + # If first string is empty, the only option is to + # insert all characters of second string into first + if m == 0: + return n + + # If second string is empty, the only option is to + # remove all characters of first string + if n == 0: + return m + + # If last characters of two strings are same, nothing + # much to do. Ignore last characters and get count for + # remaining strings. + if str1[m - 1] == str2[n - 1]: + return edit_distance(str1, str2, m - 1, n - 1) + + # If last characters are not same, consider all three + # operations on last character of first string, recursively + # compute minimum cost for all three operations and take + # minimum of three values. + return 1 + min( + edit_distance(str1, str2, m, n - 1), # Insert + edit_distance(str1, str2, m - 1, n), # Remove + edit_distance(str1, str2, m - 1, n - 1), # Replace + ) diff --git a/src/scripts/python/util/egalax.py b/src/scripts/python/util/egalax.py index 1cf43aa..3056fb4 100644 --- a/src/scripts/python/util/egalax.py +++ b/src/scripts/python/util/egalax.py @@ -5,8 +5,8 @@ touchpannel's drm output and its overal status. """ from pathlib import Path -from x import get_edid_dev_path -from common import max_match +from .x import get_edid_dev_path +from .common import max_match VENDOR_ID = "0EEF" DEVICE_ID = "C000"