diff options
Diffstat (limited to 'x11vnc/misc/panner.pl')
-rwxr-xr-x | x11vnc/misc/panner.pl | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/x11vnc/misc/panner.pl b/x11vnc/misc/panner.pl new file mode 100755 index 0000000..344beee --- /dev/null +++ b/x11vnc/misc/panner.pl @@ -0,0 +1,117 @@ +#!/usr/bin/perl +# +# panner.pl: start up x11vnc in '-clip' mode viewing a small (WxH) +# rectangular region of the screen. Allow the viewer user +# to 'pan' around the display region by moving the mouse. +# +# Remote interaction with applications, e.g. clicking a +# button though the VNC viewer, will be very difficult. +# This may be useful in a 'demo' mode where the user sitting +# at the physical display is the only one moving the mouse. +# Depending on your usage the following x11vnc options may +# be useful: -nonap +# +# Usage: panner.pl WxH <x11vnc-args> (e.g. -display ...) +# or panner.pl WxH:0.05 <x11vnc-args> (e.g. 0.05 is polling time in secs.) + +use strict; + +my $WxH = shift; +my $poll_time; + +# split off poll time: +# +($WxH, $poll_time) = split(/:/, $WxH); +my ($W, $H) = split(/x/, $WxH); + +$poll_time = 0.1 unless $poll_time ne ''; + +# set to x11vnc command (e.g. full PATH) +# +my $x11vnc = "x11vnc"; + +# check if display was given: +# +my $query_args = ""; +for (my $i=0; $i < @ARGV; $i++) { + if ($ARGV[$i] eq '-display') { + $query_args = "-display $ARGV[$i+1]"; + } +} + +# find the size of display and the current mouse position: +my %v; +vset("DIRECT:wdpy_x,wdpy_y,pointer_x,pointer_y,pointer_same"); + +# set a -clip argument based on the above: +# +my $clip = ''; +clip_set(); +$clip = "${W}x${H}+0+0" unless $v{pointer_same}; + +# launch x11vnc with -clip in the background: +# +my $cmd = "$x11vnc -clip $clip -bg " . join(" ", @ARGV); +print STDERR "running: $cmd\n"; +system $cmd; + +# user can hit Ctrl-C or kill this script to quit (and stop x11vnc) +# +sub quit { + system("$x11vnc $query_args -R stop"); + exit 0; +} + +$SIG{INT} = \&quit; +$SIG{TERM} = \&quit; + +# loop forever waiting for mouse position to change, then shift -clip: +# +my $clip_old = $clip; +while (1) { + fsleep($poll_time); + vset("pointer_x,pointer_y,pointer_same"); + next unless $v{pointer_same}; + clip_set(); + if ($clip ne $clip_old) { + system("$x11vnc $query_args -R clip:$clip"); + $clip_old = $clip + } +} + +exit 0; + +# short sleep: +# +sub fsleep { + my ($time) = @_; + select(undef, undef, undef, $time) if $time; +} + +# set the -clip string, making sure view doesn't go off edges of display: +# +sub clip_set { + my $x = int($v{pointer_x} - $W/2); + my $y = int($v{pointer_y} - $H/2); + $x = 0 if $x < 0; + $y = 0 if $y < 0; + $x = $v{wdpy_x} - $W if $x + $W > $v{wdpy_x}; + $y = $v{wdpy_y} - $H if $y + $H > $v{wdpy_y}; + $clip = "${W}x${H}+$x+$y"; +} + +# query x11vnc for values, put results in the %v hash: +# +sub vset { + my $str = shift; + my $out = `$x11vnc $query_args -Q $str 2>/dev/null`; + chomp $out; + foreach my $pair (split(/,/, $out)) { + $pair =~ s/^a..=//; + my ($k, $v) = split(/:/, $pair, 2); + if ($k ne '' && $v ne '') { + print STDERR "k=$k v=$v\n" if $ENV{DEBUG}; + $v{$k} = $v; + } + } +} |