diff --git a/setup.sh b/setup.sh index e11d023..f8c31e0 100755 --- a/setup.sh +++ b/setup.sh @@ -1,98 +1,20 @@ #!/bin/env bash -source ./src/scripts/utils/source.sh -source ./src/scripts/utils/progressbar.sh - -while getopts 'v' OPTION; do - case "$OPTION" in - v) - _V=1 - ;; - ?) - echo "usage: ./setup.sh [-v]" >&2 - exit 1 - ;; - esac -done - -enable_trapping -draw_progress_bar 0 -log '.: Setting up sono-os v0.1.0 :.' -check_superuser -sleep 1 -draw_progress_bar 5 -log 'Installing dependancies ...' -sudo apt -qq update -draw_progress_bar 10 -sudo apt -qq install -y python3-pip build-essential -draw_progress_bar 15 - -log 'Installing pyxlib and pyudev ...' -pip3 install pyxlib pyudev -q -draw_progress_bar 20 - -log 'Installing X scripts ...' -sudo cp -r src/scripts/xscript/* /usr/local/bin -draw_progress_bar 23 -sudo cp src/scripts/setupmonitor.sh /usr/local/bin -draw_progress_bar 27 -sudo chmod +x /usr/local/bin/setupmonitor.sh -draw_progress_bar 30 -sudo chmod +x /usr/local/bin/changemouse.py - -log 'Installing Sleep scripts ...' -sudo cp src/scripts/utils/socknix.py /usr/local/bin -draw_progress_bar 33 -sudo chmod +x /usr/local/bin/socknix.py -draw_progress_bar 35 -sudo cp src/scripts/sleeputil.sh /lib/systemd/system-sleep/ -draw_progress_bar 36 -sudo chmod +x /lib/systemd/system-sleep/sleeputil.sh - - -draw_progress_bar 45 -log 'Installing config files ...' -# TODO - -draw_progress_bar 65 -log 'Configuring Logger ...' -# TODO - -draw_progress_bar 85 -log 'Copying rules to udev ...' -sudo cp -r src/rules/* /usr/lib/udev/rules.d -sudo cp src/rules/90-usb-storage.rules /etc/udev/rules.d -sudo cp src/rules/90-dvd-storage.rules /etc/udev/rules.d +sudo cp -r src/rules/* /etc/udev/rules.d sudo udevadm control --reload-rules sudo udevadm trigger -draw_progress_bar 90 sudo cp src/scripts/utils/usb/usb-storage-action /usr/local/bin/ sudo chmod +x /usr/local/bin/usb-storage-action -sudo cp src/scripts/utils/usb/addUsbScript.sh /usr/local/bin/ -sudo chmod +x /usr/local/bin/addUsbScript.sh sudo cp src/scripts/utils/usb/usb-socket-sono.socket /etc/systemd/system sudo cp src/scripts/utils/usb/usb-socket-sono.service /etc/systemd/system sudo systemctl enable usb-socket-sono.socket -sudo systemctl enable usb-socket-sono.service sudo systemctl start usb-socket-sono.socket -sudo systemctl start usb-socket-sono.service sudo cp src/scripts/utils/dvd/dvd-storage-action /usr/local/bin/ sudo chmod +x /usr/local/bin/dvd-storage-action -sudo cp src/scripts/utils/dvd/addDvdScript.sh /usr/local/bin/ -sudo chmod +x /usr/local/bin/addDvdScript.sh sudo cp src/scripts/utils/dvd/dvd-socket-sono.socket /etc/systemd/system sudo cp src/scripts/utils/dvd/dvd-socket-sono.service /etc/systemd/system sudo systemctl enable dvd-socket-sono.socket -sudo systemctl enable dvd-socket-sono.service sudo systemctl start dvd-socket-sono.socket -sudo systemctl start dvd-socket-sono.service - - -draw_progress_bar 95 -log 'Install PCIE Driver' -# TODO -draw_progress_bar 100 -destroy_scroll_area \ No newline at end of file diff --git a/src/rules/90-drm.rules b/src/rules/90-drm.rules deleted file mode 100644 index cbd4186..0000000 --- a/src/rules/90-drm.rules +++ /dev/null @@ -1 +0,0 @@ -SUBSYSTEM=="drm", ENV{MONITOR_LOCK}="/tmp/monitorlock", ENV{SONOLOG}="/tmp/sonolog.log", RUN+="/usr/local/bin/setupmonitor.sh" \ No newline at end of file diff --git a/src/scripts/autostart b/src/scripts/autostart deleted file mode 100644 index f66a53a..0000000 --- a/src/scripts/autostart +++ /dev/null @@ -1,39 +0,0 @@ -# /bin/sh -# These things are run when an Openbox X Session is started. -# You may place a similar script in $HOME/.config/openbox/autostart -# to run user-specific things. -if true; then -MAX_CRASH=5000 -CRASH_COUNT=0 -while true; do - sudo /home/hasis/Desktop/build-sono-Desktop_Qt_5_13_1_GCC_64bit-Debug/ui/sono & - PID=$! - - wait $PID - - if [ "$(expr 1 = 0)" -eq 1 ]; then - CRASH_COUNT=0 - exit 0 - else - CRASH_COUNT="$(expr $CRASH_COUNT + 1)" - if [ $(expr $CRASH_COUNT ">=" $MAX_CRASH) -eq 1 ]; then - echo "[$(date)] Program has crashed $CRASH_COUNT times, giving up." >> /var/log/crashreport.log - exit 1 - else - echo "[$(date)] Program has crashed $CRASH_COUNT times, restarting." >> /var/log/crashreport.log - fi - fi -done -fi & - -# If you want to use GNOME config tools... -# -#if test -x /usr/lib/x86_64-linux-gnu/gnome-settings-daemon >/dev/null; then -# /usr/lib/x86_64-linux-gnu/gnome-settings-daemon & -#elif which gnome-settings-daemon >/dev/null 2>&1; then -# gnome-settings-daemon & -#fi - -# If you want to use XFCE config tools... -# -#xfce-mcs-manager & diff --git a/src/scripts/setupmonitor.sh b/src/scripts/setupmonitor.sh deleted file mode 100755 index 5cda063..0000000 --- a/src/scripts/setupmonitor.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -# This script will run when drm change event detected. -# This sctipt should be placed in /usr/local/bin -# SONOLOG file must be set beforehand in the udev rule -# MONITOR_LOCK should be set -( - flock -n 100 || exit 1 - sleep 1 # wait until all changes take place - python3 /usr/bin/local/setupmonitor.py - echo $(data) - INFO - Setup Monitor Done >> $SONOLOG -) 100> $MONITOR_LOCK \ No newline at end of file diff --git a/src/scripts/sleeputil.sh b/src/scripts/sleeputil.sh deleted file mode 100755 index dd5097b..0000000 --- a/src/scripts/sleeputil.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -# should be moved to the /lib/systemd/system-sleep/ - -PATH=/sbin:/usr/sbin:/bin:/usr/bin -case "$1" in - pre) - STATUS=$(/usr/local/bin/socknix.py --socket /tmp/sleep.socket -m SUSPEND) - if [ "$STATUS" != "OK" ]; then - exit 1 - fi - ;; - post) - STATUS=$(/usr/local/bin/socknix.py --socket /tmp/sleep.socket -m AWAIKEN) - if [ "$STATUS" != "OK" ]; then - exit 1 - fi - ;; -esac - -exit 0 diff --git a/src/scripts/utils/dvd/addDvdScript.sh b/src/scripts/utils/dvd/addDvdScript.sh deleted file mode 100644 index 9c9bfaa..0000000 --- a/src/scripts/utils/dvd/addDvdScript.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -# Your script logic here -echo "Connection received on Unix socket" >> /var/log/exampleDvd.log diff --git a/src/scripts/utils/dvd/dvd-socket-sono.service b/src/scripts/utils/dvd/dvd-socket-sono.service index b6fd490..486ba8a 100644 --- a/src/scripts/utils/dvd/dvd-socket-sono.service +++ b/src/scripts/utils/dvd/dvd-socket-sono.service @@ -1,9 +1,9 @@ [Unit] -Description=Example Service for Unix Socket +Description=Socket for DVD events (Sono) After=network.target [Service] -ExecStart=/usr/local/bin/addDvdScript.sh +ExecStart=/bin/true StandardInput=socket [Install] diff --git a/src/scripts/utils/dvd/dvd-socket-sono.socket b/src/scripts/utils/dvd/dvd-socket-sono.socket index 36d96d8..cb125ab 100644 --- a/src/scripts/utils/dvd/dvd-socket-sono.socket +++ b/src/scripts/utils/dvd/dvd-socket-sono.socket @@ -1,9 +1,9 @@ [Unit] -Description=Example Unix Socket +Description=Socket for DVD events (Sono) +Requires=dvd-socket-sono.service [Socket] -ListenStream=/tmp/dvd-Sono-Socket.socket -Accept=false +ListenStream=/run/dvd-Sono-Socket.socket [Install] WantedBy=sockets.target diff --git a/src/scripts/utils/progressbar.sh b/src/scripts/utils/progressbar.sh deleted file mode 100644 index 075f33b..0000000 --- a/src/scripts/utils/progressbar.sh +++ /dev/null @@ -1,195 +0,0 @@ -#!/bin/bash -# https://github.com/pollev/bash_progress_bar - See license at end of file - -# Constants -CODE_SAVE_CURSOR="\033[s" -CODE_RESTORE_CURSOR="\033[u" -CODE_CURSOR_IN_SCROLL_AREA="\033[1A" -COLOR_FG="\e[30m" -COLOR_BG="\e[42m" -COLOR_BG_BLOCKED="\e[43m" -RESTORE_FG="\e[39m" -RESTORE_BG="\e[49m" - -# Variables -PROGRESS_BLOCKED="false" -TRAPPING_ENABLED="false" -TRAP_SET="false" - -CURRENT_NR_LINES=0 - -setup_scroll_area() { - # If trapping is enabled, we will want to activate it whenever we setup the scroll area and remove it when we break the scroll area - if [ "$TRAPPING_ENABLED" = "true" ]; then - trap_on_interrupt - fi - - lines=$(tput lines) - CURRENT_NR_LINES=$lines - let lines=$lines-1 - # Scroll down a bit to avoid visual glitch when the screen area shrinks by one row - log -en "\n" - - # Save cursor - log -en "$CODE_SAVE_CURSOR" - # Set scroll region (this will place the cursor in the top left) - log -en "\033[0;${lines}r" - - # Restore cursor but ensure its inside the scrolling area - log -en "$CODE_RESTORE_CURSOR" - log -en "$CODE_CURSOR_IN_SCROLL_AREA" - - # Start empty progress bar - draw_progress_bar 0 -} - -destroy_scroll_area() { - lines=$(tput lines) - # Save cursor - log -en "$CODE_SAVE_CURSOR" - # Set scroll region (this will place the cursor in the top left) - log -en "\033[0;${lines}r" - - # Restore cursor but ensure its inside the scrolling area - log -en "$CODE_RESTORE_CURSOR" - log -en "$CODE_CURSOR_IN_SCROLL_AREA" - - # We are done so clear the scroll bar - clear_progress_bar - - # Scroll down a bit to avoid visual glitch when the screen area grows by one row - log -en "\n\n" - - # Once the scroll area is cleared, we want to remove any trap previously set. Otherwise, ctrl+c will exit our shell - if [ "$TRAP_SET" = "true" ]; then - trap - INT - fi -} - -draw_progress_bar() { - percentage=$1 - lines=$(tput lines) - let lines=$lines - - # Check if the window has been resized. If so, reset the scroll area - if [ "$lines" -ne "$CURRENT_NR_LINES" ]; then - setup_scroll_area - fi - - # Save cursor - log -en "$CODE_SAVE_CURSOR" - - # Move cursor position to last row - log -en "\033[${lines};0f" - - # Clear progress bar - tput el - - # Draw progress bar - PROGRESS_BLOCKED="false" - print_bar_text $percentage - - # Restore cursor position - log -en "$CODE_RESTORE_CURSOR" -} - -block_progress_bar() { - percentage=$1 - lines=$(tput lines) - let lines=$lines - # Save cursor - log -en "$CODE_SAVE_CURSOR" - - # Move cursor position to last row - log -en "\033[${lines};0f" - - # Clear progress bar - tput el - - # Draw progress bar - PROGRESS_BLOCKED="true" - print_bar_text $percentage - - # Restore cursor position - log -en "$CODE_RESTORE_CURSOR" -} - -clear_progress_bar() { - lines=$(tput lines) - let lines=$lines - # Save cursor - log -en "$CODE_SAVE_CURSOR" - - # Move cursor position to last row - log -en "\033[${lines};0f" - - # clear progress bar - tput el - - # Restore cursor position - log -en "$CODE_RESTORE_CURSOR" -} - -print_bar_text() { - local percentage=$1 - local cols=$(tput cols) - let bar_size=$cols-17 - - local color="${COLOR_FG}${COLOR_BG}" - if [ "$PROGRESS_BLOCKED" = "true" ]; then - color="${COLOR_FG}${COLOR_BG_BLOCKED}" - fi - - # Prepare progress bar - let complete_size=($bar_size*$percentage)/100 - let remainder_size=$bar_size-$complete_size - progress_bar=$(log -ne "["; log -en "${color}"; printf_new "#" $complete_size; log -en "${RESTORE_FG}${RESTORE_BG}"; printf_new "." $remainder_size; log -ne "]"); - - # Print progress bar - log -ne " Progress ${percentage}% ${progress_bar}" -} - -enable_trapping() { - TRAPPING_ENABLED="true" -} - -trap_on_interrupt() { - # If this function is called, we setup an interrupt handler to cleanup the progress bar - TRAP_SET="true" - trap cleanup_on_interrupt INT -} - -cleanup_on_interrupt() { - destroy_scroll_area - exit -} - -printf_new() { - str=$1 - num=$2 - v=$(printf "%-${num}s" "$str") - log -ne "${v// /$str}" -} - - -# SPDX-License-Identifier: MIT -# -# Copyright (c) 2018--2020 Polle Vanhoof -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. diff --git a/src/scripts/utils/socknix.py b/src/scripts/utils/socknix.py deleted file mode 100755 index 310de67..0000000 --- a/src/scripts/utils/socknix.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/python3 - -# Author: Ali Hatami Tajik (info@alihatamitajik.ir) -# Date: 08 May 2023 - -import socket -import argparse - -parser = argparse.ArgumentParser(prog='socknix.py', - description='Sends specified massage to unix socket specified prints out the answer of the server in the stdout.') - -parser.add_argument('--socket', '-s', required=True, - help='address of the UNIX socket in the filesystem') -parser.add_argument('--message', '-m') -parser.add_argument('--buffer', '-b', type=int, default=1024) - -args = parser.parse_args() - -s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) -s.connect(args.socket) -if args.message: - s.send(args.message.encode()) -else: - s.send(input().encode()) -print(s.recv(args.buffer).decode(), end='') \ No newline at end of file diff --git a/src/scripts/utils/source.sh b/src/scripts/utils/source.sh deleted file mode 100644 index 1e64e2c..0000000 --- a/src/scripts/utils/source.sh +++ /dev/null @@ -1,400 +0,0 @@ -#!/usr/bin/env bash - -# DESC: Handler for unexpected errors -# ARGS: $1 (optional): Exit code (defaults to 1) -# OUTS: None -function script_trap_err() { - local exit_code=1 - - # Disable the error trap handler to prevent potential recursion - trap - ERR - - # Consider any further errors non-fatal to ensure we run to completion - set +o errexit - set +o pipefail - - # Validate any provided exit code - if [[ ${1-} =~ ^[0-9]+$ ]]; then - exit_code="$1" - fi - - # Output debug data if in Cron mode - if [[ -n ${cron-} ]]; then - # Restore original file output descriptors - if [[ -n ${script_output-} ]]; then - exec 1>&3 2>&4 - fi - - # Print basic debugging information - printf '%b\n' "$ta_none" - printf '***** Abnormal termination of script *****\n' - printf 'Script Path: %s\n' "$script_path" - printf 'Script Parameters: %s\n' "$script_params" - printf 'Script Exit Code: %s\n' "$exit_code" - - # Print the script log if we have it. It's possible we may not if we - # failed before we even called cron_init(). This can happen if bad - # parameters were passed to the script so we bailed out very early. - if [[ -n ${script_output-} ]]; then - # shellcheck disable=SC2312 - printf 'Script Output:\n\n%s' "$(cat "$script_output")" - else - printf 'Script Output: None (failed before log init)\n' - fi - fi - - # Exit with failure status - exit "$exit_code" -} - -# DESC: Handler for exiting the script -# ARGS: None -# OUTS: None -function script_trap_exit() { - cd "$orig_cwd" - - # Remove Cron mode script log - if [[ -n ${cron-} && -f ${script_output-} ]]; then - rm "$script_output" - fi - - # Remove script execution lock - if [[ -d ${script_lock-} ]]; then - rmdir "$script_lock" - fi - - # Restore terminal colours - printf '%b' "$ta_none" -} - -# DESC: Exit script with the given message -# ARGS: $1 (required): Message to print on exit -# $2 (optional): Exit code (defaults to 0) -# OUTS: None -# NOTE: The convention used in this script for exit codes is: -# 0: Normal exit -# 1: Abnormal exit due to external error -# 2: Abnormal exit due to script error -function script_exit() { - if [[ $# -eq 1 ]]; then - printf '%s\n' "$1" - exit 0 - fi - - if [[ ${2-} =~ ^[0-9]+$ ]]; then - printf '%b\n' "$1" - # If we've been provided a non-zero exit code run the error trap - if [[ $2 -ne 0 ]]; then - script_trap_err "$2" - else - exit 0 - fi - fi - - script_exit 'Missing required argument to script_exit()!' 2 -} - -# DESC: Generic script initialisation -# ARGS: $@ (optional): Arguments provided to the script -# OUTS: $orig_cwd: The current working directory when the script was run -# $script_path: The full path to the script -# $script_dir: The directory path of the script -# $script_name: The file name of the script -# $script_params: The original parameters provided to the script -# $ta_none: The ANSI control code to reset all text attributes -# NOTE: $script_path only contains the path that was used to call the script -# and will not resolve any symlinks which may be present in the path. -# You can use a tool like realpath to obtain the "true" path. The same -# caveat applies to both the $script_dir and $script_name variables. -# shellcheck disable=SC2034 -function script_init() { - # Useful variables - readonly orig_cwd="$PWD" - readonly script_params="$*" - readonly script_path="${BASH_SOURCE[1]}" - script_dir="$(dirname "$script_path")" - script_name="$(basename "$script_path")" - readonly script_dir script_name - - # Important to always set as we use it in the exit handler - # shellcheck disable=SC2155 - readonly ta_none="$(tput sgr0 2> /dev/null || true)" -} - -# DESC: Initialise colour variables -# ARGS: None -# OUTS: Read-only variables with ANSI control codes -# NOTE: If --no-colour was set the variables will be empty. The output of the -# $ta_none variable after each tput is redundant during normal execution, -# but ensures the terminal output isn't mangled when running with xtrace. -# shellcheck disable=SC2034,SC2155 -function colour_init() { - if [[ -z ${no_colour-} ]]; then - # Text attributes - readonly ta_bold="$(tput bold 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly ta_uscore="$(tput smul 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly ta_blink="$(tput blink 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly ta_reverse="$(tput rev 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly ta_conceal="$(tput invis 2> /dev/null || true)" - printf '%b' "$ta_none" - - # Foreground codes - readonly fg_black="$(tput setaf 0 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly fg_blue="$(tput setaf 4 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly fg_cyan="$(tput setaf 6 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly fg_green="$(tput setaf 2 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly fg_magenta="$(tput setaf 5 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly fg_red="$(tput setaf 1 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly fg_white="$(tput setaf 7 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly fg_yellow="$(tput setaf 3 2> /dev/null || true)" - printf '%b' "$ta_none" - - # Background codes - readonly bg_black="$(tput setab 0 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly bg_blue="$(tput setab 4 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly bg_cyan="$(tput setab 6 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly bg_green="$(tput setab 2 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly bg_magenta="$(tput setab 5 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly bg_red="$(tput setab 1 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly bg_white="$(tput setab 7 2> /dev/null || true)" - printf '%b' "$ta_none" - readonly bg_yellow="$(tput setab 3 2> /dev/null || true)" - printf '%b' "$ta_none" - else - # Text attributes - readonly ta_bold='' - readonly ta_uscore='' - readonly ta_blink='' - readonly ta_reverse='' - readonly ta_conceal='' - - # Foreground codes - readonly fg_black='' - readonly fg_blue='' - readonly fg_cyan='' - readonly fg_green='' - readonly fg_magenta='' - readonly fg_red='' - readonly fg_white='' - readonly fg_yellow='' - - # Background codes - readonly bg_black='' - readonly bg_blue='' - readonly bg_cyan='' - readonly bg_green='' - readonly bg_magenta='' - readonly bg_red='' - readonly bg_white='' - readonly bg_yellow='' - fi -} - -# DESC: Initialise Cron mode -# ARGS: None -# OUTS: $script_output: Path to the file stdout & stderr was redirected to -function cron_init() { - if [[ -n ${cron-} ]]; then - # Redirect all output to a temporary file - script_output="$(mktemp --tmpdir "$script_name".XXXXX)" - readonly script_output - exec 3>&1 4>&2 1> "$script_output" 2>&1 - fi -} - -# DESC: Acquire script lock -# ARGS: $1 (optional): Scope of script execution lock (system or user) -# OUTS: $script_lock: Path to the directory indicating we have the script lock -# NOTE: This lock implementation is extremely simple but should be reliable -# across all platforms. It does *not* support locking a script with -# symlinks or multiple hardlinks as there's no portable way of doing so. -# If the lock was acquired it's automatically released on script exit. -function lock_init() { - local lock_dir - if [[ $1 = 'system' ]]; then - lock_dir="/tmp/$script_name.lock" - elif [[ $1 = 'user' ]]; then - lock_dir="/tmp/$script_name.$UID.lock" - else - script_exit 'Missing or invalid argument to lock_init()!' 2 - fi - - if mkdir "$lock_dir" 2> /dev/null; then - readonly script_lock="$lock_dir" - verbose_print "Acquired script lock: $script_lock" - else - script_exit "Unable to acquire script lock: $lock_dir" 1 - fi -} - -# DESC: Pretty print the provided string -# ARGS: $1 (required): Message to print (defaults to a green foreground) -# $2 (optional): Colour to print the message with. This can be an ANSI -# escape code or one of the prepopulated colour variables. -# $3 (optional): Set to any value to not append a new line to the message -# OUTS: None -function pretty_print() { - if [[ $# -lt 1 ]]; then - script_exit 'Missing required argument to pretty_print()!' 2 - fi - - if [[ -z ${no_colour-} ]]; then - if [[ -n ${2-} ]]; then - printf '%b' "$2" - else - printf '%b' "$fg_green" - fi - fi - - # Print message & reset text attributes - if [[ -n ${3-} ]]; then - printf '%s%b' "$1" "$ta_none" - else - printf '%s%b\n' "$1" "$ta_none" - fi -} - -# DESC: Only pretty_print() the provided string if verbose mode is enabled -# ARGS: $@ (required): Passed through to pretty_print() function -# OUTS: None -function verbose_print() { - if [[ -n ${verbose-} ]]; then - pretty_print "$@" - fi -} - -# DESC: Combines two path variables and removes any duplicates -# ARGS: $1 (required): Path(s) to join with the second argument -# $2 (optional): Path(s) to join with the first argument -# OUTS: $build_path: The constructed path -# NOTE: Heavily inspired by: https://unix.stackexchange.com/a/40973 -function build_path() { - if [[ $# -lt 1 ]]; then - script_exit 'Missing required argument to build_path()!' 2 - fi - - local new_path path_entry temp_path - - temp_path="$1:" - if [[ -n ${2-} ]]; then - temp_path="$temp_path$2:" - fi - - new_path= - while [[ -n $temp_path ]]; do - path_entry="${temp_path%%:*}" - case "$new_path:" in - *:"$path_entry":*) ;; - *) - new_path="$new_path:$path_entry" - ;; - esac - temp_path="${temp_path#*:}" - done - - # shellcheck disable=SC2034 - build_path="${new_path#:}" -} - -# DESC: Check a binary exists in the search path -# ARGS: $1 (required): Name of the binary to test for existence -# $2 (optional): Set to any value to treat failure as a fatal error -# OUTS: None -function check_binary() { - if [[ $# -lt 1 ]]; then - script_exit 'Missing required argument to check_binary()!' 2 - fi - - if ! command -v "$1" > /dev/null 2>&1; then - if [[ -n ${2-} ]]; then - script_exit "Missing dependency: Couldn't locate $1." 1 - else - verbose_print "Missing dependency: $1" "${fg_red-}" - return 1 - fi - fi - - verbose_print "Found dependency: $1" - return 0 -} - -# DESC: Validate we have superuser access as root (via sudo if requested) -# ARGS: $1 (optional): Set to any value to not attempt root access via sudo -# OUTS: None -function check_superuser() { - local superuser - if [[ $EUID -eq 0 ]]; then - superuser=true - elif [[ -z ${1-} ]]; then - # shellcheck disable=SC2310 - if check_binary sudo; then - verbose_print 'Sudo: Updating cached credentials ...' - if ! sudo -v; then - verbose_print "Sudo: Couldn't acquire credentials ..." \ - "${fg_red-}" - else - local test_euid - test_euid="$(sudo -H -- "$BASH" -c 'printf "%s" "$EUID"')" - if [[ $test_euid -eq 0 ]]; then - superuser=true - fi - fi - fi - fi - - if [[ -z ${superuser-} ]]; then - verbose_print 'Unable to acquire superuser credentials.' "${fg_red-}" - return 1 - fi - - verbose_print 'Successfully acquired superuser credentials.' - return 0 -} - -# DESC: Run the requested command as root (via sudo if requested) -# ARGS: $1 (optional): Set to zero to not attempt execution via sudo -# $@ (required): Passed through for execution as root user -# OUTS: None -function run_as_root() { - if [[ $# -eq 0 ]]; then - script_exit 'Missing required argument to run_as_root()!' 2 - fi - - if [[ ${1-} =~ ^0$ ]]; then - local skip_sudo=true - shift - fi - - if [[ $EUID -eq 0 ]]; then - "$@" - elif [[ -z ${skip_sudo-} ]]; then - sudo -H -- "$@" - else - script_exit "Unable to run requested command as root: $*" 1 - fi -} - -function log () { - if [[ $_V -eq 1 ]]; then - echo "$@" - fi -} - -# vim: syntax=sh cc=80 tw=79 ts=4 sw=4 sts=4 et sr \ No newline at end of file diff --git a/src/scripts/utils/usb/addUsbScript.sh b/src/scripts/utils/usb/addUsbScript.sh deleted file mode 100644 index 489d6be..0000000 --- a/src/scripts/utils/usb/addUsbScript.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -# Your script logic here -echo "Connection received on Unix socket" >> /var/log/example.log diff --git a/src/scripts/utils/usb/usb-socket-sono.service b/src/scripts/utils/usb/usb-socket-sono.service index 7726825..4a5153c 100644 --- a/src/scripts/utils/usb/usb-socket-sono.service +++ b/src/scripts/utils/usb/usb-socket-sono.service @@ -1,9 +1,9 @@ [Unit] -Description=Example Service for Unix Socket +Description=Socket for USB events (Sono) After=network.target [Service] -ExecStart=/usr/local/bin/addUsbScript.sh +ExecStart=/bin/true StandardInput=socket [Install] diff --git a/src/scripts/utils/usb/usb-socket-sono.socket b/src/scripts/utils/usb/usb-socket-sono.socket index 9ae9907..ed18864 100644 --- a/src/scripts/utils/usb/usb-socket-sono.socket +++ b/src/scripts/utils/usb/usb-socket-sono.socket @@ -1,9 +1,9 @@ [Unit] -Description=Example Unix Socket +Description=Socket for USB events (Sono) +Requires=usb-socket-sono.service [Socket] -ListenStream=/tmp/usb-Sono-Socket.socket -Accept=false +ListenStream=/run/usb-Sono-Socket.socket [Install] WantedBy=sockets.target diff --git a/src/scripts/xscript/conf/desktop.conf b/src/scripts/xscript/conf/desktop.conf deleted file mode 100644 index 11d68f1..0000000 --- a/src/scripts/xscript/conf/desktop.conf +++ /dev/null @@ -1,3 +0,0 @@ -[DEFAULT] -MainDisplay=HDMI-3 -Policy=Mirror diff --git a/src/scripts/xscript/setupmonitor.py b/src/scripts/xscript/setupmonitor.py deleted file mode 100644 index 7f71d69..0000000 --- a/src/scripts/xscript/setupmonitor.py +++ /dev/null @@ -1,211 +0,0 @@ -"""Setup Monitor Script - -Author: Ali Hatami Tajik [hatam](mailto:a.hatam008@gmail.com) -Date: 2023 Mar 04 - - This script should be used whenever a change happen in the rdm system, I - guess! But as I investigate a rdm change event will happen many time in case - of addition or removal of a monitor auto configuration is done by the - org.mate.SettingsDaemon.plugins.xrandr deamon. I'll searching for a way to - change that event to run our specified script. - - - This script will do the following: - 1. List currently available monitors - 2. Map those to config file - 3. Replace default values for missing configs - 4. Handle missing touch-screen/main monitor - NOTE: In general we use at least two monitoers with our system. - One is for touch screen and one is for regular screen. In - case of one missing a callback is run to handle that - occurance (an event may send to the software or a temp log - file may be updated so the software adjust ifself - correspondigly). - - Config files are in JSON format and spesify screen output name and their - mode (xrandr resolution and stuff may be added but for now --auto/--prefered - option is used). The format is: - -""" - -import Xlib.display -import Xlib.ext.randr -import configparser -from util import edit_distance -from util.egalax import get_egalax_drm_pure_name -import subprocess -from pathlib import Path -import os - -CONFIG_NAME = Path(os.path.dirname(os.path.realpath(__file__))) / "conf/desktop.conf" -XRANDR = "/usr/bin/xrandr" - -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: str): - """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) - first, second = name.rsplit("-", maxsplit=1) - return first + "-" + card_num + "-" + second - - -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) if egalax_drm else None - 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 - - -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__": - conf = read_config() - main, egalax, others = prepare_monitors(conf) - config_xrandr(conf, main, egalax, others) diff --git a/src/scripts/xscript/udevhandle.py b/src/scripts/xscript/udevhandle.py deleted file mode 100644 index 1e79eb3..0000000 --- a/src/scripts/xscript/udevhandle.py +++ /dev/null @@ -1,64 +0,0 @@ -from abc import ABC, abstractmethod -from pyudev import Context, Monitor, MonitorObserver, Device - - -class Handler(ABC): - """Abstract Handler calss for device monitoring - - NOTE: No checking are done for overlaping filters and callback will be - even by multiple handlers. - - Args: - ABC: Abstract Base Class, provides abstract method functionality and - readability. - """ - - def __init__(self, filter) -> None: - """Initiate a monitor observer and applies `filter` if any provided - - Args: - filter (_type_): _description_ - """ - monitor = Monitor.from_netlink(Context()) - if filter: - monitor.filter_by(filter) - self.observer = MonitorObserver(monitor, callback=self.handler) - self.observer.start() - - @abstractmethod - def callback(self, device: Device): - """Callback - - This method must be implemented by child calsses. This method is - responsible for further managments of the devices related to its filter. - - Args: - device (pyudev.Device): device passed by observer through handler - """ - raise NotImplemented("Callback MUST be implemented") - - def handler(self, device): - """wrapper around callback implemented - - Args: - device (pyudev.Device): modified device passed by self.observer - """ - self.callback(device) - - -class MouseHandler(Handler): - def __init__(self) -> None: - """Initiate UsbHanlder - - Initialization contains two major steps. First it would do a - configuration for currently available devices and then it would wait for - USB udev events to reconfigure the settings. configurations would be - done by (This part is not decided yet. it could be done by BASH SCRIPTS - or we can invoke xinput binaries via python itself. a bash script - solution would be benefitial since it can used as utility). - """ - # TODO: use somthing that only captures - super().__init__("usb") - - def callback(self, device): - print(device.action) diff --git a/src/scripts/xscript/util/__init__.py b/src/scripts/xscript/util/__init__.py deleted file mode 100644 index 7d9dd68..0000000 --- a/src/scripts/xscript/util/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .common import edit_distance, max_match diff --git a/src/scripts/xscript/util/common.py b/src/scripts/xscript/util/common.py deleted file mode 100644 index 2ee76e4..0000000 --- a/src/scripts/xscript/util/common.py +++ /dev/null @@ -1,63 +0,0 @@ -"""Common Utilities""" - - -def max_match(a: str, b: str) -> str: - """Maximum matching of intersection of pair of string - - This function will return the intersection of two strings from the start. - - Example: - >>> a = "/sys/devices/folan/bahman" - >>> b = "/sys/devices/fol/bahman" - >>> max_match(a,b) - '/sys/dedices/fol' - - Args: - a (str): firsrt string - b (str): second string - - Returns: - str: intersection of two strings OR None if one or both strings are - empty or None - """ - i = 0 - - if not a or not b: - return None - - if len(b) < len(a): - a, b = b, a - - for c in a: - if b[i] == c: - 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/xscript/util/egalax.py b/src/scripts/xscript/util/egalax.py deleted file mode 100644 index 3056fb4..0000000 --- a/src/scripts/xscript/util/egalax.py +++ /dev/null @@ -1,80 +0,0 @@ -"""eGalax - -This module is responsible for detecting the touchpanel. It would detect the -touchpannel's drm output and its overal status. -""" - -from pathlib import Path -from .x import get_edid_dev_path -from .common import max_match - -VENDOR_ID = "0EEF" -DEVICE_ID = "C000" - - -def get_egalax_path() -> Path: - """Get device path - - This function will return the path of the HID device related to the pannel. - NOTE that it is not the path of the EDID but it can be extracted from it. - - Returns: - Path: Path of the eGalax hid device OR None if device is not ceonnected - """ - query = "*" + VENDOR_ID + ":" + DEVICE_ID + "*" - devices = list(Path("/sys/devices").rglob(query)) - if devices: - return devices[0] - else: - return None - - -def is_egalax_connected() -> bool: - """Checks if device is connected - - avaiability of the device is checked by existing a path of the device in the - /sys/devices directory. - - Returns: - bool: True if device is connected - """ - devpath = get_egalax_path() - return bool(devpath) - - -def get_egalax_edid_path() -> Path: - """return EDID path of touchpannel rdm - - This function will find intersection of the edid pathes and eGalax hid - device and if this intersection and returns the maximum match. - - Runtime: 160ms on average -> Not efficient - - Returns: - Path: edid path of eGalax OR None if not found or device is'nt connected - """ - egalax_dev = get_egalax_path() - if not egalax_dev: - return None - max_dir = "/sys/devices" - max_path = None - for path in get_edid_dev_path(): - base_dir = max_match(str(path), str(egalax_dev)) - if len(max_dir) < len(base_dir): - max_dir = base_dir - max_path = path - # TODO add sanity check (both edid and VENDOR:DEVICE are in that base) - return max_path - - -def get_egalax_drm_pure_name() -> str: - """Extract DRM name form edid path - - Returns: - str: pure drm name OR none if device is not found - """ - edid_path = get_egalax_edid_path() - if edid_path: - return str(edid_path.parent.stem) - else: - return None diff --git a/src/scripts/xscript/util/pointer.py b/src/scripts/xscript/util/pointer.py deleted file mode 100644 index 2e6795f..0000000 --- a/src/scripts/xscript/util/pointer.py +++ /dev/null @@ -1,198 +0,0 @@ -import util.x as xutil - -# Pointer states -SLAVE, MASTER, FLOATING = range(3) - - -class XInput: - """Base XInput class - - Attributes: - name (str): name of the input - id (int): id of the input - is_master (bool): True if device is master - """ - - def __init__(self, name, id, state) -> None: - """Initializes the class with name, id and master status - - Args: - name (str): name of the input. No processing is done on the name - id (int): id of the input - is_master (bool): master status of the input device - """ - self.name = name - self.id = id - self.state = state - - -class Pointer(XInput): - """Pointer class - - This class is a wrapper around xinput commandline --list output. - - - Attrs: - is_master (bool): True if the pointer is a master pointer else False - """ - - def __init__(self, name, id, state) -> None: - super().__init__(name, id, state) - - def __repr__(self) -> str: - return f"" - - @property - def slave(self): - return self.state == SLAVE - - @property - def master(self): - return self.state == MASTER - - def floating(self): - return self.state == FLOATING - - -def get_short_pointer(id) -> Pointer: - """Generates Pointer object corresponding to id (short attrs) - - Args: - id (int): pointer id - - Returns: - Pointer: pointer object with name, id and is_master props - - Rises: - ValueError: if id is not reistered with xinput - ValueError: if id is not a pointer id - """ - desc = xutil.get_list_short_with(id) - name, props = desc.rsplit("id=", 1) - if "pointer" in props: - state = FLOATING - if "master" in props: - state = MASTER - elif "slave" in props: - state = SLAVE - return Pointer(name.strip(), props.split(maxsplit=1)[0], state) - else: - raise TypeError(f"id[{id}] is not a pointer id") - - -def get_ids_iter(): - """xinput id generator - - Yields: - int: id of xinput devices - """ - ids = xutil.get_ids() - for id in ids: - yield id - - -def get_pointer_iter(is_short=True): - """xinput pointers generator - - Args: - is_short (bool, optional): if True generates short type pointers. - Defaults to True. - - Yields: - Pointer: xinput pointers - """ - for id in get_ids_iter(): - if is_short: - try: - yield get_short_pointer(id) - except TypeError as e: - # ignore if the id is not pointer - pass - except e: - # TODO: logging - pass - else: - pass # TODO - - -def get_pointers(is_short=True): - """Wraps pointers in `xinput --list` in Pointer class - - Creation of the pointer is done by getting the list description of - each id. if the is_short arg is True, then short list description will be - used which will provide the class `name`, `is_master` and `id` values. - - Getting this pointers is done by first calling `xinput --list --id-only` to - get ids and then execute `xinput --list {id}` to get the description with - less-complicated output compare to iterating over `xinput --list --short` - line by line (--short option has some special characters that cause overhead - to the system for processing them individually and per-case). - """ - pointers = [] - for pointer in get_pointer_iter(is_short): - pointers.append(pointer) - return pointers - - -def create_touch_master(): - """_summary_ - - Raises: - SystemError: If creation of touch pointer failed - - Returns: - Pointer: pointer object corresponding to `touch` master - """ - touch = None - xutil.create_master("touch") - id = xutil.get_xi_id_by_name("touch pointer") - if id: - try: - touch = get_short_pointer(id) - except: - raise SystemError( - "touch pointer is not available. cannot create touch pointer" - ) - else: - raise SystemError( - "touch pointer is not available. cannot create touch pointer" - ) - - # TODO configure cursor bitmap - return touch - - -def get_pointers_categorized(): - """Categorized Pointers - - Categories: - 1. VCore: Pointer - 2. Touch Master: Pointer - 3. eGalax: Pointer | None - 4. Other non-masters: List[Pinter] - - Raises: - SystemError: If creation of touch pointer failed - - Returns: - - """ - v_core = None - touch = None - e_galax = None - pointers = [] - # filter pointers - for pointer in get_pointer_iter(): - if pointer.name == "Virtual core pointer": - v_core = pointer - elif "eGalax" in pointer.name: - e_galax = pointer - elif pointer.name == "touch pointer": - touch = pointer - elif not pointer.master: - pointers.append(pointer) - - if not touch: - touch = create_touch_master() - - return v_core, touch, e_galax, pointers diff --git a/src/scripts/xscript/util/randr.py b/src/scripts/xscript/util/randr.py deleted file mode 100644 index a278ce9..0000000 --- a/src/scripts/xscript/util/randr.py +++ /dev/null @@ -1,113 +0,0 @@ -"""RandR - -Author: Ali Hatami Tajik [hatam](mailto:a.hatam008@gmail.com) -Creation Date: 2023 Mar 04 - ---- -This module provides a wrapper utility around xrandr. - -Classes: - Mode - Setting - Screen - Dir - Pos - - -Utilities: - get_screens - -""" - -from enum import Enum -from dataclasses import dataclass -from typing import List - -from Xlib.ext import randr as rnd - - -# TODO: Option class which can be applied by get_args method -# TODO: Screen-related option class ~ -# TODO: abs position - - -class Pos(Enum): - """Position types in xrandr - - Position the output relative to the position of another output. - """ - - LEFT_OF = (0,) - RIGHT_OF = (1,) - ABOVE = (2,) - BELOW = (3,) - SAME_AS = 4 - - -class RotationDir(Enum): - """Rotation direction - - This causes the output contents to be rotated in the specified direction. - """ - - NORMAL = (0,) - LEFT = (1,) - RIGHT = (2,) - INVERTED = 3 - - -class ReflectDir(Enum): - """Reflection direction - - This causes the output contents to be reflected across the specified axes. - """ - - NORMAL = (0,) - X = (1,) - Y = (2,) - XY = 3 - - -@dataclass -class Setting: - """Settings of a screen - - This data struct will be used as the config of each screen. Note that - default screen cannot be use - """ - - resolution = (None,) - is_primary = (False,) - is_enabeled = (True,) - rotation = None - position = None - reflection = None - - -@dataclass -class Mode: - """Mode - - Mode of the screen including width, height, refresh rate(s) - """ - - height: int = 0 - width: int = 0 - frequency: List[int] = [] - - -class Screen: - """Screen class - - This class will hold screen properties and methods related to the screens. - - At the time it will use xrandr (and not the verbose mode) to list the - screens and modes. - """ - - -class Monitor: - """Monitor Class - - List Monitor Outputs and their states - """ diff --git a/src/scripts/xscript/util/x.py b/src/scripts/xscript/util/x.py deleted file mode 100644 index 8457433..0000000 --- a/src/scripts/xscript/util/x.py +++ /dev/null @@ -1,106 +0,0 @@ -import subprocess -from pathlib import Path -import os - -ENCODING = "utf-8" -XINPUT = "/ust/bin/xinput" - - -def exec_xinput(args: list): - args.insert(0, XINPUT) - _read, _write = os.pipe() - write_fd = os.fdopen(_write, "w", 0) - os.read() - - -def get_list_short(): - """Returns string output of the `xinput --list --short` command encoded as - UTF-8""" - completed = subprocess.run( - [XINPUT, "--list", "--short"], capture_output=True - ) - return completed.stdout.decode(ENCODING) - - -def get_list_short_with(id): - """Short List of the id - - Args: - id (int): id registered in xinput - - Rises: - ValueError: in case of id not found in devices - """ - completed = subprocess.run( - [XINPUT, "--list", "--short", str(id)], capture_output=True - ) - - if completed.returncode == 0: - return completed.stdout.decode(ENCODING) - else: - ValueError(f"id[{id}] is not registered") - - -def reattach(id, master): - """Reattach a device to a master - - Args: - id (str|int): name of the slave or id - master (_type_): _description_ - - TODO: Error handling should be done. BUT, if the master is not a master or - id is not valid, xinput will not do anything and nothing bad will happen :) - """ - completed = subprocess.run( - [XINPUT, "--reattach", str(id), str(master)], capture_output=True - ) - - return completed.returncode - - -def get_ids(): - """returns list of ids registered in xinput""" - completed = subprocess.run( - [XINPUT, "--list", "--id-only"], capture_output=True - ) - return list(map(int, completed.stdout.decode(ENCODING).split())) - - -def create_master(name: str = "touch"): - """Creates master with specified name - - Args: - name (str, optional): name of the master. Defaults to 'touch'. - """ - completed = subprocess.run([XINPUT, "create-master", name]) - - return completed.returncode - - -def get_xi_id_by_name(name): - """find device id from name - - Args: - name (str): name of the device - """ - completed = subprocess.run( - [XINPUT, "list", "--id-only", name], capture_output=True - ) - - if completed.returncode == 1: - return None - else: - return int(completed.stdout.decode(ENCODING)) - - -def map_to_output(output, device_id): - # TODO - pass - - -def get_edid_dev_path(): - """returns iterator of pathes of devices with edid - - devices which has EDID are monitors. - """ - return Path("/sys/devices").rglob("edid")