#!/bin/bash # # displaylink-debian: # DisplayLink driver installer for Debian and Ubuntu based Linux distributions: Debian, Ubuntu, Elementary OS, # Mint, Kali, Deepin and more! Full list of all supported platforms: http://bit.ly/2zrwz2u # # DisplayLink driver installer for Debian GNU/Linux, Ubuntu, Elementary OS, Mint, Kali, Deepin and more! Full list of all supported Linux distributions # # Blog post: http://foolcontrol.org/?p=1777 # # Copyleft: Adnan Hodzic # License: GPLv3 # Bash Strict Mode set -eu # set -o pipefail # TODO: Some code still fails this check, fix before enabling. IFS=$'\n\t' kernel_check="$(uname -r | egrep -o '^[0-9]+\.[0-9]+')" function ver2int { echo "$@" | awk -F "." '{ printf("%03d%03d%03d\n", $1,$2,$3); }'; } # Get latest versions versions=$(wget -q -O - https://www.synaptics.com/products/displaylink-graphics/downloads/ubuntu | grep "

Release: " | head -n 2 | perl -pe '($_)=/([0-9]+([.][0-9]+)+(\ Beta)*)/; exit if $. > 1;') # if versions contains "Beta", try to download previous version if [[ $versions =~ Beta ]]; then version=$(wget -q -O - https://www.synaptics.com/products/displaylink-graphics/downloads/ubuntu | grep "

