Change screen resolution in VNC session
This is one solution for creating VNC session between computer with different resolution.
I have one powerful computer, running with a 1920x1080 screen, and one little 10' netbook with a 1024x600 display. Sometimes I just want to lay on the couch next to my desk but continue working using the X session on the PC computer, so I use VNC to connect from my netbook to the current X session on the computer. The operation is pretty straightforward but I ran in some probems due to the different resolution of the screens, so I wrote a script in order to automate the process of creating the VNC session.
For the server I'll use x11vnc, which allows to view the existing x11 display, while for the client vncviewer will be used.
x11vnc have one option for scaling the screen to a different resolution, but the results were not as good as having the screen running at the same resolution of the client display. This is because just scaling down the size will results in really small letters and everything will be really tiny.
A better result can be obtained by changing the resolution on the server host
so that it match the size of the client screen. You can do that by using
xrandr
tool, and selecting one of the available mode for your screen.
In my case the resolution of the client display was not available in the modes
on the server machine, this problem can be resolved by calculating the CVT mode
with the cvt
tool and adding a new mode.
The script you can find below will do the following operation:
- Get the client resolution.
- Connect to server using ssh.
- Get all available resolution on the server.
- If the client resolution is available, change to client resolution, else add and use client resolution.
- Launch
x11vnc
server. - Launch
xvncviewer
client.
This is the script, you should change the variable at the start where indicated:
## LOCAL CONFIG ##
IP_LOCAL=change_to_client_ip
IFACE_LOCAL=change_to_client_net_iface
MODE_LOCAL=""
## REMOTE CONFIG ##
IP_REMOTE=change_to_server_ip
USR_REMOTE=change_to_your_username
OUTPUT_REMOTE=""
MODE_REMOTE=""
######################
# bring up local iface, comment out if not neccesary
su -c "ifconfig $IFACE_LOCAL $IP_LOCAL netmask 255.255.255.0 up"
# get local resolution
MODE_LOCAL=$(xrandr | grep \*| awk '{print $1}')
# connect to remote box with ssh
ssh $USR_REMOTE@$IP_REMOTE <<-ENDOFSCRIPT
#set DISPLAY env var
export DISPLAY=:0.0
# get remote output name
OUTPUT_REMOTE="\$(xrandr | grep " connected" | awk '{print \$1}')"
#get all available resolution for remote box
modes=\$( xrandr | sed -e "1,/\$OUTPUT_REMOTE/ d" \
-e "/connected/,$ d" \
-e "s/\([^[:space:]]\)[[:space:]].*/\1/" )
#check if the desired (local) resolution is available
if [[ \$modes == *"$MODE_LOCAL"* ]]
then
echo "Current resolution available";
#check if desired resolution is currently used
if [[ \$(xrandr | grep \* | awk '{print $1}') == *"$MODE_LOCAL"* ]]
then
echo "Desired resolution available and already in use"
else
echo "Desired resolution available, changing to desired"
for m in \$modes
do
if [[ \$m == *"$MODE_LOCAL"* ]]
then
xrandr --output "\$OUTPUT_REMOTE" --mode "\$m";
fi
done
fi
else
echo "Desired resolution not available, adding new mode and changing
resolution";
#calculate CVT mode
MODE_NAME=$(cvt "$(echo $MODE_LOCAL|cut -dx -f1)" "$(echo $MODE_LOCAL|cut -dx \
-f2)"| tail -n 1| cut -d\" -f2)
MODE_PARAM="$(cvt "$(echo $MODE_LOCAL|cut -dx -f1)" "$(echo $MODE_LOCAL|cut -dx \
-f2)"| tail -n 1| cut -d\" -f3)"
#add new mode and change resolution
xrandr --newmode \$MODE_NAME \$MODE_PARAM;
xrandr --addmode "\$OUTPUT_REMOTE" "\$MODE_NAME";
xrandr --output "\$OUTPUT_REMOTE" --mode "\$MODE_NAME";
fi
#start x11vnc server
x11vnc -display :0 -usepw -listen $IP_REMOTE -bg
ENDOFSCRIPT
#start VNC viewer
xvncviewer --fullscreen "$IP_REMOTE"
Now all I have to do is launch ./vnc.sh
and insert a few passwords (you can
make it passwordless using sudo, using ssh keys, etc..) and the script will
automatically set the resolution of the server so that it match the one on the
client.