ich möchte unbedingt auch eine Möglichkeit finden um die native Auflösung des Beamers zu verwenden, damit bei Präsentationen die beste Anzeigequalität für das Publikum garantiert ist.
Wie man die native Auflösung herausfindet, habe ich nun ja gelöst.
Ich rätsele aber noch daran, wie man dann die beste Auflösung des zweiten Anzeigegeräts bestimmen könnte. Da bräuchte ich Hilfe.
Ich meine, dass man mehrere Überprüfungen machen müsste:
Bester Fall: Wird die native Beamerauflösung auch vom zweiten Anzeigegerät unterstützt?
Bingo!
Nächter Fall: Passt das Bild ganz auf das zweite Anzeigegerät (mit möglichst wenig schwarzen Rändern)?
Gibt es Auflösungen vom zweiten Anzeigegerät, bei der x- und y-Auflösung größergleich sind als bei der Beamerauflösung? Dann davon die kleinste nehmen.
Nächster Fall: Es wird ein Teil des Bildes auf jeden Fall abgeschnitten. Es soll aber möglichst wenig Verlust geben.
Wie könnte man dann die versch. Verlustmöglichkeiten priorisieren?
x-Auflösung ohne Verlust
vor
y-Auflösung ohne Verlust
vor
geringsten Verlust ermitteln aus Summe von Verlust bei x-Auflösung + Verlust bei y-Auflösung
nach längerem Ausprobieren, habe ich nun eine Lösung gefunden, die sich im privaten Bereich mit 2 Anzeigegeräten schon bewährt:
Ein Skript stellt beim Aufrufen die native Bildschirmauflösung für 1 Anzeigegerät ein und klont die Anzeige skaliert auf das andere Anzeigegerät.
So ist auf einem Anzeigegerät immer die optimale Darstellung gegeben und auf dem anderen Anzeigegerät wird die Darstellung zwar verzerrt aber vollständig angezeigt unter Ausnutzung der gesamten Bildschirmfläche. Durch erneutes Starten wird das andere Anzeigegerät als jenes mit der native Bildschirmauflösung gesetzt.
Das Skript habe ich nun so erweitert, dass alle Einstellungen vom Skript selbst ermittelt werden. Man muss also das Skript nicht konfigurieren.
Getestet habe ich es nur mit 2 Anzeigegeräten - aber ich habe die Hoffnung, dass es auch mit mehr als 2 Anzeigegeräten funktionieren könnte. Ich habe jedenfalls versucht die for-Schleife so zu bauen, dass es möglich sein sollte. Ob der xrandr-Befehl das aber packt, weiß ich nicht.
Wer Lust hat zu testen, möge bitte Rückmeldung geben.
#!/bin/bash
# Anzeige skaliert klonen
#
# Stellt die native Bildschirmauflösung für 1 Anzeigegerät ein und skaliert die anderen Anzeigegeräte.
# So ist auf einem Anzeigegerät immer die optimale Darstellung gegeben
# und auf den restlichen Anzeigegeräten wird die Darstellung zwar verzerrt aber vollständig angezeigt
# unter Ausnutzung der gesamten Bildschirmfläche.
# Durch erneutes Starten wird das nächste Anzeigegerät als jenes mit der native Bildschirmauflösung ausgewählt
#
# Sen 2017-10-14
# Linux Mint 18.2 Xfce 64bit
#
# GPL v3
# NUR FÜR XFCE-Desktop geeignet: Shortcut setzen, um Skript per Shortcut aufrufen zu können
# xfconf-query -c xfce4-keyboard-shortcuts -p "/commands/custom/<Primary><Alt>r" -n -t string -s "/opt/xrandr-beamer/xrandr-beamer-clone.sh"
# Anzahl der angeschlossenen Anzeigeräte ermitteln
dispcon=($(xrandr --query | grep -c " connected"))
# Höchste Nummer der Anzeigegeräte
dispmaxnumb=$((dispcon - 1))
# Bezeichnungen aller angeschlossenen Anzeigeräte ermitteln
disp=($(xrandr --query | grep " connected" | awk '{print $1}'))
# Native Auflösungen der angeschlossenen Anzeigeräte ermitteln
natres=($(xrandr --query | grep -e \+$ -e \+[[:space:]] | awk '{print $1}'))
case $dispcon in
1*)
### Ein Anzeigegerät angeschlossen
# Standardauflösung einstellen
xrandr --output ${disp[0]} --mode ${natres[0]} --scale 1x1
;;
*)
### Mehrere Anzeigegeräte angeschlossen
# Zähler auslesen - Nummer des zuletzt nativ angezeigten Anzeigegeräts
numb=$(head -n 1 /tmp/xrandr-beamer-clone.log)
# Zähler erhöhen
numb=$((numb + 1))
# Zähler überprüfen und gegebenenfalls zurücksetzen
[[ ! $numb = [0-$dispmaxnumb] ]] && numb=0
# Zähler in Datei schreiben
echo $numb > /tmp/xrandr-beamer-clone.log
# Auflösungen einstellen
for((i=0; i<$dispcon; i++)); do
if [ ! $i = $numb ]; then
xrandr --output ${disp[$numb]} --mode ${natres[$numb]} --scale 1x1 --output ${disp[$i]} --same-as ${disp[$numb]} --mode ${natres[$i]} --scale-from ${natres[$numb]}
fi
done
;;
esac
# Benachrichtigung anzeigen
notify-send -t 8700 "Anzeige ist nun optimiert für Anzeigerät ${disp[$numb]}"
exit 0
P.S: Ich bevorzuge nun diese Methode, weil die andere Methode, welche die größte gemeinsame Auflösung verwendet, sich mit den neueren Beamern leider bei mir nicht bewährt hat, da Beamer mit nativ 1024x768 mittlerweile auch Auflösungen anbieten wie 1366x768. Dann kommt es zu unschönen Anzeigen.
ich bräuchte etwas Hilfe beim Ermitteln der nativen Auflösung eines Anzeigegerätes damit das oben veröffentlichte Skript oder sein verbesserter Nachfolger (auf einem Anzeigegerät die native Auflösung; keine verzerrten Darstellungen bei den anderen Anzeigegerät, sondern maximale Einpassung mit schwarzen Rändern) in mehr Fällen korrekt funktioniert.
Das Problem ist, dass manche Anzeigegeräte mehr als eine native Auflösung in xrandr anbieten, zu erkenen an den Pluszeichen - hier bei VGA1:
linuxadmin@edv-l24oss ~ $ xrandr
Screen 0: minimum 320 x 200, current 1366 x 768, maximum 32767 x 32767
LVDS1 connected 1366x768+0+0 (normal left inverted right x axis y axis) 310mm x 174mm
1366x768 60.0*+
1360x768 59.8 60.0
1024x768 60.0
800x600 60.3 56.2
640x480 59.9
VGA1 connected 1366x768+0+0 (normal left inverted right x axis y axis) 518mm x 324mm
1920x1200 60.0*+
1920x1080 60.0 +
1600x1200 60.0
1680x1050 60.0
1280x1024 60.0
1280x960 60.0
1024x768 60.0
800x600 60.3
640x480 60.0
720x400 70.1
HDMI1 disconnected (normal left inverted right x axis y axis)
DP1 disconnected (normal left inverted right x axis y axis)
HDMI2 disconnected (normal left inverted right x axis y axis)
HDMI3 disconnected (normal left inverted right x axis y axis)
DP2 disconnected (normal left inverted right x axis y axis)
DP3 disconnected (normal left inverted right x axis y axis)
VIRTUAL1 disconnected (normal left inverted right x axis y axis)
Ich bräuchte einen bash-Code, der für jedes Anzeigegerät nur die erste der Auflösungen mit einem Pluszeichen ermittelt.
Die momentan verwendete Codezeile gibt alle Auflösungen mit einem Pluszeichen in der Zeile aus. dadurch kann die Zuordnung der nativen Auflösungen zu den Anzeigegeräten fehlerhaft werden.
Danke für den Versuch, aber der sed-Befehl gibt einfach nur die erste aller Zeilen mit dem “+” aus.
Ich brauche aber JEWEILS die erste Zeile der Auflösung mit “+” für JEDES Anzeigegerät. Das ist knifflig, weil das Anzeigegerät (z.B. VGA1) nicht in der selben Zeile steht, wie die erste Zeile der Auflösung mit “+”.
Man kann es also nicht einfach mit einem Tool lösen, welches nur zeilenweise funktioniert.
#!/bin/bash
# by Christoph Guenschmann
xrandr -q >xrandr_output
za=`cat xrandr_output|wc -l`
for ((z=1;z<=$za;z++));
do
cat xrandr_output|sed -n `echo $z`p >line1
vo=`awk '{ if ($1 ~ /[L,V,D,H]/) print $1 }' line1`
vo_state=`awk '{ if ($1 ~ /[L,V,D,H]/) print $2 }' line1`
if [ "$vo_state" = "connected" ]
then
echo "Ausgang:$vo"
echo "Status:$vo_state"
unset vo_res
# Innere Schleife
while [ "$vo_res" = '' ]
do
((z++))
cat xrandr_output|sed -n `echo $z`p >line2
vo_res=`cat line2 | grep -e [[:space:]]\+$ -e *\+$ -e \+[[:space:]] \
| awk '{print $1}'`
# Endlosschleife bei fehlerhafter Ausgabe von xrandr vermeiden
if [ "$z" -gt 50 ] ; then
break
fi
done
echo $vo_res
echo "--------------"
fi
done
Liebe Grüße,
Christoph Gü
(P.S. Ich bin nicht der bash/awk/sed-Experte. Insbesondere bei der Variablenübergabe habe ich sehr grob gearbeitet - da ist sicher mehr Eleganz möglich)
hier nun das Skript, welche die Anzeigen mehrerer Anzeigegeräte automatisch klont
und zwar ohne irgendwelche Bildverzerrungen,
so dass die native Bildschirmauflösung für 1 Anzeigegerät eingestellt wird
und die anderen Anzeigegeräte unter maximaler möglicher Ausnutzung der Pixel skaliert werden.
Durch erneutes Starten des Skriptes wird das nächste Anzeigegerät als jenes mit der nativen Bildschirmauflösung ausgewählt. Um es den Benutzern einfach zu machen, kann man deshalb einen Starter mit passendem Icon auf dem Desktop erstellen. So müssen die Benutzer einfach nur so lange darauf klicken bis eine gefällige Anzeige erscheint.
Man kann das Skript zusätzlich auch in den Login-Autostart legen, so dass es nach der Anmeldung gleich ausgeführt wird.
Skript:
/opt/videosettings/xrandr-video-clone.sh
Eintrag wurde entfernt - Aktueller Beitrag siehe unten
Starter:
Desktop aller Benutzer: /home/linuxadmin/Desktop/xrandr-video-clone.desktop
Programmenü: /usr/share/applications/xrandr-video-clone.desktop
Autostart: /etc/xdg/autostart/xrandr-video-clone.desktop
[Desktop Entry]
Version=1.0
Type=Application
Name=Anzeige optimieren
Comment=Optimiert die Anzeige bei oder nach der Verwendung von mehreren Anzeigegeräten. Starten Sie diese Anwendung so oft bis die Auflösungen der Bildschirmanzeigen Ihnen zusagen. Tastaturkürzel: Strg+Alt+r
Exec=/opt/videosettings/xrandr-video-clone.sh
Icon=/usr/share/icons/resolution.png
Categories=Utility
Terminal=false
StartupNotify=false
Wer das Skript einmal vom Terminal aus aufruft, bekommt viele Ausgaben angezeigt mit denen man überprüfen kann, was berechnet wird und welche xrandr-Befehle abgesetzt werden.
Das Skripte sollte auch für mehr als 2 Anzeigegeräte funktionieren. Das konnte ich aber bei mir nicht testen.
Hallo STefan, habe hier: Bionic-Client: Bildschirme steuern in v7 im Thread für v7 mal dasselbe versucht und bin nach reichlich probieren mit deinem Skript zufrieden. Vielen Dank! Ich habe die SChleifen etwas angepasst, aber den rescale-mechanismus nicht angefasst und poste es mal hier:
#!/bin/bash
# xrandr-video-clone
#
# Speicherort: /opt/videosettings/xrandr-video-clone.sh
#
# Stellt die maximale Bildschirmauflösung für 1 Anzeigegerät ein und skaliert die anderen Anzeigegeräte ohne Bildverzerrung.
# Durch erneutes Starten wird das nächste Anzeigegerät als jenes mit der nativen Bildschirmauflösung ausgewählt
#
# Linux Mint 17.0 Xfce 64bit
# Linux Mint 18.2 Xfce 64bit
# Ubuntu Bionic 18.04 64bit
#
# Sen 2017-12-12
# T.Küchel 2019-09-30
# GPL v3
### Shortcut setzen, um Skript per Shortcut aufrufen zu können (NUR FÜR XFCE-Desktop)
# xfconf-query -c xfce4-keyboard-shortcuts -p "/commands/custom/<Primary><Alt>r" -n -t string -s "/opt/videosettings/xrandr-video-clone.sh"
outputfile=`mktemp`
logger -t "$0[$USER]" "Output in $outputfile"
### Ermitteln der angeschlossenen Anzeigeräte und der jewiligen ersten nativen Auflösung
xrandr --query --verbose > $outputfile
## Fehlerhaftes xrandr (z.B. kein DISPLAY) abfangen
[ $? -ne 0 ] && { echo usage: $0 ; exit 1; }
## Zeilenanzahl
za=`cat $outputfile | wc -l`
nmbr=0
z=0
# Äußere Schleife über alle Zeilen von $outputfile
while read line1; do
((z++))
## need the lines with either "connected" or "disconnected"
if echo $line1 | grep -i "connected" >/dev/null ; then
vo=$(echo -n $line1 | cut -d " " -f 1)
vo_state=$(echo -n $line1 | cut -d " " -f 2)
if [ "$vo_state" = "connected" ] ; then
## maximale gemeinsame Auflösung, wenn es mehr als ein Display gibt (Danke, @Sven)
MAXAUFLOESUNG=$(xrandr --query | awk '/^ *[0-9]*x[0-9]*/{ print $1 }' | sort -n | uniq -d | tail -1)
if [ -z "$MAXAUFLOESUNG" ]; then
MAXAUFLOESUNG=$(xrandr --query | awk '/^ *[0-9]*x[0-9]*/{ print $1 }' | sort -n | tail -1)
fi
## Standardauflösung finden
preferredfile=`mktemp`
unset vo_res
# Innere Schleife, um die nachfolgenden Zeilen nach der bevorzugten Auflösung zu durchsuchen
while [ "$vo_res" = '' ] ; do
((z++))
cat $outputfile | sed -n `echo $z`p > $preferredfile
line2=$(cat $preferredfile)
if echo $line2 | grep -i "preferred" >/dev/null; then
vo_res=$(echo -n $line2 | cut -d " " -f 1)
fi
#vo_res=`cat /tmp/xrandr-video-clone.ln2 | grep -e \+preferred$ -e \+preferred[[:space:]] | awk '{print $1}'`
# Endlosschleife bei fehlerhafter Ausgabe von xrandr vermeiden
if [ "$z" -gt 1000 ] ; then
echo "no preferred resolution found"
break
fi
done
rm -f $preferredfile
## Bezeichnungen des angeschlossenen Anzeigeräts speichern
disp[nmbr]=$vo
echo "Angeschlossenes Anzeigegerät Nr.$nmbr: ${disp[nmbr]}"
logger -t "$0[$USER]" "Angeschlossenes Anzeigegerät Nr.$nmbr: ${disp[nmbr]}"
# Native Auflösungen des angeschlossenen Anzeigeräts speichern
natres[nmbr]=$vo_res
natresx[nmbr]=$(echo $vo_res | cut -dx -f1)
natresy[nmbr]=$(echo $vo_res | cut -dx -f2)
echo "Bevorzugte Auflösung: xres: ${natresx[nmbr]}, yres: ${natresy[nmbr]}"
echo "Maximale (gemeinsame) Auflösung: $MAXAUFLOESUNG"
echo "--------------"
maxres[nmbr]=$MAXAUFLOESUNG
maxresx[nmbr]=$(echo $MAXAUFLOESUNG | cut -dx -f1)
maxresy[nmbr]=$(echo $MAXAUFLOESUNG | cut -dx -f2)
# Höchste Nummer der angeschlossenen Anzeigeräte speichern (beginnend mit 0)
dispmaxnumb=$nmbr
# Zähler erhöhen
nmbr=$((nmbr + 1))
# Anzahl der angeschlossenen Anzeigeräte speichern (beginnend mit 1)
dispcon=$nmbr
fi
fi
done < $outputfile
rm -f $outputfile
echo "Höchste Nr. der angeschlossenen Anzeigegeräte: $dispmaxnumb"
logger -t "$0[$USER]" "Höchste Nr. der angeschlossenen Anzeigegeräte: $dispmaxnumb"
echo "Anzahl der angeschlossenen Anzeigegeräte: $dispcon"
logger -t "$0[$USER]" "Anzahl der angeschlossenen Anzeigegeräte: $dispcon"
### Fallunterscheidung falls nur 1 Anzeigegerät angeschlossen ist
case $dispcon in
1)
### Ein Anzeigegerät angeschlossen
# Standardauflösung einstellen
#xrandr --output ${disp[0]} --mode ${natres[0]} --scale 1x1
# Maximalauflösung einstellen
xrandr --output ${disp[0]} --mode ${maxres[0]} --scale 1x1
;;
2-9)
### Mehrere Anzeigegeräte angeschlossen
# Zähler für natives Anzeigegerät
numb=$(head -n 1 /tmp/xrandr-video-clone.log)
# Zähler erhöhen
numb=$((numb + 1))
# Zähler überprüfen und gegebenenfalls zurücksetzen
[[ ! $numb = [0-$dispmaxnumb] ]] && numb=0
# Zähler in Datei schreiben
echo $numb > /tmp/xrandr-video-clone.log
# Zähler für anzupassende Anzeigegeräte
for ((i=0; i<$dispcon; i++)) ; do
if [ ! $i = $numb ] ; then
# Anzupassenden Anzeigemodus berechnen
quotx=$(echo "scale=8; ${natresx[$numb]} / ${natresx[$i]}" | bc -l)
echo "xopt: ${natresx[$numb]}"
echo "xtofit: ${natresx[$i]}"
echo "xquot: $quotx"
quoty=$(echo "scale=8; ${natresy[$numb]} / ${natresy[$i]}" | bc -l)
echo "yopt: ${natresy[$numb]}"
echo "ytofit: ${natresy[$i]}"
echo "yquot: $quoty"
if ( expr $quotx \> $quoty >/dev/null ) ; then
echo "xquot>yquot"
fitresx[$i]=${natresx[$i]}
fitresy[$i]=$(echo "scale=0; ${natresx[$i]} * ${natresy[$numb]} / ${natresx[$numb]}" | bc -l)
echo "xfit: ${fitresx[$i]}"
echo "yfit: ${fitresy[$i]}"
else
echo "yquot>xquot"
fitresy[$i]=${natresy[$i]}
fitresx[$i]=$(echo "scale=0; ${natresy[$i]} * ${natresx[$numb]} / ${natresy[$numb]}" | bc -l)
echo "xfit: ${fitresx[$i]}"
echo "yfit: ${fitresy[$i]}"
fi
fitmodeline[$i]=$(cvt ${fitresx[$i]} ${fitresy[$i]} | grep Modeline | cut -d\" -f2,3 | sed 's/\"//g')
fitmode[$i]=$(cvt ${fitresx[$i]} ${fitresy[$i]} | grep Modeline | cut -d\" -f2)
echo "fitmodeline: ${fitmodeline[$i]}"
echo "fitmode: ${fitmode[$i]}"
# Berechneten Anzeigemodus registrieren
echo "Befehlszeile: xrandr --newmode ${fitmodeline[$i]}"
xrandr --newmode ${fitmodeline[$i]}
echo "Befehlszeile: xrandr --addmode ${disp[$i]} ${fitmode[$i]}"
xrandr --addmode ${disp[$i]} ${fitmode[$i]}
# Anzeige klonen
echo "Befehlszeile: xrandr --output ${disp[$numb]} --mode ${natres[$numb]} --scale 1x1 --output ${disp[$i]} --same-as ${disp[$numb]} --mode ${fitmode[$i]} --scale-from\
${natres[$numb]}"
xrandr --output ${disp[$numb]} --mode ${natres[$numb]} --scale 1x1 --output ${disp[$i]} --same-as ${disp[$numb]} --mode ${fitmode[$i]} --scale-from ${natres[$numb]}
fi
done
;;
*)
echo "Mehr als 9 Anzeigegeräte vorsichtshalber nicht unterstützt. Kann man sicher machen..."
;;
esac
### Benachrichtigung anzeigen
notify-send -t 8700 "Optimiert für Anzeige ${disp[$numb]}"
logger -t "$0[$USER]" "Optimiert für Anzeige ${disp[$numb]}"
exit 0
Mit dem „rescale-mechanismus“ hatte ich bei einigen Rechnern Probleme.
An der Stelle
xrandr --newmode ${fitmodeline[$i]}
oder
xrandr --addmode ${disp[$i]} ${fitmode[$i]}
Es kam dort zu Fehlermeldungen, dass der mittels cvt ermittelte Modus fehlerhaft wäre. Um das zu beheben, reichte meine xrandr-Recherche leider nicht aus. Ich vermute und hoffe mich recht zu erinnern, dass es Probleme gibt, wenn der ermittelte neue Modus im Prinzip mit einem schon existierenden Modus überein stimmt. An der Stelle bin ich dann ausgestiegen.
Hallo Stefan,
erst mal vielen Dank für dein Script und die Mühe. Bei mir kommt in manchen Situationen die Anzeige „Außerhalb des Bereichs“. Ich glaube das passiert dann, wenn das Script fälschlicherweise den Beamer und nicht den Monitor als primäre Anzeige erkennt(?). Leider bin ich im Scripten schlecht, so dass ich das nicht ganz verstehe. Kannst du mir erklären, was das Problem ist?