Release: " | head -n 2 | perl -pe '($_)=/([0-9]+([.][0-9]+)+(?!\ Beta))/; exit if $. > 1;') dlurl="https://www.synaptics.com/$(wget -q -O - https://www.synaptics.com/products/displaylink-graphics/downloads/ubuntu | grep -B 2 $version'-Release' | perl -pe '($_)=/]+class="download-link"/')" driver_url="https://www.synaptics.com/$(wget -q -O - ${dlurl} | grep 'Release: " | head -n 1 | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/; exit if $. > 1;'` dlurl="https://www.synaptics.com/$(wget -q -O - https://www.synaptics.com/products/displaylink-graphics/downloads/ubuntu | grep -B 2 $version'-Release' | perl -pe '($_)=/]+class="download-link"/')" driver_url="https://www.synaptics.com/$(wget -q -O - ${dlurl} | grep ' /dev/null 2>&1 then default=y read -p "$dep not found! Install? [Y/n] " response response=${response:-$default} if [[ $response =~ ^(yes|y|Y)$ ]] then if ! apt-get install $dep then echo "$dep installation failed. Aborting." exit 1 fi else separator echo -e "\nCannot continue without $dep. Aborting." separator exit 1 fi else echo "$dep is installed" fi done } distro_check(){ separator # RedHat if [ -f /etc/redhat-release ]; then echo "This is a Redhat based distro ..." # ToDo: # Add platform type message for RedHat exit 1 else # Confirm dependencies are in place dep_check # Unsupported platform message message(){ echo -e "\n---------------------------------------------------------------\n" echo -e "Unsuported platform: $platform" echo -e "Full list of all supported platforms: http://bit.ly/2zrwz2u" echo -e "" echo -e "This tool is Open Source and feel free to extend it" echo -e "GitHub repo: https://github.com/AdnanHodzic/displaylink-debian/" echo -e "\n---------------------------------------------------------------\n" } # Ubuntu, Neon, PopOS if [ "$lsb" == "Ubuntu" ] || [ "$lsb" == "Neon" ] || [ "$lsb" == "Pop" ]; then echo -e "\nPlatform requirements satisfied, proceeding ..." # elementary OS elif [ "$lsb" == "elementary OS" ] || echo $lsb | grep -qi "elementary"; then echo -e "\nPlatform requirements satisfied, proceeding ..." # Debian elif [ "$lsb" == "Debian" ]; then echo -e "\nPlatform requirements satisfied, proceeding ..." # Devuan elif [ "$lsb" == "Devuan" ] then echo -e "\nPlatform requirements satisfied, proceeding ..." # Mint elif echo $lsb | grep -qi "Linuxmint" ; then echo -e "\nPlatform requirements satisfied, proceeding ..." # Kali elif [ "$lsb" == "Kali" ]; then echo -e "\nPlatform requirements satisfied, proceeding ..." # Deepin elif [ "$lsb" == "Deepin" ] || [ "$lsb" == "Uos" ] ; then echo -e "\nPlatform requirements satisfied, proceeding ..." # MX Linux elif [ "$lsb" == "MX" ]; then echo -e "\nPlatform requirements satisfied, proceeding ..." # BunsenLabs elif [ "$lsb" == "BunsenLabs" ] || [ "$lsb" == "Bunsenlabs" ]; then echo -e "\nPlatform requirements satisfied, proceeding ..." # Parrot elif [ "$lsb" == "Parrot" ]; then echo -e "\nPlatform requirements satisfied, proceeding ..." # PureOS elif [ "$lsb" == "PureOS" ]; then echo -e "\nPlatform requirements satisfied, proceeding ..." # Nitrux elif [ "$lsb" == "Nitrux" ]; then echo -e "\nPlatform requirements satisfied, proceeding ..." # Zorin elif [ "$lsb" == "Zorin" ]; then echo -e "\nPlatform requirements satisfied, proceeding ..." else message exit 1 fi fi } pre_install() { if [ -f $kconfig_file ]; then kconfig_exists="true" else kconfig_exists="false" touch $kconfig_file fi } sysinitdaemon_get(){ sysinitdaemon="systemd" if [ "$lsb" == "Ubuntu" ]; then if [ $codename == "trusty" ]; then sysinitdaemon="upstart" fi # Elementary elif [ "$lsb" == "elementary OS" ] || echo $lsb | grep -qi "elementary"; then if [ $codename == "freya" ]; then sysinitdaemon="upstart" fi elif [ "$lsb" == "Devuan" ] then sysinitdaemon="sysvinit" fi echo $sysinitdaemon } displaylink_service_check () { sysinitdaemon=$(sysinitdaemon_get) if [ "$sysinitdaemon" == "systemd" ] then systemctl is-active --quiet displaylink-driver.service && \ echo up and running elif [ "$sysinitdaemon" == "sysvinit" ] then /etc/init.d/$init_script status fi } clean_up(){ # remove obsolete/redundant files which can only hamper reinstalls separator echo -e "\nPerforming clean-up" # go back to displaylink-debian cd - &> /dev/null if [ -f "DisplayLink_Ubuntu_$version.zip" ] then echo "Removing redundant: \"DisplayLink_Ubuntu_$version.zip\" file" rm "DisplayLink_Ubuntu_$version.zip" fi if [ -d $driver_dir ] then echo "Removing redundant: \"$driver_dir\" directory" rm -r $driver_dir fi } setup_complete(){ default=Y ack=${ack:-$default} read -p "Reboot now? [Y/n] " ack ack=${ack:-$default} for letter in "$ack"; do if [[ "$letter" == [Yy] ]]; then echo "Rebooting ..." reboot elif [[ "$letter" == [Nn] ]]; then echo -e "\nReboot postponed, changes won't be applied until reboot" else wrong_key fi done } download() { default=y echo -en "\nPlease read the Software License Agreement available at: \n$dlurl\nDo you accept?: [Y/n]: " read ACCEPT ACCEPT=${ACCEPT:-$default} case $ACCEPT in y*|Y*) echo -e "\nDownloading DisplayLink Ubuntu driver:\n" wget -O DisplayLink_Ubuntu_${version}.zip "${driver_url}" # make sure file is downloaded before continuing if [ $? -ne 0 ] then echo -e "\nUnable to download Displaylink driver\n" exit fi ;; *) echo "Can't download the driver without accepting the license agreement!" exit 1 ;; esac } install(){ separator download # prep # Check whether prior drivers have been downloaded if [ -d $driver_dir ] then echo "Removing prior: \"$driver_dir\" directory" rm -r $driver_dir fi mkdir $driver_dir separator echo -e "\nPreparing for install\n" test -d $driver_dir && /bin/rm -Rf $driver_dir unzip -d $driver_dir DisplayLink_Ubuntu_${version}.zip chmod +x $driver_dir/displaylink-driver-${version}*.run ./$driver_dir/displaylink-driver-${version}*.run --keep --noexec mv displaylink-driver-${version}*/ $driver_dir/displaylink-driver-${version} # get sysinitdaemon sysinitdaemon=$(sysinitdaemon_get) # modify displaylink-installer.sh sed -i "s/SYSTEMINITDAEMON=unknown/SYSTEMINITDAEMON=$sysinitdaemon/g" $driver_dir/displaylink-driver-${version}/displaylink-installer.sh # issue: 227 if [ "$lsb" == "Debian" ] || [ "$lsb" == "Devuan" ] || [ "$lsb" == "Kali" ] || [ "$lsb" == "Deepin" ] || [ "$lsb" == "BunsenLabs" ] || [ "$lsb" == "Bunsenlabs" ] || [ "$lsb" == "MX" ] || [ "$lsb" == "Uos" ]; then sed -i 's#/lib/modules/$KVER/build/Kconfig#/lib/modules/$KVER/build/scripts/kconfig/conf#g' $driver_dir/displaylink-driver-${version}/displaylink-installer.sh ln -sf /lib/modules/$(uname -r)/build/Makefile /lib/modules/$(uname -r)/build/Kconfig fi # Patch displaylink-installer.sh to prevent reboot before our script is done. patchName="displaylink-installer.patch" finalPatchPath="$resourcesDir$patchName" patch -Np0 $driver_dir/displaylink-driver-${version}/displaylink-installer.sh <$finalPatchPath # run displaylink install echo -e "\nInstalling driver version: $version\n" cd $driver_dir/displaylink-driver-${version} ./displaylink-installer.sh install # udlfb kernel version check kernel_check="$(uname -r | egrep -o '[0-9]+\.[0-9]+')" # add udlfb to blacklist (issue #207) udl_block(){ # if necessary create blacklist.conf if [ ! -f $blacklist ]; then touch $blacklist fi if ! grep -Fxq "blacklist udlfb" $blacklist then echo "Adding udlfb to blacklist" echo "blacklist udlfb" >> $blacklist fi # add udl to blacklist (issue #207) if ! grep -Fxq "blacklist udl" $blacklist then echo "Adding udl to blacklist" echo "blacklist udl" >> $blacklist fi } # add udl/udlfb to blacklist depending on kernel version (issue #207) if [ "$(ver2int $kernel_check)" -ge "$(ver2int '4.14.9')" ]; then udl_block fi } # post install post_install(){ separator echo -e "\nPerforming post install steps\n" if [ "$kconfig_exists" == "false" ]; then rm $kconfig_file fi # fix: issue #42 (dlm.service can't start) # note: for this to work libstdc++6 package needs to be installed from >= Stretch if [ "$lsb" == "Debian" ] || [ "$lsb" == "Devuan" ] || [ "$lsb" == "Kali" ]; then ln -sf /usr/lib/x86_64-linux-gnu/libstdc++.so.6 /opt/displaylink/libstdc++.so.6 fi sysinitdaemon=$(sysinitdaemon_get) if [ "$sysinitdaemon" == "systemd" ] then # Fix inability to enable displaylink-driver.service sed -i "/RestartSec=5/a[Install]\nWantedBy=multi-user.target" /lib/systemd/system/displaylink-driver.service echo "Enable displaylink-driver service" systemctl enable displaylink-driver.service elif [ "$sysinitdaemon" == "sysvinit" ] then echo "Copying init script to /etc/init.d\n" cp "$dir/$init_script" /etc/init.d/ chmod +x "/etc/init.d/$init_script" echo "Load evdi at startup" cat > "$evdi_modprobe" < $xorg_config_displaylink < $xorg_config_displaylink < $xorg_config_displaylink <> $xsetup_loc << EOL xrandr --setprovideroutputsource modesetting NVIDIA-0 xrandr --auto EOL } nvidia_xrandr_full(){ cat >> $xsetup_loc << EOL #!/bin/sh # Xsetup - run as root before the login dialog appears if [ -e /sbin/prime-offload ]; then echo running NVIDIA Prime setup /sbin/prime-offload /sbin/prime-offload fi xrandr --setprovideroutputsource modesetting NVIDIA-0 xrandr --auto EOL } # create Xsetup file if not there + make necessary changes (issue: #201, #206) if [ ! -f $xsetup_loc ]; then echo "$xsetup_loc not found, creating" mkdir -p /usr/share/sddm/scripts/ touch $xsetup_loc nvidia_xrandr_full chmod +x $xsetup_loc echo -e "Wrote changes to $xsetup_loc" fi # make necessary changes to Xsetup if ! grep -q "setprovideroutputsource modesetting" $xsetup_loc then mv $xsetup_loc $xsetup_loc.org.bak echo -e "\nMade backup of: $xsetup_loc file" echo -e "\nLocation: $xsetup_loc.org.bak" nvidia_xrandr chmod +x $xsetup_loc echo -e "Wrote changes to $xsetup_loc" fi # xorg.conf ops xorg_config="/etc/x11/xorg.conf" usr_xorg_config_displaylink="/usr/share/X11/xorg.conf.d/20-displaylink.conf" if [ -f $xorg_config ]; then mv $xorg_config $xorg_config.org.bak echo -e "\nMade backup of: $xorg_config file" echo -e "\nLocation: $xorg_config.org.bak" fi if [ -f $xorg_config_displaylink ]; then mv $xorg_config_displaylink $xorg_config_displaylink.org.bak echo -e "\nMade backup of: $xorg_config_displaylink file" echo -e "\nLocation: $xorg_config_displaylink.org.bak" fi if [ -f $usr_xorg_config_displaylink ]; then mv $usr_xorg_config_displaylink $usr_xorg_config_displaylink.org.bak echo -e "\nMade backup of: $usr_xorg_config_displaylink file" echo -e "\nLocation: $usr_xorg_config_displaylink.org.bak" fi } # nvidia displaylink xorg.conf (issue: 176) xorg_nvidia(){ cat > $xorg_config_displaylink < $xorg_config_displaylink <&1>/dev/null # remove modesetting file if [ -f $xorg_config_displaylink ] then echo "Removing Displaylink Xorg config file" rm $xorg_config_displaylink fi # delete udl/udlfb from blacklist (issue #207) sed -i '/blacklist udlfb/d' $blacklist sed -i '/blacklist udl/d' $blacklist } # debug: get system information for issue debug debug(){ separator echo -e "\nStarting Debug ...\n" default=N ack=${ack:-$default} read -p "Did you read Post Installation Guide? https://github.com/AdnanHodzic/displaylink-debian/blob/master/docs/post-install-guide.md [y/N] " ack ack=${ack:-$default} for letter in "$ack"; do if [[ "$letter" == [Yy] ]]; then echo "" continue elif [[ "$letter" == [Nn] ]]; then echo -e "\nPlease read Post Installation Guide: https://github.com/AdnanHodzic/displaylink-debian/blob/master/docs/post-install-guide.md\n" exit 1 else wrong_key fi done read -p "Did you read Troubleshooting most common issues? https://github.com/AdnanHodzic/displaylink-debian/blob/master/docs/common-issues.md [y/N] " ack ack=${ack:-$default} for letter in "$ack"; do if [[ "$letter" == [Yy] ]]; then echo -e "" continue elif [[ "$letter" == [Nn] ]]; then echo -e "\nPlease read Troubleshooting most common issues: https://github.com/AdnanHodzic/displaylink-debian/blob/master/docs/common-issues.md\n" exit 1 else wrong_key fi done if [ -f /sys/devices/evdi/version ] then evdi_version="$(cat /sys/devices/evdi/version)" else evdi_version="/sys/devices/evdi/version not found" fi echo -e "--------------- Linux system info ----------------\n" echo -e "Distro: $lsb" echo -e "Release: $codename" echo -e "Kernel: $kernel" echo -e "\n---------------- DisplayLink info ----------------\n" echo -e "Driver version: $sys_driver_version" echo -e "DisplayLink service status: $(displaylink_service_check)" echo -e "EVDI service version: $evdi_version" echo -e "\n------------------ Graphics card -----------------\n" echo -e "Vendor: $graphics_vendor" echo -e "Subsystem: $graphics_subcard" echo -e "VGA: $vga_info" echo -e "VGA (3D): $vga_info_3d" echo -e "X11 version: $xorg_vcheck" xconfig_list echo -e "\n-------------- DisplayLink xorg.conf -------------\n" echo -e "File: $xorg_config_displaylink" echo -e "Contents:\n $(cat $xorg_config_displaylink)" echo -e "\n-------------------- Monitors --------------------\n" echo -e "$providers" } # interactively asks for operation ask_operation(){ echo -e "\n--------------------------- displaylink-debian -------------------------------" echo -e "\nDisplayLink driver installer for Debian and Ubuntu based Linux distributions:\n" echo -e "* Debian, Ubuntu, Elementary OS, Mint, Kali, Deepin and many more!" echo -e "* Full list of all supported platforms: http://bit.ly/2zrwz2u" echo -e "* When submitting a new issue, include Debug information" echo -e "\nOptions:\n" read -p "[I]nstall [D]ebug [R]e-install [U]ninstall [Q]uit Select a key: [i/d/r/u/q]: " answer } root_check if [[ "$#" -lt 1 ]]; then ask_operation else case "${1}" in "--install") answer="i" ;; "--uninstall") answer="u" ;; "--reinstall") answer="r" ;; "--debug") answer="d" ;; *) answer="n" ;; esac fi if [[ $answer == [Ii] ]]; then distro_check pre_install install post_install clean_up separator echo -e "\nInstall complete, please reboot to apply the changes" echo -e "After reboot, make sure to consult post-install guide! https://github.com/AdnanHodzic/displaylink-debian/blob/master/docs/post-install-guide.md" setup_complete separator echo "" elif [[ $answer == [Uu] ]]; then distro_check uninstall clean_up separator echo -e "\nUninstall complete, please reboot to apply the changes" setup_complete separator echo "" elif [[ $answer == [Rr] ]]; then distro_check uninstall clean_up distro_check pre_install install post_install clean_up separator echo -e "\nInstall complete, please reboot to apply the changes" echo -e "After reboot, make sure to consult post-install guide! https://github.com/AdnanHodzic/displaylink-debian/blob/master/docs/post-install-guide.md" setup_complete separator echo "" elif [[ $answer == [Dd] ]]; then debug separator echo -e "\nUse this information when submitting an issue (http://bit.ly/2GLDlpY)" separator echo "" elif [[ $answer == [Qq] ]]; then separator echo "" exit 0 else echo -e "\nWrong key, aborting ...\n" exit 1 fi