Add labwc support
This commit is contained in:
parent
d14339d748
commit
7ba3f50d36
1 changed files with 120 additions and 50 deletions
|
|
@ -7,6 +7,9 @@ Written in Python by Melissa LeBlanc-Williams for Adafruit Industries
|
|||
|
||||
import time
|
||||
import os
|
||||
import glob
|
||||
import re
|
||||
|
||||
try:
|
||||
import click
|
||||
except ImportError:
|
||||
|
|
@ -58,6 +61,27 @@ TS_TSC2007 = "tsc2007"
|
|||
TS_FOCALTOUCH = "EP0110M09"
|
||||
|
||||
config = [
|
||||
{
|
||||
"type": "24rv2",
|
||||
"menulabel": "PiTFT 2.4\" V2 resistive (240x320)",
|
||||
"product": "2.4\" V2 resistive",
|
||||
"kernel_upgrade": False,
|
||||
"overlay_src": "overlays/pitft24v2-tsc2007-overlay.dts",
|
||||
"overlay_dest": "{boot_dir}/overlays/pitft24rv2.dtbo",
|
||||
"touchscreen": {
|
||||
"identifier": "TSC2007 Touchscreen Calibration",
|
||||
"product": TS_TSC2007,
|
||||
"transforms": {
|
||||
"0": "-1 0 1 0 -1 1",
|
||||
"90": "0 1 0 -1 0 1",
|
||||
"180": "1 0 0 0 1 0",
|
||||
"270": "0 -1 1 1 0 0",
|
||||
},
|
||||
},
|
||||
"overlay": "dtoverlay=pitft24rv2,rotate={pitftrot},fps=60",
|
||||
"width": 320,
|
||||
"height": 240,
|
||||
},
|
||||
{
|
||||
"type": "28r",
|
||||
"menulabel": "PiTFT 2.4\", 2.8\" or 3.2\" resistive (240x320)",
|
||||
|
|
@ -155,7 +179,7 @@ config = [
|
|||
"overlay_drm_option": "drm",
|
||||
"width": 480,
|
||||
"height": 320,
|
||||
"x11_scale": 1.5,
|
||||
"display_scale": 1.5,
|
||||
},
|
||||
{
|
||||
"type": "st7789_240x240",
|
||||
|
|
@ -269,29 +293,6 @@ config = [
|
|||
"270": "3",
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "24v2",
|
||||
"menulabel": "PiTFT 2.4\" V2 resistive (240x320)",
|
||||
"product": "2.4\" V2 resistive",
|
||||
"kernel_upgrade": False,
|
||||
"overlay_src": "overlays/pitft24v2-tsc2007-overlay.dts",
|
||||
"overlay_dest": "{boot_dir}/overlays/pitft24v2.dtbo",
|
||||
"touchscreen": {
|
||||
"identifier": "TSC2007 Touchscreen Calibration",
|
||||
"product": TS_TSC2007,
|
||||
"transforms": {
|
||||
# TODO: Test because 0 and 180 may be reversed
|
||||
"0": "-1 0 1 0 -1 1",
|
||||
"90": "0 1 0 -1 0 1",
|
||||
"180": "1 0 0 0 1 0",
|
||||
"270": "0 -1 1 1 0 0",
|
||||
},
|
||||
},
|
||||
"overlay": "dtoverlay=pitft24v2,rotate={pitftrot},fps=60",
|
||||
#"overlay_drm_option": "drm",
|
||||
"width": 320,
|
||||
"height": 240,
|
||||
},
|
||||
]
|
||||
|
||||
# default rotations
|
||||
|
|
@ -308,6 +309,12 @@ mipi_data = {
|
|||
"spi": "spi0-0",
|
||||
}
|
||||
|
||||
install_types = {
|
||||
"mirror": "Setup PiTFT as desktop display (mirror)",
|
||||
"console": "Display console on PiTFT (console)",
|
||||
"drivers": "Install Drivers only"
|
||||
}
|
||||
|
||||
PITFT_ROTATIONS = ("90", "180", "270", "0")
|
||||
UPDATE_DB = False
|
||||
SYSTEMD = None
|
||||
|
|
@ -316,6 +323,7 @@ pitft_config = None
|
|||
pitftrot = None
|
||||
auto_reboot = None
|
||||
is_desktop = False
|
||||
manager = None
|
||||
|
||||
def warn_exit(message):
|
||||
shell.warn(message)
|
||||
|
|
@ -551,8 +559,6 @@ def install_console():
|
|||
return True
|
||||
|
||||
def uninstall_console():
|
||||
global is_desktop
|
||||
|
||||
print(f"Removing console fbcon map from {boot_dir}/cmdline.txt")
|
||||
shell.pattern_replace(f"{boot_dir}/cmdline.txt", 'rootwait fbcon=map:10 fbcon=font:VGA8x8', 'rootwait')
|
||||
|
||||
|
|
@ -638,11 +644,11 @@ def install_mirror():
|
|||
shell.reconfig(f"{boot_dir}/config.txt", "^.*hdmi_group.*$", "hdmi_group=2")
|
||||
shell.reconfig(f"{boot_dir}/config.txt", "^.*hdmi_mode.*$", "hdmi_mode=87")
|
||||
|
||||
# if there's X11 installed...
|
||||
# if using the desktop version, update driver scale...
|
||||
scale = 1
|
||||
if is_desktop:
|
||||
if "x11_scale" in pitft_config:
|
||||
scale = pitft_config["x11_scale"]
|
||||
if "display_scale" in pitft_config:
|
||||
scale = pitft_config["display_scale"]
|
||||
else:
|
||||
scale = 2
|
||||
WIDTH = int(pitft_config['width'] * scale)
|
||||
|
|
@ -666,17 +672,20 @@ def install_mirror():
|
|||
shell.bail(f"Unable to update {boot_dir}/config.txt")
|
||||
return True
|
||||
|
||||
def update_wayfire_settings():
|
||||
def update_wayland_settings():
|
||||
# Set the scale factor for Wayland, which is the reciprocal of the X11 scale factor
|
||||
if "x11_scale" in pitft_config:
|
||||
scale = 1/pitft_config["x11_scale"]
|
||||
if "display_scale" in pitft_config:
|
||||
scale = 1/pitft_config["display_scale"]
|
||||
else:
|
||||
scale = 0.5
|
||||
scale = 0.5 # Default Scale
|
||||
device_name = "SPI-1"
|
||||
date = shell.date()
|
||||
|
||||
if manager == "wayfire":
|
||||
### WAYFIRE ###
|
||||
wayfire_config = f"{target_homedir}/.config/wayfire.ini"
|
||||
# Remove any existing settings previously added by this script
|
||||
shell.pattern_replace(wayfire_config, '\n# --- added by adafruit-pitft-helper.*?\n# --- end adafruit-pitft-helper.*?\n', multi_line=True)
|
||||
date = shell.date()
|
||||
shell.write_text_file(wayfire_config, f"""
|
||||
# --- added by adafruit-pitft-helper {date} ---
|
||||
[output:{device_name}]
|
||||
|
|
@ -684,8 +693,47 @@ scale = {scale}
|
|||
# --- end adafruit-pitft-helper {date} ---
|
||||
""")
|
||||
|
||||
shell.pattern_replace(target_homedir, "^.*[output:SPI-1].*$", "hdmi_force_hotplug=0")
|
||||
elif manager == "labwc":
|
||||
### LABWC (Using Kanshi) ###
|
||||
# See https://man.archlinux.org/man/kanshi.5.en for more information on kanshi config files
|
||||
labwc_config = f"{target_homedir}/.config/kanshi/config"
|
||||
|
||||
# If the config file doesn't exist or doesn't contain profile, enumerate the devices and create a new profile
|
||||
if not shell.exists(labwc_config) or not shell.pattern_search(labwc_config, "^profile"):
|
||||
drm_devices = get_drm_devices(connected_only=True)
|
||||
profile_content = "profile {"
|
||||
for device in drm_devices:
|
||||
device_name = device["name"]
|
||||
mode = device["modes"][0]
|
||||
device_refresh = "@60.000"
|
||||
device_scale = ""
|
||||
if device_name == "SPI-1":
|
||||
device_refresh = "" # For SPI displays, we don't specify refresh rate
|
||||
device_scale = f" scale {scale}"
|
||||
|
||||
profile_content += f"\n\t\toutput {device_name} enable mode {mode}{device_refresh} transform normal{device_scale}"
|
||||
profile_content += "\n}\n"
|
||||
shell.write_text_file(labwc_config, profile_content, append=True)
|
||||
else:
|
||||
profiles = shell.pattern_search(labwc_config, r"(profile(?: .*)?) {([\S\s]*?)}", multi_line=True, return_match=True, find_all=True)
|
||||
if profiles:
|
||||
for profile in profiles:
|
||||
profile_name = profile[0].strip()
|
||||
profile_content = profile[1].strip()
|
||||
# Check if the profile already has an output section for the device
|
||||
if not shell.pattern_search(profile_content, f"(output {device_name}.*)"):
|
||||
# If not, add the output section for the device
|
||||
width, height = pitft_config["width"], pitft_config["height"]
|
||||
new_output_device = f"\t\toutput {device_name} enable mode {width}x{height} transform normal scale {scale}\n"
|
||||
# insert the new output device line into the profile content
|
||||
profile_content += new_output_device
|
||||
# Replace the profile with the updated content
|
||||
shell.pattern_replace(labwc_config, f"^{profile_name} {{([\S\s]*?)}}", f"{profile_name}: {{{profile_content}}}", multi_line=True)
|
||||
|
||||
# Remove scaling from any existing scale settings for the device
|
||||
shell.pattern_replace(labwc_config, f"(output {device_name}.*) scale [0-9](?:\.[0-9]+)?(.*)", r"\1\2")
|
||||
# Add new scale to the end of the line
|
||||
shell.pattern_replace(labwc_config, f"(output {device_name}.*)", r"\1 scale " + f"{scale}")
|
||||
|
||||
def install_fbcp_service():
|
||||
shell.write_templated_file("/etc/systemd/system/", "templates/fbcp.service")
|
||||
|
|
@ -771,6 +819,24 @@ Settings take effect on next boot.
|
|||
shell.reboot()
|
||||
shell.exit()
|
||||
|
||||
def get_drm_devices(connected_only=False):
|
||||
# get all drm devices from /sys/class/drm e.g. card1-HDMI-A-1, card2-SPI-1, etc.
|
||||
devices = []
|
||||
for item in glob.glob("/sys/class/drm/card?-*"):
|
||||
status = shell.read_text_file(f"{item}/status").strip()
|
||||
if connected_only and status != "connected":
|
||||
continue
|
||||
modes = shell.read_text_file(f"{item}/modes").strip().splitlines()
|
||||
# remove duplicate modes
|
||||
modes = list(dict.fromkeys(modes))
|
||||
info = {
|
||||
"name": item.split("-", 1)[1],
|
||||
"status": status,
|
||||
"modes": modes,
|
||||
}
|
||||
devices.append(info)
|
||||
return devices
|
||||
|
||||
####################################################### MAIN
|
||||
target_homedir = "/home/pi"
|
||||
username = os.environ["SUDO_USER"]
|
||||
|
|
@ -800,7 +866,7 @@ if shell.get_raspbian_version() == "bullseye":
|
|||
@click.option('--reboot', nargs=1, default=None, type=click.Choice(['yes', 'no']), help="Specify whether to reboot after the script is finished")
|
||||
@click.option('--boot', nargs=1, default=boot_dir, type=str, help="Specify the boot directory", show_default=True)
|
||||
def main(user, display, rotation, install_type, reboot, boot):
|
||||
global target_homedir, pitft_config, pitftrot, auto_reboot, boot_dir, is_desktop
|
||||
global target_homedir, pitft_config, pitftrot, auto_reboot, boot_dir, is_desktop, manager, SYSTEMD
|
||||
shell.clear()
|
||||
if user != target_homedir:
|
||||
target_homedir = user
|
||||
|
|
@ -814,10 +880,12 @@ def main(user, display, rotation, install_type, reboot, boot):
|
|||
# Check if we are running on a desktop environment or lite
|
||||
is_desktop = shell.exists("/etc/lightdm")
|
||||
print("Running on a {} environment".format("desktop" if is_desktop else "lite"))
|
||||
if is_desktop:
|
||||
manager = shell.get_window_manager()
|
||||
if manager is None:
|
||||
shell.bail("Unable to determine desktop manager. Please run this script in a terminal emulator, not from the desktop environment.")
|
||||
print("Desktop manager: {}".format(manager))
|
||||
print()
|
||||
# "mirror" will be the new install type, but keep fbcp for backwards compatibility
|
||||
if install_type == "fbcp":
|
||||
install_type = "mirror"
|
||||
|
||||
print("""This script downloads and installs
|
||||
PiTFT Support using userspace touch
|
||||
|
|
@ -830,7 +898,6 @@ Run time of up to 5 minutes. Reboot required!
|
|||
|
||||
if install_type == "uninstall":
|
||||
uninstall()
|
||||
|
||||
def select_display(config, interactive=False):
|
||||
global pitft_config
|
||||
pitft_config = config
|
||||
|
|
@ -880,6 +947,11 @@ Run time of up to 5 minutes. Reboot required!
|
|||
shell.bail("""Unfortunately {rotation} degrees for the {display} is not working at this time. Please
|
||||
restart the script and choose a different orientation.""".format(rotation=pitftrot, display=pitft_config["menulabel"]))
|
||||
|
||||
if install_type is None:
|
||||
# Show a selection menu for install_types using shell.select_n and setting the selection to the key of install_types
|
||||
install_selection = shell.select_n("Select install type:", install_types.values())
|
||||
install_type = list(install_types.keys())[install_selection - 1]
|
||||
update_wayland_settings()
|
||||
if REMOVE_KERNEL_PINNING:
|
||||
# Checking if kernel is pinned
|
||||
if shell.exists('/etc/apt/preferences.d/99-adafruit-pin-kernel'):
|
||||
|
|
@ -938,7 +1010,7 @@ restart the script and choose a different orientation.""".format(rotation=pitftr
|
|||
shell.bail("Unable to update /etc/pointercal")
|
||||
|
||||
# ask for console access
|
||||
if install_type == "console" or (install_type is None and shell.prompt("Would you like the console to appear on the PiTFT display?")):
|
||||
if install_type == "console":
|
||||
shell.info("Updating console to PiTFT...")
|
||||
if not uninstall_fbcp():
|
||||
shell.bail("Unable to uninstall fbcp")
|
||||
|
|
@ -947,15 +1019,13 @@ restart the script and choose a different orientation.""".format(rotation=pitftr
|
|||
else:
|
||||
shell.info("Making sure console doesn't use PiTFT")
|
||||
if not uninstall_console():
|
||||
shell.bail("Unable to configure console")
|
||||
shell.bail("Unable to uninstall console")
|
||||
|
||||
# With wayland, PiTFT shows up as an additional display rather than a mirror
|
||||
mirror_prompt = "Would you like the to use the PiTFT as a desktop display?"
|
||||
if install_type == "mirror" or (install_type is None and shell.prompt(mirror_prompt)):
|
||||
shell.info("Updating Wayland desktop settings...")
|
||||
update_wayfire_settings()
|
||||
|
||||
if install_type == "mirror":
|
||||
if is_desktop:
|
||||
shell.info("Updating Wayland desktop settings...")
|
||||
update_wayland_settings()
|
||||
shell.info("Updating Desktop Touch calibration...")
|
||||
if not update_xorg():
|
||||
shell.bail("Unable to update calibration")
|
||||
|
|
|
|||
Loading…
Reference in a new issue