updated to new automake and refactored server stuff. the server
now speaks to the primary screen and secondary screens almost everywhere the same way through an IClient interface; only special primary screen calls are accessed through a different interface, the CPrimaryClient interface. this simplifies the server since it no longer needs to test whether the active screen is the primary or a secondary in most cases. the server no longer speaks directly to the primary screen; all that goes through the CPrimaryClient, which often just forwards the call. the primary screen no longer speaks directly to the server either, again going through the CPrimaryClient via a IPrimaryReceiver interface. CServerProtocol classes have been replaced by CClientProxy classes which are very similar. the name makes more sense though.
This commit is contained in:
parent
bdfdc8e816
commit
64232c7854
|
@ -0,0 +1,411 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
# depcomp - compile a program generating dependencies as side-effects
|
||||||
|
# Copyright 1999, 2000 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||||
|
|
||||||
|
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||||
|
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# `libtool' can also be set to `yes' or `no'.
|
||||||
|
|
||||||
|
depfile=${depfile-`echo "$object" | sed 's,\([^/]*\)$,.deps/\1,;s/\.\([^.]*\)$/.P\1/'`}
|
||||||
|
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||||
|
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
|
||||||
|
# Some modes work just like other modes, but use different flags. We
|
||||||
|
# parameterize here, but still list the modes in the big case below,
|
||||||
|
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||||
|
# here, because this file can only contain one case statement.
|
||||||
|
if test "$depmode" = hp; then
|
||||||
|
# HP compiler uses -M and no extra arg.
|
||||||
|
gccflag=-M
|
||||||
|
depmode=gcc
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$depmode" = dashXmstdout; then
|
||||||
|
# This is just like dashmstdout with a different argument.
|
||||||
|
dashmflag=-xM
|
||||||
|
depmode=dashmstdout
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$depmode" in
|
||||||
|
gcc3)
|
||||||
|
## gcc 3 implements dependency tracking that does exactly what
|
||||||
|
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||||
|
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||||
|
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
mv "$tmpdepfile" "$depfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
gcc)
|
||||||
|
## There are various ways to get dependency output from gcc. Here's
|
||||||
|
## why we pick this rather obscure method:
|
||||||
|
## - Don't want to use -MD because we'd like the dependencies to end
|
||||||
|
## up in a subdir. Having to rename by hand is ugly.
|
||||||
|
## (We might end up doing this anyway to support other compilers.)
|
||||||
|
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||||
|
## -MM, not -M (despite what the docs say).
|
||||||
|
## - Using -M directly means running the compiler twice (even worse
|
||||||
|
## than renaming).
|
||||||
|
if test -z "$gccflag"; then
|
||||||
|
gccflag=-MD,
|
||||||
|
fi
|
||||||
|
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||||
|
## The second -e expression handles DOS-style file names with drive letters.
|
||||||
|
sed -e 's/^[^:]*: / /' \
|
||||||
|
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||||
|
## This next piece of magic avoids the `deleted header file' problem.
|
||||||
|
## The problem is that when a header file which appears in a .P file
|
||||||
|
## is deleted, the dependency causes make to die (because there is
|
||||||
|
## typically no way to rebuild the header). We avoid this by adding
|
||||||
|
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||||
|
## this for us directly.
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" |
|
||||||
|
## Some versions of gcc put a space before the `:'. On the theory
|
||||||
|
## that the space means something, we add a space to the output as
|
||||||
|
## well.
|
||||||
|
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
## correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
hp)
|
||||||
|
# This case exists only to let depend.m4 do its work. It works by
|
||||||
|
# looking at the text of this script. This case will never be run,
|
||||||
|
# since it is checked for above.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
sgi)
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||||
|
else
|
||||||
|
"$@" -MDupdate "$tmpdepfile"
|
||||||
|
fi
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
|
||||||
|
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
|
||||||
|
# Clip off the initial element (the dependent). Don't try to be
|
||||||
|
# clever and replace this with sed code, as IRIX sed won't handle
|
||||||
|
# lines with more than a fixed number of characters (4096 in
|
||||||
|
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||||
|
# the IRIX cc adds comments like `#:fec' to the end of the
|
||||||
|
# dependency line.
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
|
||||||
|
tr '
|
||||||
|
' ' ' >> $depfile
|
||||||
|
echo >> $depfile
|
||||||
|
|
||||||
|
# The second pass generates a dummy entry for each header file.
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||||
|
>> $depfile
|
||||||
|
else
|
||||||
|
# The sourcefile does not contain any dependencies, so just
|
||||||
|
# store a dummy comment line, to avoid errors with the Makefile
|
||||||
|
# "include basename.Plo" scheme.
|
||||||
|
echo "#dummy" > "$depfile"
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
aix)
|
||||||
|
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||||
|
# in a .u file. This file always lives in the current directory.
|
||||||
|
# Also, the AIX compiler puts `$object:' at the start of each line;
|
||||||
|
# $object doesn't have directory information.
|
||||||
|
stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
|
||||||
|
tmpdepfile="$stripped.u"
|
||||||
|
outname="$stripped.o"
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
"$@" -Wc,-M
|
||||||
|
else
|
||||||
|
"$@" -M
|
||||||
|
fi
|
||||||
|
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -f "$tmpdepfile"; then
|
||||||
|
# Each line is of the form `foo.o: dependent.h'.
|
||||||
|
# Do two passes, one to just change these to
|
||||||
|
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||||
|
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
|
||||||
|
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
|
||||||
|
else
|
||||||
|
# The sourcefile does not contain any dependencies, so just
|
||||||
|
# store a dummy comment line, to avoid errors with the Makefile
|
||||||
|
# "include basename.Plo" scheme.
|
||||||
|
echo "#dummy" > "$depfile"
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
tru64)
|
||||||
|
# The Tru64 AIX compiler uses -MD to generate dependencies as a side
|
||||||
|
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
|
||||||
|
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||||
|
# dependencies in `foo.d' instead, so we check for that too.
|
||||||
|
# Subdirectories are respected.
|
||||||
|
|
||||||
|
tmpdepfile1="$object.d"
|
||||||
|
tmpdepfile2=`echo "$object" | sed -e 's/.o$/.d/'`
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
"$@" -Wc,-MD
|
||||||
|
else
|
||||||
|
"$@" -MD
|
||||||
|
fi
|
||||||
|
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -f "$tmpdepfile1"; then
|
||||||
|
tmpdepfile="$tmpdepfile1"
|
||||||
|
else
|
||||||
|
tmpdepfile="$tmpdepfile2"
|
||||||
|
fi
|
||||||
|
if test -f "$tmpdepfile"; then
|
||||||
|
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||||
|
# That's a space and a tab in the [].
|
||||||
|
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||||
|
else
|
||||||
|
echo "#dummy" > "$depfile"
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
#nosideeffect)
|
||||||
|
# This comment above is used by automake to tell side-effect
|
||||||
|
# dependency tracking mechanisms from slower ones.
|
||||||
|
|
||||||
|
dashmstdout)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the proprocessed file to stdout, regardless of -o,
|
||||||
|
# because we must use -o when running libtool.
|
||||||
|
test -z "$dashmflag" && dashmflag=-M
|
||||||
|
( IFS=" "
|
||||||
|
case " $* " in
|
||||||
|
*" --mode=compile "*) # this is libtool, let us make it quiet
|
||||||
|
for arg
|
||||||
|
do # cycle over the arguments
|
||||||
|
case "$arg" in
|
||||||
|
"--mode=compile")
|
||||||
|
# insert --quiet before "--mode=compile"
|
||||||
|
set fnord "$@" --quiet
|
||||||
|
shift # fnord
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
set fnord "$@" "$arg"
|
||||||
|
shift # fnord
|
||||||
|
shift # "$arg"
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
"$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||||
|
) &
|
||||||
|
proc=$!
|
||||||
|
"$@"
|
||||||
|
stat=$?
|
||||||
|
wait "$proc"
|
||||||
|
if test "$stat" != 0; then exit $stat; fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
cat < "$tmpdepfile" > "$depfile"
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" | \
|
||||||
|
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
## correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
dashXmstdout)
|
||||||
|
# This case only exists to satisfy depend.m4. It is never actually
|
||||||
|
# run, as this mode is specially recognized in the preamble.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
makedepend)
|
||||||
|
# X makedepend
|
||||||
|
(
|
||||||
|
shift
|
||||||
|
cleared=no
|
||||||
|
for arg in "$@"; do
|
||||||
|
case $cleared in no)
|
||||||
|
set ""; shift
|
||||||
|
cleared=yes
|
||||||
|
esac
|
||||||
|
case "$arg" in
|
||||||
|
-D*|-I*)
|
||||||
|
set fnord "$@" "$arg"; shift;;
|
||||||
|
-*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"; shift;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
obj_suffix="`echo $object | sed 's/^.*\././'`"
|
||||||
|
touch "$tmpdepfile"
|
||||||
|
${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||||
|
) &
|
||||||
|
proc=$!
|
||||||
|
"$@"
|
||||||
|
stat=$?
|
||||||
|
wait "$proc"
|
||||||
|
if test "$stat" != 0; then exit $stat; fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
cat < "$tmpdepfile" > "$depfile"
|
||||||
|
tail +3 "$tmpdepfile" | tr ' ' '
|
||||||
|
' | \
|
||||||
|
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
## correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||||
|
;;
|
||||||
|
|
||||||
|
cpp)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the proprocessed file to stdout, regardless of -o,
|
||||||
|
# because we must use -o when running libtool.
|
||||||
|
( IFS=" "
|
||||||
|
case " $* " in
|
||||||
|
*" --mode=compile "*)
|
||||||
|
for arg
|
||||||
|
do # cycle over the arguments
|
||||||
|
case $arg in
|
||||||
|
"--mode=compile")
|
||||||
|
# insert --quiet before "--mode=compile"
|
||||||
|
set fnord "$@" --quiet
|
||||||
|
shift # fnord
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
set fnord "$@" "$arg"
|
||||||
|
shift # fnord
|
||||||
|
shift # "$arg"
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
"$@" -E |
|
||||||
|
sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
|
||||||
|
sed '$ s: \\$::' > "$tmpdepfile"
|
||||||
|
) &
|
||||||
|
proc=$!
|
||||||
|
"$@"
|
||||||
|
stat=$?
|
||||||
|
wait "$proc"
|
||||||
|
if test "$stat" != 0; then exit $stat; fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
cat < "$tmpdepfile" >> "$depfile"
|
||||||
|
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
msvisualcpp)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the proprocessed file to stdout, regardless of -o,
|
||||||
|
# because we must use -o when running libtool.
|
||||||
|
( IFS=" "
|
||||||
|
case " $* " in
|
||||||
|
*" --mode=compile "*)
|
||||||
|
for arg
|
||||||
|
do # cycle over the arguments
|
||||||
|
case $arg in
|
||||||
|
"--mode=compile")
|
||||||
|
# insert --quiet before "--mode=compile"
|
||||||
|
set fnord "$@" --quiet
|
||||||
|
shift # fnord
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
set fnord "$@" "$arg"
|
||||||
|
shift # fnord
|
||||||
|
shift # "$arg"
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
"$@" -E |
|
||||||
|
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
|
||||||
|
) &
|
||||||
|
proc=$!
|
||||||
|
"$@"
|
||||||
|
stat=$?
|
||||||
|
wait "$proc"
|
||||||
|
if test "$stat" != 0; then exit $stat; fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
|
||||||
|
echo " " >> "$depfile"
|
||||||
|
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
none)
|
||||||
|
exec "$@"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Unknown depmode $depmode" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
109
config/missing
109
config/missing
|
@ -1,7 +1,7 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Common stub for a few missing GNU programs while installing.
|
# Common stub for a few missing GNU programs while installing.
|
||||||
# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
# Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
|
||||||
# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
|
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||||
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -18,11 +18,37 @@
|
||||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
# 02111-1307, USA.
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
if test $# -eq 0; then
|
if test $# -eq 0; then
|
||||||
echo 1>&2 "Try \`$0 --help' for more information"
|
echo 1>&2 "Try \`$0 --help' for more information"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
run=:
|
||||||
|
|
||||||
|
# In the cases where this matters, `missing' is being run in the
|
||||||
|
# srcdir already.
|
||||||
|
if test -f configure.ac; then
|
||||||
|
configure_ac=configure.ac
|
||||||
|
else
|
||||||
|
configure_ac=configure.in
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
--run)
|
||||||
|
# Try to run requested program, and just exit if it succeeds.
|
||||||
|
run=
|
||||||
|
shift
|
||||||
|
"$@" && exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# If it does not exist, or fails to run (possibly an outdated version),
|
||||||
|
# try to emulate it.
|
||||||
case "$1" in
|
case "$1" in
|
||||||
|
|
||||||
-h|--h|--he|--hel|--help)
|
-h|--h|--he|--hel|--help)
|
||||||
|
@ -35,6 +61,7 @@ error status if there is no known handling for PROGRAM.
|
||||||
Options:
|
Options:
|
||||||
-h, --help display this help and exit
|
-h, --help display this help and exit
|
||||||
-v, --version output version information and exit
|
-v, --version output version information and exit
|
||||||
|
--run try to run the given command, and emulate it if it fails
|
||||||
|
|
||||||
Supported PROGRAM values:
|
Supported PROGRAM values:
|
||||||
aclocal touch file \`aclocal.m4'
|
aclocal touch file \`aclocal.m4'
|
||||||
|
@ -43,13 +70,15 @@ Supported PROGRAM values:
|
||||||
automake touch all \`Makefile.in' files
|
automake touch all \`Makefile.in' files
|
||||||
bison create \`y.tab.[ch]', if possible, from existing .[ch]
|
bison create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||||
flex create \`lex.yy.c', if possible, from existing .c
|
flex create \`lex.yy.c', if possible, from existing .c
|
||||||
|
help2man touch the output file
|
||||||
lex create \`lex.yy.c', if possible, from existing .c
|
lex create \`lex.yy.c', if possible, from existing .c
|
||||||
makeinfo touch the output file
|
makeinfo touch the output file
|
||||||
|
tar try tar, gnutar, gtar, then tar without non-portable flags
|
||||||
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
|
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||||
echo "missing - GNU libit 0.0"
|
echo "missing 0.3 - GNU automake"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
-*)
|
-*)
|
||||||
|
@ -61,7 +90,7 @@ Supported PROGRAM values:
|
||||||
aclocal)
|
aclocal)
|
||||||
echo 1>&2 "\
|
echo 1>&2 "\
|
||||||
WARNING: \`$1' is missing on your system. You should only need it if
|
WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
you modified \`acinclude.m4' or \`configure.in'. You might want
|
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
|
||||||
to install the \`Automake' and \`Perl' packages. Grab them from
|
to install the \`Automake' and \`Perl' packages. Grab them from
|
||||||
any GNU archive site."
|
any GNU archive site."
|
||||||
touch aclocal.m4
|
touch aclocal.m4
|
||||||
|
@ -70,7 +99,7 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
autoconf)
|
autoconf)
|
||||||
echo 1>&2 "\
|
echo 1>&2 "\
|
||||||
WARNING: \`$1' is missing on your system. You should only need it if
|
WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
you modified \`configure.in'. You might want to install the
|
you modified \`${configure_ac}'. You might want to install the
|
||||||
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
|
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
|
||||||
archive site."
|
archive site."
|
||||||
touch configure
|
touch configure
|
||||||
|
@ -79,10 +108,10 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
autoheader)
|
autoheader)
|
||||||
echo 1>&2 "\
|
echo 1>&2 "\
|
||||||
WARNING: \`$1' is missing on your system. You should only need it if
|
WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
you modified \`acconfig.h' or \`configure.in'. You might want
|
you modified \`acconfig.h' or \`${configure_ac}'. You might want
|
||||||
to install the \`Autoconf' and \`GNU m4' packages. Grab them
|
to install the \`Autoconf' and \`GNU m4' packages. Grab them
|
||||||
from any GNU archive site."
|
from any GNU archive site."
|
||||||
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in`
|
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
|
||||||
test -z "$files" && files="config.h"
|
test -z "$files" && files="config.h"
|
||||||
touch_files=
|
touch_files=
|
||||||
for f in $files; do
|
for f in $files; do
|
||||||
|
@ -98,7 +127,7 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
automake)
|
automake)
|
||||||
echo 1>&2 "\
|
echo 1>&2 "\
|
||||||
WARNING: \`$1' is missing on your system. You should only need it if
|
WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
|
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
|
||||||
You might want to install the \`Automake' and \`Perl' packages.
|
You might want to install the \`Automake' and \`Perl' packages.
|
||||||
Grab them from any GNU archive site."
|
Grab them from any GNU archive site."
|
||||||
find . -type f -name Makefile.am -print |
|
find . -type f -name Makefile.am -print |
|
||||||
|
@ -159,7 +188,32 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
help2man)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
|
you modified a dependency of a manual page. You may need the
|
||||||
|
\`Help2man' package in order for those modifications to take
|
||||||
|
effect. You can get \`Help2man' from any GNU archive site."
|
||||||
|
|
||||||
|
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
|
||||||
|
if test -z "$file"; then
|
||||||
|
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
|
||||||
|
fi
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
touch $file
|
||||||
|
else
|
||||||
|
test -z "$file" || exec >$file
|
||||||
|
echo ".ab help2man is required to generate this page"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
makeinfo)
|
makeinfo)
|
||||||
|
if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
|
||||||
|
# We have makeinfo, but it failed.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo 1>&2 "\
|
echo 1>&2 "\
|
||||||
WARNING: \`$1' is missing on your system. You should only need it if
|
WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
you modified a \`.texi' or \`.texinfo' file, or any other file
|
you modified a \`.texi' or \`.texinfo' file, or any other file
|
||||||
|
@ -175,6 +229,45 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
touch $file
|
touch $file
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
tar)
|
||||||
|
shift
|
||||||
|
if test -n "$run"; then
|
||||||
|
echo 1>&2 "ERROR: \`tar' requires --run"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# We have already tried tar in the generic part.
|
||||||
|
# Look for gnutar/gtar before invocation to avoid ugly error
|
||||||
|
# messages.
|
||||||
|
if (gnutar --version > /dev/null 2>&1); then
|
||||||
|
gnutar ${1+"$@"} && exit 0
|
||||||
|
fi
|
||||||
|
if (gtar --version > /dev/null 2>&1); then
|
||||||
|
gtar ${1+"$@"} && exit 0
|
||||||
|
fi
|
||||||
|
firstarg="$1"
|
||||||
|
if shift; then
|
||||||
|
case "$firstarg" in
|
||||||
|
*o*)
|
||||||
|
firstarg=`echo "$firstarg" | sed s/o//`
|
||||||
|
tar "$firstarg" ${1+"$@"} && exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case "$firstarg" in
|
||||||
|
*h*)
|
||||||
|
firstarg=`echo "$firstarg" | sed s/h//`
|
||||||
|
tar "$firstarg" ${1+"$@"} && exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: I can't seem to be able to run \`tar' with the given arguments.
|
||||||
|
You may want to install GNU tar or Free paxutils, or check the
|
||||||
|
command line arguments."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
echo 1>&2 "\
|
echo 1>&2 "\
|
||||||
WARNING: \`$1' is needed, and you do not seem to have it handy on your
|
WARNING: \`$1' is needed, and you do not seem to have it handy on your
|
||||||
|
|
|
@ -127,8 +127,7 @@ CThread::getResult() const
|
||||||
void*
|
void*
|
||||||
CThread::getUserData()
|
CThread::getUserData()
|
||||||
{
|
{
|
||||||
CThreadPtr currentRep(CThreadRep::getCurrentThreadRep());
|
return m_rep->getUserData();
|
||||||
return currentRep->getUserData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -88,15 +88,14 @@ public:
|
||||||
// return a thread object representing the calling thread
|
// return a thread object representing the calling thread
|
||||||
static CThread getCurrentThread();
|
static CThread getCurrentThread();
|
||||||
|
|
||||||
// get the user data passed to the constructor for the current
|
|
||||||
// thread.
|
|
||||||
static void* getUserData();
|
|
||||||
|
|
||||||
// testCancel() does nothing but is a cancellation point. call
|
// testCancel() does nothing but is a cancellation point. call
|
||||||
// this to make a function itself a cancellation point.
|
// this to make a function itself a cancellation point.
|
||||||
// (cancellation point)
|
// (cancellation point)
|
||||||
static void testCancel();
|
static void testCancel();
|
||||||
|
|
||||||
|
// get the user data passed to the constructor for this thread.
|
||||||
|
void* getUserData();
|
||||||
|
|
||||||
// waits for the thread to terminate (by exit() or cancel() or
|
// waits for the thread to terminate (by exit() or cancel() or
|
||||||
// by returning from the thread job). returns immediately if
|
// by returning from the thread job). returns immediately if
|
||||||
// the thread has already terminated. returns immediately with
|
// the thread has already terminated. returns immediately with
|
||||||
|
|
109
notes
109
notes
|
@ -7,16 +7,27 @@ hangup if invalid
|
||||||
query info -->
|
query info -->
|
||||||
<-- info (size)
|
<-- info (size)
|
||||||
|
|
||||||
|
---
|
||||||
|
nedit doesn't seem to be playing nice with the motif clipboard lock
|
||||||
|
it's not releasing it
|
||||||
|
may need to learn more about how the motif clipboard lock works
|
||||||
|
not sure if this a new problem with synergy or a problem with new nedit
|
||||||
|
|
||||||
---
|
---
|
||||||
enable heartbeat disconnection or remove heartbeat sending in client
|
enable heartbeat disconnection or remove heartbeat sending in client
|
||||||
should either ship with it fully enabled or fully disabled
|
should either ship with it fully enabled or fully disabled
|
||||||
possibly make it part of startup negotiation
|
possibly make it part of startup negotiation
|
||||||
|
|
||||||
---
|
---
|
||||||
sometimes jumping too far into secondary screen
|
getting a stuttering when leaving win32 server screen
|
||||||
probably bogus delta (adding in center pixel coords into delta?)
|
|
||||||
this is with an X primary and secondary
|
---
|
||||||
don't know which matters but probably X primary
|
merge platform dependent code into platform independent where possible
|
||||||
|
also try to simplify where possible
|
||||||
|
|
||||||
|
---
|
||||||
|
IServer and IPrimaryReceiver are really similar
|
||||||
|
can we merge them into one?
|
||||||
|
|
||||||
---
|
---
|
||||||
use automake
|
use automake
|
||||||
|
@ -33,20 +44,59 @@ HTTP stuff
|
||||||
handy for debugging at least
|
handy for debugging at least
|
||||||
|
|
||||||
---
|
---
|
||||||
make generic input devices?
|
negotiation:
|
||||||
replace mouse and keyboard with button and valuator devices?
|
use a generic negotiation message (name/value pair) or specific
|
||||||
could fairly easily add new devices then
|
messages (name/values)? later allows more parsing to be done by
|
||||||
valuators would have to come in groups that change together
|
CProtocolUtil but how can we skip unknown messages? would have
|
||||||
mouse position would be two ganged valuators
|
to have a method on CInputPacketStream to discard to end of
|
||||||
key events are not simply button presses though
|
message and we'd need to know the stream is a CInputPacketStream.
|
||||||
they have a non-boolean character, shift state, and repeat count
|
|
||||||
maybe another device type: {data, state, repeat}
|
|
||||||
|
|
||||||
must handle on-the-fly addition/removal of devices
|
how does negotiation proceed?
|
||||||
USB allows hotplugging and we should support, say, an added joystick
|
could have sequence of queries and replies:
|
||||||
|
server -> client -> server ... end
|
||||||
|
client -> server -> client ... end
|
||||||
|
or a sequence of messages:
|
||||||
|
server -> client ... end
|
||||||
|
client -> server ... end
|
||||||
|
probably go with latter because it's more efficient but make it
|
||||||
|
3-way:
|
||||||
|
client -> server ... end
|
||||||
|
server -> client ... end
|
||||||
|
client -> server ... end
|
||||||
|
first messages from client must be version and name. the server
|
||||||
|
can create the appropriate protocol object right away then.
|
||||||
|
|
||||||
must have device negotiation
|
example: clipboard formats:
|
||||||
at very least it negotiates mouse/keyboard at start
|
# CNEG = negotiation command CNEG%s%s
|
||||||
|
# CNGE = end of negotiation command
|
||||||
|
# cbfa = clipboard, format, add (permitted format)
|
||||||
|
# cbia = clipboard, id, add (clipboard with id exists)
|
||||||
|
client -> server: CNEG "vers" "1.0"
|
||||||
|
client -> server: CNEG "name" "foobar"
|
||||||
|
client -> server: CNGE
|
||||||
|
server -> client: CNEG "cbfa" "text/plain/LF"
|
||||||
|
server -> client: CNEG "cbfa" "image/BMP"
|
||||||
|
server -> client: CNGE
|
||||||
|
client -> server: CNEG "cbia" "0"
|
||||||
|
client -> server: CNGE
|
||||||
|
|
||||||
|
server should just ask CProtocol (renamed from CServerProtocol) to
|
||||||
|
return a protocol. CProtocol should do negotiation, create the
|
||||||
|
appropriate protocol object, finish negotiation, and return the
|
||||||
|
new protocol object. unless connection is registered with server,
|
||||||
|
though, we can't save any screen info. perhaps CProtocol should
|
||||||
|
also return a screen info object or that should be part of the
|
||||||
|
protocol object (currently the protocol is part of the screen info).
|
||||||
|
if screen info is available to CProtocol then it should finish with
|
||||||
|
requesting the screen info, waiting for and then handling the reply.
|
||||||
|
the server can then just ask CProtocol for the protocol object then
|
||||||
|
add it to the connections.
|
||||||
|
|
||||||
|
maybe call the protocol types CClientProxy since that's how the
|
||||||
|
server uses it: as a stand-in for the client object. the interface
|
||||||
|
should closely reflect the CClient interface. do the reverse for
|
||||||
|
a server proxy for the client. maybe even have interface classes
|
||||||
|
for the client and server methods.
|
||||||
|
|
||||||
---
|
---
|
||||||
should add clipboard data type format negotiation
|
should add clipboard data type format negotiation
|
||||||
|
@ -72,6 +122,28 @@ allows compatibility with versions that are identical except for
|
||||||
the support clipboard formats, obviating bumping up the protocol
|
the support clipboard formats, obviating bumping up the protocol
|
||||||
version number.
|
version number.
|
||||||
|
|
||||||
|
maybe config file can list format shared libraries to load. user
|
||||||
|
can then pick formats to support. but why would you ever want
|
||||||
|
fewer formats?
|
||||||
|
|
||||||
|
should the major burden of translation be on client or server?
|
||||||
|
probably client since it knows the formats preferred by the
|
||||||
|
platform and may be able to use platform utilities to convert.
|
||||||
|
server would then just support formats that minimize loss of
|
||||||
|
information.
|
||||||
|
|
||||||
|
desired formats to support:
|
||||||
|
text (LF)
|
||||||
|
text with character set
|
||||||
|
unicode (LF)
|
||||||
|
rich text (or some kind of formatting)
|
||||||
|
bitmap (BMP, PNG?)
|
||||||
|
sound (WAV)
|
||||||
|
|
||||||
|
note that formats should be added to the win32 clipboard in the
|
||||||
|
order of most descriptive to least because they're kept in order
|
||||||
|
and apps will generally use the first suitable match.
|
||||||
|
|
||||||
---
|
---
|
||||||
hot keys
|
hot keys
|
||||||
should have keyboard shortcuts to jump to screens
|
should have keyboard shortcuts to jump to screens
|
||||||
|
@ -130,6 +202,7 @@ xscreensaver won't start if pointer on secondary screen
|
||||||
unless using MIT or SGI screen saver extensions
|
unless using MIT or SGI screen saver extensions
|
||||||
otherwise it cannot know when to stop the screen saver
|
otherwise it cannot know when to stop the screen saver
|
||||||
cos it can't grab mouse and keyboard
|
cos it can't grab mouse and keyboard
|
||||||
|
|
||||||
---
|
---
|
||||||
all screensavers hidden when showing win32 screensaver lock window
|
all screensavers hidden when showing win32 screensaver lock window
|
||||||
win32 kills the screen saver and shows the lock window
|
win32 kills the screen saver and shows the lock window
|
||||||
|
@ -396,6 +469,10 @@ gspencer:
|
||||||
code, since if you have a key down you aren't supposed to be able to
|
code, since if you have a key down you aren't supposed to be able to
|
||||||
cross over...
|
cross over...
|
||||||
|
|
||||||
|
gspencer:
|
||||||
|
bouncy mouse at edge of screen (win32 server). almost certainly
|
||||||
|
related to changes that fixed mouse delta calculation.
|
||||||
|
|
||||||
|
|
||||||
== fixed? ===
|
== fixed? ===
|
||||||
dragging windows is too slow
|
dragging windows is too slow
|
||||||
|
|
|
@ -525,6 +525,7 @@ CXWindowsClipboard::motifLockClipboard() const
|
||||||
// fail if anybody owns the lock (even us, so this is non-recursive)
|
// fail if anybody owns the lock (even us, so this is non-recursive)
|
||||||
Window lockOwner = XGetSelectionOwner(m_display, m_atomMotifClipLock);
|
Window lockOwner = XGetSelectionOwner(m_display, m_atomMotifClipLock);
|
||||||
if (lockOwner != None) {
|
if (lockOwner != None) {
|
||||||
|
log((CLOG_DEBUG1 "motif lock owner 0x%08x", lockOwner));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,6 +537,7 @@ CXWindowsClipboard::motifLockClipboard() const
|
||||||
XSetSelectionOwner(m_display, m_atomMotifClipLock, m_window, time);
|
XSetSelectionOwner(m_display, m_atomMotifClipLock, m_window, time);
|
||||||
lockOwner = XGetSelectionOwner(m_display, m_atomMotifClipLock);
|
lockOwner = XGetSelectionOwner(m_display, m_atomMotifClipLock);
|
||||||
if (lockOwner != m_window) {
|
if (lockOwner != m_window) {
|
||||||
|
log((CLOG_DEBUG1 "motif lock owner 0x%08x", lockOwner));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
#include "CClientProxy.h"
|
||||||
|
#include "IInputStream.h"
|
||||||
|
#include "IOutputStream.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// CClientProxy
|
||||||
|
//
|
||||||
|
|
||||||
|
CClientProxy::CClientProxy(IServer* server, const CString& name,
|
||||||
|
IInputStream* input, IOutputStream* output) :
|
||||||
|
m_server(server),
|
||||||
|
m_name(name),
|
||||||
|
m_input(input),
|
||||||
|
m_output(output)
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
CClientProxy::~CClientProxy()
|
||||||
|
{
|
||||||
|
delete m_output;
|
||||||
|
delete m_input;
|
||||||
|
}
|
||||||
|
|
||||||
|
IServer*
|
||||||
|
CClientProxy::getServer() const
|
||||||
|
{
|
||||||
|
return m_server;
|
||||||
|
}
|
||||||
|
|
||||||
|
IInputStream*
|
||||||
|
CClientProxy::getInputStream() const
|
||||||
|
{
|
||||||
|
return m_input;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOutputStream*
|
||||||
|
CClientProxy::getOutputStream() const
|
||||||
|
{
|
||||||
|
return m_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
CString
|
||||||
|
CClientProxy::getName() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
#ifndef CCLIENTPROXY_H
|
||||||
|
#define CCLIENTPROXY_H
|
||||||
|
|
||||||
|
#include "IClient.h"
|
||||||
|
#include "CString.h"
|
||||||
|
|
||||||
|
class IInputStream;
|
||||||
|
class IOutputStream;
|
||||||
|
class IServer;
|
||||||
|
|
||||||
|
class CClientProxy : public IClient {
|
||||||
|
public:
|
||||||
|
CClientProxy(IServer* server, const CString& name,
|
||||||
|
IInputStream* adoptedInput,
|
||||||
|
IOutputStream* adoptedOutput);
|
||||||
|
~CClientProxy();
|
||||||
|
|
||||||
|
// manipulators
|
||||||
|
|
||||||
|
// accessors
|
||||||
|
|
||||||
|
// get the server
|
||||||
|
IServer* getServer() const;
|
||||||
|
|
||||||
|
// get the input and output streams for the client
|
||||||
|
IInputStream* getInputStream() const;
|
||||||
|
IOutputStream* getOutputStream() const;
|
||||||
|
|
||||||
|
// IClient overrides
|
||||||
|
virtual void open() = 0;
|
||||||
|
virtual void run() = 0;
|
||||||
|
virtual void close() = 0;
|
||||||
|
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
||||||
|
UInt32 seqNum, KeyModifierMask mask,
|
||||||
|
bool screenSaver) = 0;
|
||||||
|
virtual bool leave() = 0;
|
||||||
|
virtual void setClipboard(ClipboardID, const CString&) = 0;
|
||||||
|
virtual void grabClipboard(ClipboardID) = 0;
|
||||||
|
virtual void setClipboardDirty(ClipboardID, bool) = 0;
|
||||||
|
virtual void keyDown(KeyID, KeyModifierMask) = 0;
|
||||||
|
virtual void keyRepeat(KeyID, KeyModifierMask, SInt32 count) = 0;
|
||||||
|
virtual void keyUp(KeyID, KeyModifierMask) = 0;
|
||||||
|
virtual void mouseDown(ButtonID) = 0;
|
||||||
|
virtual void mouseUp(ButtonID) = 0;
|
||||||
|
virtual void mouseMove(SInt32 xAbs, SInt32 yAbs) = 0;
|
||||||
|
virtual void mouseWheel(SInt32 delta) = 0;
|
||||||
|
virtual void screenSaver(bool activate) = 0;
|
||||||
|
virtual CString getName() const;
|
||||||
|
virtual void getShape(SInt32& x, SInt32& y,
|
||||||
|
SInt32& width, SInt32& height) const = 0;
|
||||||
|
virtual void getCenter(SInt32& x, SInt32& y) const = 0;
|
||||||
|
virtual SInt32 getJumpZoneSize() const = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
IServer* m_server;
|
||||||
|
CString m_name;
|
||||||
|
IInputStream* m_input;
|
||||||
|
IOutputStream* m_output;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,337 @@
|
||||||
|
#include "CClientProxy1_0.h"
|
||||||
|
#include "CServer.h"
|
||||||
|
#include "CClipboard.h"
|
||||||
|
#include "CProtocolUtil.h"
|
||||||
|
#include "ProtocolTypes.h"
|
||||||
|
#include "XSynergy.h"
|
||||||
|
#include "IInputStream.h"
|
||||||
|
#include "IOutputStream.h"
|
||||||
|
#include "CLock.h"
|
||||||
|
#include "CThread.h"
|
||||||
|
#include "CLog.h"
|
||||||
|
#include "CStopwatch.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
//
|
||||||
|
// CClientProxy1_0
|
||||||
|
//
|
||||||
|
|
||||||
|
CClientProxy1_0::CClientProxy1_0(IServer* server, const CString& name,
|
||||||
|
IInputStream* input, IOutputStream* output) :
|
||||||
|
CClientProxy(server, name, input, output)
|
||||||
|
{
|
||||||
|
for (UInt32 i = 0; i < kClipboardEnd; ++i) {
|
||||||
|
m_clipboardDirty[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CClientProxy1_0::~CClientProxy1_0()
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::open()
|
||||||
|
{
|
||||||
|
// send request
|
||||||
|
log((CLOG_DEBUG1 "querying client \"%s\" info", getName().c_str()));
|
||||||
|
CProtocolUtil::writef(getOutputStream(), kMsgQInfo);
|
||||||
|
getOutputStream()->flush();
|
||||||
|
|
||||||
|
// wait for and verify reply
|
||||||
|
UInt8 code[4];
|
||||||
|
for (;;) {
|
||||||
|
UInt32 n = getInputStream()->read(code, 4, -1.0);
|
||||||
|
if (n == 4) {
|
||||||
|
if (memcmp(code, kMsgCNoop, 4) == 0) {
|
||||||
|
// discard heartbeats
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (memcmp(code, kMsgDInfo, 4) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw XBadClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle reply
|
||||||
|
recvInfo(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::run()
|
||||||
|
{
|
||||||
|
// handle messages until the client hangs up or stops sending heartbeats
|
||||||
|
CStopwatch heartTimer;
|
||||||
|
for (;;) {
|
||||||
|
CThread::testCancel();
|
||||||
|
|
||||||
|
// wait for a message
|
||||||
|
UInt8 code[4];
|
||||||
|
UInt32 n = getInputStream()->read(code, 4, kHeartRate);
|
||||||
|
CThread::testCancel();
|
||||||
|
|
||||||
|
// check if client hungup
|
||||||
|
if (n == 0) {
|
||||||
|
log((CLOG_NOTE "client \"%s\" disconnected", getName().c_str()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if client has stopped sending heartbeats
|
||||||
|
if (n == (UInt32)-1) {
|
||||||
|
/* FIXME -- disabled to avoid masking bugs
|
||||||
|
if (heartTimer.getTime() > kHeartDeath) {
|
||||||
|
log((CLOG_NOTE "client \"%s\" is dead", getName().c_str()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// got a message so reset heartbeat monitor
|
||||||
|
heartTimer.reset();
|
||||||
|
|
||||||
|
// verify we got an entire code
|
||||||
|
if (n != 4) {
|
||||||
|
log((CLOG_ERR "incomplete message from \"%s\": %d bytes", getName().c_str(), n));
|
||||||
|
|
||||||
|
// client sent an incomplete message
|
||||||
|
throw XBadClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse message
|
||||||
|
log((CLOG_DEBUG2 "msg from \"%s\": %c%c%c%c", getName().c_str(), code[0], code[1], code[2], code[3]));
|
||||||
|
if (memcmp(code, kMsgDInfo, 4) == 0) {
|
||||||
|
recvInfo(true);
|
||||||
|
}
|
||||||
|
else if (memcmp(code, kMsgCNoop, 4) == 0) {
|
||||||
|
// discard no-ops
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (memcmp(code, kMsgCClipboard, 4) == 0) {
|
||||||
|
recvGrabClipboard();
|
||||||
|
}
|
||||||
|
else if (memcmp(code, kMsgDClipboard, 4) == 0) {
|
||||||
|
recvClipboard();
|
||||||
|
}
|
||||||
|
// note -- more message handlers go here
|
||||||
|
else {
|
||||||
|
log((CLOG_ERR "invalid message from client \"%s\"", getName().c_str()));
|
||||||
|
|
||||||
|
// unknown message
|
||||||
|
throw XBadClient();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::close()
|
||||||
|
{
|
||||||
|
log((CLOG_DEBUG1 "send close to \"%s\"", getName().c_str()));
|
||||||
|
CProtocolUtil::writef(getOutputStream(), kMsgCClose);
|
||||||
|
|
||||||
|
// force the close to be sent before we return
|
||||||
|
getOutputStream()->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::enter(SInt32 xAbs, SInt32 yAbs,
|
||||||
|
UInt32 seqNum, KeyModifierMask mask, bool)
|
||||||
|
{
|
||||||
|
log((CLOG_DEBUG1 "send enter to \"%s\", %d,%d %d %04x", getName().c_str(), xAbs, yAbs, seqNum, mask));
|
||||||
|
CProtocolUtil::writef(getOutputStream(), kMsgCEnter,
|
||||||
|
xAbs, yAbs, seqNum, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CClientProxy1_0::leave()
|
||||||
|
{
|
||||||
|
log((CLOG_DEBUG1 "send leave to \"%s\"", getName().c_str()));
|
||||||
|
CProtocolUtil::writef(getOutputStream(), kMsgCLeave);
|
||||||
|
|
||||||
|
// we can never prevent the user from leaving
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::setClipboard(ClipboardID id, const CString& data)
|
||||||
|
{
|
||||||
|
// ignore if this clipboard is already clean
|
||||||
|
CLock lock(&m_mutex);
|
||||||
|
if (m_clipboardDirty[id]) {
|
||||||
|
// this clipboard is now clean
|
||||||
|
m_clipboardDirty[id] = false;
|
||||||
|
|
||||||
|
log((CLOG_DEBUG "send clipboard %d to \"%s\" size=%d", id, getName().c_str(), data.size()));
|
||||||
|
CProtocolUtil::writef(getOutputStream(), kMsgDClipboard, id, 0, &data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::grabClipboard(ClipboardID id)
|
||||||
|
{
|
||||||
|
log((CLOG_DEBUG "send grab clipboard %d to \"%s\"", id, getName().c_str()));
|
||||||
|
CProtocolUtil::writef(getOutputStream(), kMsgCClipboard, id, 0);
|
||||||
|
|
||||||
|
// this clipboard is now dirty
|
||||||
|
CLock lock(&m_mutex);
|
||||||
|
m_clipboardDirty[id] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::setClipboardDirty(ClipboardID id, bool dirty)
|
||||||
|
{
|
||||||
|
CLock lock(&m_mutex);
|
||||||
|
m_clipboardDirty[id] = dirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::keyDown(KeyID key, KeyModifierMask mask)
|
||||||
|
{
|
||||||
|
log((CLOG_DEBUG1 "send key down to \"%s\" id=%d, mask=0x%04x", getName().c_str(), key, mask));
|
||||||
|
CProtocolUtil::writef(getOutputStream(), kMsgDKeyDown, key, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::keyRepeat(KeyID key, KeyModifierMask mask, SInt32 count)
|
||||||
|
{
|
||||||
|
log((CLOG_DEBUG1 "send key repeat to \"%s\" id=%d, mask=0x%04x, count=%d", getName().c_str(), key, mask, count));
|
||||||
|
CProtocolUtil::writef(getOutputStream(), kMsgDKeyRepeat, key, mask, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::keyUp(KeyID key, KeyModifierMask mask)
|
||||||
|
{
|
||||||
|
log((CLOG_DEBUG1 "send key up to \"%s\" id=%d, mask=0x%04x", getName().c_str(), key, mask));
|
||||||
|
CProtocolUtil::writef(getOutputStream(), kMsgDKeyUp, key, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::mouseDown(ButtonID button)
|
||||||
|
{
|
||||||
|
log((CLOG_DEBUG1 "send mouse down to \"%s\" id=%d", getName().c_str(), button));
|
||||||
|
CProtocolUtil::writef(getOutputStream(), kMsgDMouseDown, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::mouseUp(ButtonID button)
|
||||||
|
{
|
||||||
|
log((CLOG_DEBUG1 "send mouse up to \"%s\" id=%d", getName().c_str(), button));
|
||||||
|
CProtocolUtil::writef(getOutputStream(), kMsgDMouseUp, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::mouseMove(SInt32 xAbs, SInt32 yAbs)
|
||||||
|
{
|
||||||
|
log((CLOG_DEBUG2 "send mouse move to \"%s\" %d,%d", getName().c_str(), xAbs, yAbs));
|
||||||
|
CProtocolUtil::writef(getOutputStream(), kMsgDMouseMove, xAbs, yAbs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::mouseWheel(SInt32 delta)
|
||||||
|
{
|
||||||
|
log((CLOG_DEBUG2 "send mouse wheel to \"%s\" %+d", getName().c_str(), delta));
|
||||||
|
CProtocolUtil::writef(getOutputStream(), kMsgDMouseWheel, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::screenSaver(bool on)
|
||||||
|
{
|
||||||
|
log((CLOG_DEBUG1 "send screen saver to \"%s\" on=%d", getName().c_str(), on ? 1 : 0));
|
||||||
|
CProtocolUtil::writef(getOutputStream(), kMsgCScreenSaver, on ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::getShape(SInt32& x, SInt32& y, SInt32& w, SInt32& h) const
|
||||||
|
{
|
||||||
|
CLock lock(&m_mutex);
|
||||||
|
x = m_x;
|
||||||
|
y = m_y;
|
||||||
|
w = m_w;
|
||||||
|
h = m_h;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::getCenter(SInt32& x, SInt32& y) const
|
||||||
|
{
|
||||||
|
CLock lock(&m_mutex);
|
||||||
|
x = m_cx;
|
||||||
|
y = m_cy;
|
||||||
|
}
|
||||||
|
|
||||||
|
SInt32
|
||||||
|
CClientProxy1_0::getJumpZoneSize() const
|
||||||
|
{
|
||||||
|
CLock lock(&m_mutex);
|
||||||
|
return m_zoneSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::recvInfo(bool notify)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
CLock lock(&m_mutex);
|
||||||
|
|
||||||
|
// parse the message
|
||||||
|
CProtocolUtil::readf(getInputStream(), kMsgDInfo + 4,
|
||||||
|
&m_x, &m_y, &m_w, &m_h,
|
||||||
|
&m_zoneSize, &m_cx, &m_cy);
|
||||||
|
log((CLOG_DEBUG "received client \"%s\" info shape=%d,%d %dx%d, zone=%d, pos=%d,%d", getName().c_str(), m_x, m_y, m_w, m_h, m_zoneSize, m_cx, m_cy));
|
||||||
|
|
||||||
|
// validate
|
||||||
|
if (m_w <= 0 || m_h <= 0 || m_zoneSize < 0) {
|
||||||
|
throw XBadClient();
|
||||||
|
}
|
||||||
|
if (m_cx < m_x || m_cy < m_y || m_cx >= m_x + m_w || m_cy >= m_y + m_h) {
|
||||||
|
throw XBadClient();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// tell server of change
|
||||||
|
if (notify) {
|
||||||
|
getServer()->onInfoChanged(getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// acknowledge receipt
|
||||||
|
log((CLOG_DEBUG1 "send info ack to \"%s\"", getName().c_str()));
|
||||||
|
CProtocolUtil::writef(getOutputStream(), kMsgCInfoAck);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::recvClipboard()
|
||||||
|
{
|
||||||
|
// parse message
|
||||||
|
ClipboardID id;
|
||||||
|
UInt32 seqNum;
|
||||||
|
CString data;
|
||||||
|
CProtocolUtil::readf(getInputStream(), kMsgDClipboard + 4, &id, &seqNum, &data);
|
||||||
|
log((CLOG_DEBUG "received client \"%s\" clipboard %d seqnum=%d, size=%d", getName().c_str(), id, seqNum, data.size()));
|
||||||
|
|
||||||
|
// validate
|
||||||
|
if (id >= kClipboardEnd) {
|
||||||
|
throw XBadClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
// send update. this calls us back to reset our clipboard dirty flag
|
||||||
|
// so don't hold a lock during the call.
|
||||||
|
getServer()->onClipboardChanged(id, seqNum, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CClientProxy1_0::recvGrabClipboard()
|
||||||
|
{
|
||||||
|
// parse message
|
||||||
|
ClipboardID id;
|
||||||
|
UInt32 seqNum;
|
||||||
|
CProtocolUtil::readf(getInputStream(), kMsgCClipboard + 4, &id, &seqNum);
|
||||||
|
log((CLOG_DEBUG "received client \"%s\" grabbed clipboard %d seqnum=%d", getName().c_str(), id, seqNum));
|
||||||
|
|
||||||
|
// validate
|
||||||
|
if (id >= kClipboardEnd) {
|
||||||
|
throw XBadClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
// send update. this calls us back to reset our clipboard dirty flag
|
||||||
|
// so don't hold a lock during the call.
|
||||||
|
getServer()->onGrabClipboard(id, seqNum, getName());
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
#ifndef CCLIENTPROXY1_0_H
|
||||||
|
#define CCLIENTPROXY1_0_H
|
||||||
|
|
||||||
|
#include "CClientProxy.h"
|
||||||
|
#include "CMutex.h"
|
||||||
|
|
||||||
|
class CClientProxy1_0 : public CClientProxy {
|
||||||
|
public:
|
||||||
|
CClientProxy1_0(IServer* server, const CString& name,
|
||||||
|
IInputStream* adoptedInput,
|
||||||
|
IOutputStream* adoptedOutput);
|
||||||
|
~CClientProxy1_0();
|
||||||
|
|
||||||
|
// IClient overrides
|
||||||
|
virtual void open();
|
||||||
|
virtual void run();
|
||||||
|
virtual void close();
|
||||||
|
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
||||||
|
UInt32 seqNum, KeyModifierMask mask,
|
||||||
|
bool screenSaver);
|
||||||
|
virtual bool leave();
|
||||||
|
virtual void setClipboard(ClipboardID, const CString&);
|
||||||
|
virtual void grabClipboard(ClipboardID);
|
||||||
|
virtual void setClipboardDirty(ClipboardID, bool);
|
||||||
|
virtual void keyDown(KeyID, KeyModifierMask);
|
||||||
|
virtual void keyRepeat(KeyID, KeyModifierMask, SInt32 count);
|
||||||
|
virtual void keyUp(KeyID, KeyModifierMask);
|
||||||
|
virtual void mouseDown(ButtonID);
|
||||||
|
virtual void mouseUp(ButtonID);
|
||||||
|
virtual void mouseMove(SInt32 xAbs, SInt32 yAbs);
|
||||||
|
virtual void mouseWheel(SInt32 delta);
|
||||||
|
virtual void screenSaver(bool activate);
|
||||||
|
virtual void getShape(SInt32& x, SInt32& y,
|
||||||
|
SInt32& width, SInt32& height) const;
|
||||||
|
virtual void getCenter(SInt32& x, SInt32& y) const;
|
||||||
|
virtual SInt32 getJumpZoneSize() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void recvInfo(bool notify);
|
||||||
|
void recvClipboard();
|
||||||
|
void recvGrabClipboard();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CMutex m_mutex;
|
||||||
|
SInt16 m_x, m_y;
|
||||||
|
SInt16 m_w, m_h;
|
||||||
|
SInt16 m_zoneSize;
|
||||||
|
SInt16 m_cx, m_cy;
|
||||||
|
bool m_clipboardDirty[kClipboardEnd];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,308 @@
|
||||||
|
#include "CPrimaryClient.h"
|
||||||
|
#include "IServer.h"
|
||||||
|
#include "IPrimaryScreen.h"
|
||||||
|
#include "CClipboard.h"
|
||||||
|
#include "CLog.h"
|
||||||
|
|
||||||
|
// FIXME -- use factory to create screen
|
||||||
|
#if WINDOWS_LIKE
|
||||||
|
#include "CMSWindowsPrimaryScreen.h"
|
||||||
|
#elif UNIX_LIKE
|
||||||
|
#include "CXWindowsPrimaryScreen.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// CPrimaryClient
|
||||||
|
//
|
||||||
|
|
||||||
|
CPrimaryClient::CPrimaryClient(IServer* server, const CString& name) :
|
||||||
|
m_server(server),
|
||||||
|
m_name(name),
|
||||||
|
m_seqNum(0)
|
||||||
|
{
|
||||||
|
assert(m_server != NULL);
|
||||||
|
|
||||||
|
// create screen
|
||||||
|
log((CLOG_DEBUG1 "creating primary screen"));
|
||||||
|
#if WINDOWS_LIKE
|
||||||
|
m_screen = new CMSWindowsPrimaryScreen(this);
|
||||||
|
#elif UNIX_LIKE
|
||||||
|
m_screen = new CXWindowsPrimaryScreen(this);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CPrimaryClient::~CPrimaryClient()
|
||||||
|
{
|
||||||
|
delete m_screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::stop()
|
||||||
|
{
|
||||||
|
m_screen->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::reconfigure()
|
||||||
|
{
|
||||||
|
m_screen->reconfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::getClipboard(ClipboardID id, CString& data) const
|
||||||
|
{
|
||||||
|
CClipboard clipboard;
|
||||||
|
m_screen->getClipboard(id, &clipboard);
|
||||||
|
data = clipboard.marshall();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CPrimaryClient::isLockedToScreen() const
|
||||||
|
{
|
||||||
|
return m_screen->isLockedToScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyModifierMask
|
||||||
|
CPrimaryClient::getToggleMask() const
|
||||||
|
{
|
||||||
|
return m_screen->getToggleMask();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::onError()
|
||||||
|
{
|
||||||
|
m_server->onError();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::onInfoChanged(SInt32 x, SInt32 y, SInt32 w, SInt32 h,
|
||||||
|
SInt32 zoneSize, SInt32 cx, SInt32 cy)
|
||||||
|
{
|
||||||
|
m_x = x;
|
||||||
|
m_y = y;
|
||||||
|
m_w = w;
|
||||||
|
m_h = h;
|
||||||
|
m_zoneSize = zoneSize;
|
||||||
|
m_cx = cx;
|
||||||
|
m_cy = cy;
|
||||||
|
m_server->onInfoChanged(getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CPrimaryClient::onGrabClipboard(ClipboardID id)
|
||||||
|
{
|
||||||
|
m_clipboardOwner[id] = m_server->onGrabClipboard(id, m_seqNum, getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CPrimaryClient::onClipboardChanged(ClipboardID id, const CString& data)
|
||||||
|
{
|
||||||
|
m_server->onClipboardChanged(id, m_seqNum, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::onKeyDown(KeyID id, KeyModifierMask mask)
|
||||||
|
{
|
||||||
|
m_server->onKeyDown(id, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::onKeyUp(KeyID id, KeyModifierMask mask)
|
||||||
|
{
|
||||||
|
m_server->onKeyUp(id, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::onKeyRepeat(KeyID id, KeyModifierMask mask, SInt32 count)
|
||||||
|
{
|
||||||
|
m_server->onKeyRepeat(id, mask, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::onMouseDown(ButtonID id)
|
||||||
|
{
|
||||||
|
m_server->onMouseDown(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::onMouseUp(ButtonID id)
|
||||||
|
{
|
||||||
|
m_server->onMouseUp(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CPrimaryClient::onMouseMovePrimary(SInt32 x, SInt32 y)
|
||||||
|
{
|
||||||
|
return m_server->onMouseMovePrimary(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::onMouseMoveSecondary(SInt32 dx, SInt32 dy)
|
||||||
|
{
|
||||||
|
m_server->onMouseMoveSecondary(dx, dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::onMouseWheel(SInt32 delta)
|
||||||
|
{
|
||||||
|
m_server->onMouseWheel(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::onScreenSaver(bool activated)
|
||||||
|
{
|
||||||
|
m_server->onScreenSaver(activated);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::open()
|
||||||
|
{
|
||||||
|
// all clipboards are clean and owned by us
|
||||||
|
for (UInt32 i = 0; i < kClipboardEnd; ++i) {
|
||||||
|
m_clipboardOwner[i] = true;
|
||||||
|
m_clipboardDirty[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now open the screen
|
||||||
|
m_screen->open();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::run()
|
||||||
|
{
|
||||||
|
m_screen->run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::close()
|
||||||
|
{
|
||||||
|
m_screen->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::enter(SInt32 xAbs, SInt32 yAbs,
|
||||||
|
UInt32 seqNum, KeyModifierMask, bool screensaver)
|
||||||
|
{
|
||||||
|
// note -- we must not call any server methods except onError().
|
||||||
|
m_seqNum = seqNum;
|
||||||
|
m_screen->enter(xAbs, yAbs, screensaver);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CPrimaryClient::leave()
|
||||||
|
{
|
||||||
|
// note -- we must not call any server methods except onError().
|
||||||
|
return m_screen->leave();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::setClipboard(ClipboardID id, const CString& data)
|
||||||
|
{
|
||||||
|
// note -- we must not call any server methods except onError().
|
||||||
|
|
||||||
|
// ignore if this clipboard is already clean
|
||||||
|
if (m_clipboardDirty[id]) {
|
||||||
|
// this clipboard is now clean
|
||||||
|
m_clipboardDirty[id] = false;
|
||||||
|
|
||||||
|
// unmarshall data
|
||||||
|
CClipboard clipboard;
|
||||||
|
clipboard.unmarshall(data, 0);
|
||||||
|
|
||||||
|
// set clipboard
|
||||||
|
m_screen->setClipboard(id, &clipboard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::grabClipboard(ClipboardID id)
|
||||||
|
{
|
||||||
|
// grab clipboard
|
||||||
|
m_screen->grabClipboard(id);
|
||||||
|
|
||||||
|
// clipboard is dirty (because someone else owns it now)
|
||||||
|
m_clipboardOwner[id] = false;
|
||||||
|
m_clipboardDirty[id] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::setClipboardDirty(ClipboardID id, bool dirty)
|
||||||
|
{
|
||||||
|
m_clipboardDirty[id] = dirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::keyDown(KeyID, KeyModifierMask)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::keyRepeat(KeyID, KeyModifierMask, SInt32)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::keyUp(KeyID, KeyModifierMask)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::mouseDown(ButtonID)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::mouseUp(ButtonID)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::mouseMove(SInt32 x, SInt32 y)
|
||||||
|
{
|
||||||
|
m_screen->warpCursor(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::mouseWheel(SInt32)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::screenSaver(bool)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
CString
|
||||||
|
CPrimaryClient::getName() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::getShape(SInt32& x, SInt32& y, SInt32& w, SInt32& h) const
|
||||||
|
{
|
||||||
|
x = m_x;
|
||||||
|
y = m_y;
|
||||||
|
w = m_w;
|
||||||
|
h = m_h;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPrimaryClient::getCenter(SInt32& x, SInt32& y) const
|
||||||
|
{
|
||||||
|
x = m_cx;
|
||||||
|
y = m_cy;
|
||||||
|
}
|
||||||
|
|
||||||
|
SInt32
|
||||||
|
CPrimaryClient::getJumpZoneSize() const
|
||||||
|
{
|
||||||
|
return m_zoneSize;
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
#ifndef CPRIMARYCLIENT_H
|
||||||
|
#define CPRIMARYCLIENT_H
|
||||||
|
|
||||||
|
#include "IPrimaryReceiver.h"
|
||||||
|
#include "IClient.h"
|
||||||
|
|
||||||
|
class IClipboard;
|
||||||
|
class IPrimaryScreen;
|
||||||
|
class IServer;
|
||||||
|
|
||||||
|
class CPrimaryClient : public IPrimaryReceiver, public IClient {
|
||||||
|
public:
|
||||||
|
CPrimaryClient(IServer*, const CString& name);
|
||||||
|
~CPrimaryClient();
|
||||||
|
|
||||||
|
// manipulators
|
||||||
|
|
||||||
|
// cause run() to return
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
// called by server when the configuration changes
|
||||||
|
void reconfigure();
|
||||||
|
|
||||||
|
// accessors
|
||||||
|
|
||||||
|
// return the contents of the given clipboard.
|
||||||
|
void getClipboard(ClipboardID, CString&) const;
|
||||||
|
|
||||||
|
// returns true iff the user is locked to the primary screen
|
||||||
|
bool isLockedToScreen() const;
|
||||||
|
|
||||||
|
// returns the state of the toggle keys on the primary screen
|
||||||
|
KeyModifierMask getToggleMask() const;
|
||||||
|
|
||||||
|
// IPrimaryReceiver overrides
|
||||||
|
virtual void onError();
|
||||||
|
virtual void onInfoChanged(SInt32 xScreen, SInt32 yScreen,
|
||||||
|
SInt32 wScreen, SInt32 hScreen,
|
||||||
|
SInt32 zoneSize,
|
||||||
|
SInt32 xMouse, SInt32 yMouse);
|
||||||
|
virtual bool onGrabClipboard(ClipboardID);
|
||||||
|
virtual bool onClipboardChanged(ClipboardID, const CString& data);
|
||||||
|
virtual void onKeyDown(KeyID, KeyModifierMask);
|
||||||
|
virtual void onKeyUp(KeyID, KeyModifierMask);
|
||||||
|
virtual void onKeyRepeat(KeyID, KeyModifierMask, SInt32 count);
|
||||||
|
virtual void onMouseDown(ButtonID);
|
||||||
|
virtual void onMouseUp(ButtonID);
|
||||||
|
virtual bool onMouseMovePrimary(SInt32 x, SInt32 y);
|
||||||
|
virtual void onMouseMoveSecondary(SInt32 dx, SInt32 dy);
|
||||||
|
virtual void onMouseWheel(SInt32 delta);
|
||||||
|
virtual void onScreenSaver(bool activated);
|
||||||
|
|
||||||
|
// IClient overrides
|
||||||
|
virtual void open();
|
||||||
|
virtual void run();
|
||||||
|
virtual void close();
|
||||||
|
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
||||||
|
UInt32 seqNum, KeyModifierMask mask,
|
||||||
|
bool screenSaver);
|
||||||
|
virtual bool leave();
|
||||||
|
virtual void setClipboard(ClipboardID, const CString&);
|
||||||
|
virtual void grabClipboard(ClipboardID);
|
||||||
|
virtual void setClipboardDirty(ClipboardID, bool);
|
||||||
|
virtual void keyDown(KeyID, KeyModifierMask);
|
||||||
|
virtual void keyRepeat(KeyID, KeyModifierMask, SInt32 count);
|
||||||
|
virtual void keyUp(KeyID, KeyModifierMask);
|
||||||
|
virtual void mouseDown(ButtonID);
|
||||||
|
virtual void mouseUp(ButtonID);
|
||||||
|
virtual void mouseMove(SInt32 xAbs, SInt32 yAbs);
|
||||||
|
virtual void mouseWheel(SInt32 delta);
|
||||||
|
virtual void screenSaver(bool activate);
|
||||||
|
virtual CString getName() const;
|
||||||
|
virtual void getShape(SInt32& x, SInt32& y,
|
||||||
|
SInt32& width, SInt32& height) const;
|
||||||
|
virtual void getCenter(SInt32& x, SInt32& y) const;
|
||||||
|
virtual SInt32 getJumpZoneSize() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
IServer* m_server;
|
||||||
|
IPrimaryScreen* m_screen;
|
||||||
|
CString m_name;
|
||||||
|
UInt32 m_seqNum;
|
||||||
|
SInt16 m_x, m_y;
|
||||||
|
SInt16 m_w, m_h;
|
||||||
|
SInt16 m_zoneSize;
|
||||||
|
SInt16 m_cx, m_cy;
|
||||||
|
bool m_clipboardOwner[kClipboardEnd];
|
||||||
|
bool m_clipboardDirty[kClipboardEnd];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
1270
server/CServer.cpp
1270
server/CServer.cpp
File diff suppressed because it is too large
Load Diff
149
server/CServer.h
149
server/CServer.h
|
@ -1,6 +1,7 @@
|
||||||
#ifndef CSERVER_H
|
#ifndef CSERVER_H
|
||||||
#define CSERVER_H
|
#define CSERVER_H
|
||||||
|
|
||||||
|
#include "IServer.h"
|
||||||
#include "CConfig.h"
|
#include "CConfig.h"
|
||||||
#include "CClipboard.h"
|
#include "CClipboard.h"
|
||||||
#include "ClipboardTypes.h"
|
#include "ClipboardTypes.h"
|
||||||
|
@ -13,14 +14,17 @@
|
||||||
#include "stdlist.h"
|
#include "stdlist.h"
|
||||||
#include "stdmap.h"
|
#include "stdmap.h"
|
||||||
|
|
||||||
|
class CClientProxy;
|
||||||
|
class CHTTPServer;
|
||||||
|
class CPrimaryClient;
|
||||||
class CThread;
|
class CThread;
|
||||||
|
class IClient;
|
||||||
|
class IDataSocket;
|
||||||
class IServerProtocol;
|
class IServerProtocol;
|
||||||
class ISocketFactory;
|
class ISocketFactory;
|
||||||
class ISecurityFactory;
|
class ISecurityFactory;
|
||||||
class IPrimaryScreen;
|
|
||||||
class CHTTPServer;
|
|
||||||
|
|
||||||
class CServer {
|
class CServer : public IServer {
|
||||||
public:
|
public:
|
||||||
CServer(const CString& serverName);
|
CServer(const CString& serverName);
|
||||||
~CServer();
|
~CServer();
|
||||||
|
@ -38,50 +42,12 @@ public:
|
||||||
// after a successful open().
|
// after a successful open().
|
||||||
void quit();
|
void quit();
|
||||||
|
|
||||||
// tell the server to shutdown. this is called in an emergency
|
|
||||||
// when we need to tell the server that we cannot continue. the
|
|
||||||
// server will attempt to clean up.
|
|
||||||
void shutdown();
|
|
||||||
|
|
||||||
// update screen map. returns true iff the new configuration was
|
// update screen map. returns true iff the new configuration was
|
||||||
// accepted.
|
// accepted.
|
||||||
bool setConfig(const CConfig&);
|
bool setConfig(const CConfig&);
|
||||||
|
|
||||||
// handle events on server's screen. onMouseMovePrimary() returns
|
|
||||||
// true iff the mouse enters a jump zone and jumps.
|
|
||||||
void onKeyDown(KeyID, KeyModifierMask);
|
|
||||||
void onKeyUp(KeyID, KeyModifierMask);
|
|
||||||
void onKeyRepeat(KeyID, KeyModifierMask, SInt32 count);
|
|
||||||
void onMouseDown(ButtonID);
|
|
||||||
void onMouseUp(ButtonID);
|
|
||||||
bool onMouseMovePrimary(SInt32 x, SInt32 y);
|
|
||||||
void onMouseMoveSecondary(SInt32 dx, SInt32 dy);
|
|
||||||
void onMouseWheel(SInt32 delta);
|
|
||||||
void grabClipboard(ClipboardID);
|
|
||||||
void onScreenSaver(bool activated);
|
|
||||||
|
|
||||||
// handle updates from primary
|
|
||||||
void setInfo(SInt32 xScreen, SInt32 yScreen,
|
|
||||||
SInt32 wScreen, SInt32 hScreen,
|
|
||||||
SInt32 zoneSize,
|
|
||||||
SInt32 xMouse, SInt32 yMouse);
|
|
||||||
|
|
||||||
// handle messages from clients
|
|
||||||
void setInfo(const CString& clientName,
|
|
||||||
SInt32 xScreen, SInt32 yScreen,
|
|
||||||
SInt32 wScreen, SInt32 hScreen,
|
|
||||||
SInt32 zoneSize,
|
|
||||||
SInt32 xMouse, SInt32 yMouse);
|
|
||||||
void grabClipboard(ClipboardID,
|
|
||||||
UInt32 seqNum, const CString& clientName);
|
|
||||||
void setClipboard(ClipboardID,
|
|
||||||
UInt32 seqNum, const CString& data);
|
|
||||||
|
|
||||||
// accessors
|
// accessors
|
||||||
|
|
||||||
// returns true if the mouse should be locked to the current screen
|
|
||||||
bool isLockedToScreen() const;
|
|
||||||
|
|
||||||
// get the current screen map
|
// get the current screen map
|
||||||
void getConfig(CConfig*) const;
|
void getConfig(CConfig*) const;
|
||||||
|
|
||||||
|
@ -91,64 +57,58 @@ public:
|
||||||
// get the sides of the primary screen that have neighbors
|
// get the sides of the primary screen that have neighbors
|
||||||
UInt32 getActivePrimarySides() const;
|
UInt32 getActivePrimarySides() const;
|
||||||
|
|
||||||
|
// IServer overrides
|
||||||
|
virtual void onError();
|
||||||
|
virtual void onInfoChanged(const CString& clientName);
|
||||||
|
virtual bool onGrabClipboard(ClipboardID,
|
||||||
|
UInt32 seqNum, const CString& clientName);
|
||||||
|
virtual void onClipboardChanged(ClipboardID,
|
||||||
|
UInt32 seqNum, const CString& data);
|
||||||
|
virtual void onKeyDown(KeyID, KeyModifierMask);
|
||||||
|
virtual void onKeyUp(KeyID, KeyModifierMask);
|
||||||
|
virtual void onKeyRepeat(KeyID, KeyModifierMask, SInt32 count);
|
||||||
|
virtual void onMouseDown(ButtonID);
|
||||||
|
virtual void onMouseUp(ButtonID);
|
||||||
|
virtual bool onMouseMovePrimary(SInt32 x, SInt32 y);
|
||||||
|
virtual void onMouseMoveSecondary(SInt32 dx, SInt32 dy);
|
||||||
|
virtual void onMouseWheel(SInt32 delta);
|
||||||
|
virtual void onGrabClipboard(ClipboardID);
|
||||||
|
virtual void onScreenSaver(bool activated);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool onCommandKey(KeyID, KeyModifierMask, bool down);
|
bool onCommandKey(KeyID, KeyModifierMask, bool down);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::list<CThread*> CThreadList;
|
typedef std::list<CThread> CThreadList;
|
||||||
|
|
||||||
class CScreenInfo {
|
|
||||||
public:
|
|
||||||
CScreenInfo(const CString& name, IServerProtocol*);
|
|
||||||
~CScreenInfo();
|
|
||||||
|
|
||||||
public:
|
|
||||||
// the thread handling this screen's connection. used when
|
|
||||||
// forcing a screen to disconnect.
|
|
||||||
CThread m_thread;
|
|
||||||
CString m_name;
|
|
||||||
IServerProtocol* m_protocol;
|
|
||||||
bool m_ready;
|
|
||||||
|
|
||||||
// screen shape and jump zone size
|
|
||||||
SInt32 m_x, m_y;
|
|
||||||
SInt32 m_w, m_h;
|
|
||||||
SInt32 m_zoneSize;
|
|
||||||
|
|
||||||
bool m_gotClipboard[kClipboardEnd];
|
|
||||||
};
|
|
||||||
|
|
||||||
// handle mouse motion
|
// handle mouse motion
|
||||||
bool onMouseMovePrimaryNoLock(SInt32 x, SInt32 y);
|
bool onMouseMovePrimaryNoLock(SInt32 x, SInt32 y);
|
||||||
void onMouseMoveSecondaryNoLock(SInt32 dx, SInt32 dy);
|
void onMouseMoveSecondaryNoLock(SInt32 dx, SInt32 dy);
|
||||||
|
|
||||||
// update screen info
|
|
||||||
void setInfoNoLock(const CString& screenName,
|
|
||||||
SInt32 xScreen, SInt32 yScreen,
|
|
||||||
SInt32 wScreen, SInt32 hScreen,
|
|
||||||
SInt32 zoneSize,
|
|
||||||
SInt32 xMouse, SInt32 yMouse);
|
|
||||||
|
|
||||||
// grab the clipboard
|
// grab the clipboard
|
||||||
void grabClipboardNoLock(ClipboardID,
|
bool grabClipboardNoLock(ClipboardID,
|
||||||
UInt32 seqNum, const CString& clientName);
|
UInt32 seqNum, const CString& clientName);
|
||||||
|
|
||||||
|
// set the clipboard
|
||||||
|
void onClipboardChangedNoLock(ClipboardID,
|
||||||
|
UInt32 seqNum, const CString& data);
|
||||||
|
|
||||||
// returns true iff mouse should be locked to the current screen
|
// returns true iff mouse should be locked to the current screen
|
||||||
bool isLockedToScreenNoLock() const;
|
bool isLockedToScreenNoLock() const;
|
||||||
|
|
||||||
// change the active screen
|
// change the active screen
|
||||||
void switchScreen(CScreenInfo*,
|
void switchScreen(IClient*,
|
||||||
SInt32 x, SInt32 y, bool forScreenSaver);
|
SInt32 x, SInt32 y, bool forScreenSaver);
|
||||||
|
|
||||||
// lookup neighboring screen
|
// lookup neighboring screen
|
||||||
CScreenInfo* getNeighbor(CScreenInfo*, CConfig::EDirection) const;
|
IClient* getNeighbor(IClient*, CConfig::EDirection) const;
|
||||||
|
|
||||||
// lookup neighboring screen. given a position relative to the
|
// lookup neighboring screen. given a position relative to the
|
||||||
// source screen, find the screen we should move onto and where.
|
// source screen, find the screen we should move onto and where.
|
||||||
// if the position is sufficiently far from the source then we
|
// if the position is sufficiently far from the source then we
|
||||||
// cross multiple screens. if there is no suitable screen then
|
// cross multiple screens. if there is no suitable screen then
|
||||||
// return NULL and x,y are not modified.
|
// return NULL and x,y are not modified.
|
||||||
CScreenInfo* getNeighbor(CScreenInfo*,
|
IClient* getNeighbor(IClient*,
|
||||||
CConfig::EDirection,
|
CConfig::EDirection,
|
||||||
SInt32& x, SInt32& y) const;
|
SInt32& x, SInt32& y) const;
|
||||||
|
|
||||||
|
@ -156,15 +116,13 @@ private:
|
||||||
void openPrimaryScreen();
|
void openPrimaryScreen();
|
||||||
void closePrimaryScreen();
|
void closePrimaryScreen();
|
||||||
|
|
||||||
// clear gotClipboard flags in all screens
|
|
||||||
void clearGotClipboard(ClipboardID);
|
|
||||||
|
|
||||||
// send clipboard to the active screen if it doesn't already have it
|
|
||||||
void sendClipboard(ClipboardID);
|
|
||||||
|
|
||||||
// update the clipboard if owned by the primary screen
|
// update the clipboard if owned by the primary screen
|
||||||
void updatePrimaryClipboard(ClipboardID);
|
void updatePrimaryClipboard(ClipboardID);
|
||||||
|
|
||||||
|
// close all clients that are *not* in config, not including the
|
||||||
|
// primary client.
|
||||||
|
void closeClients(const CConfig& config);
|
||||||
|
|
||||||
// start a thread, adding it to the list of threads
|
// start a thread, adding it to the list of threads
|
||||||
void startThread(IJob* adopted);
|
void startThread(IJob* adopted);
|
||||||
|
|
||||||
|
@ -180,8 +138,9 @@ private:
|
||||||
// thread method to accept incoming client connections
|
// thread method to accept incoming client connections
|
||||||
void acceptClients(void*);
|
void acceptClients(void*);
|
||||||
|
|
||||||
// thread method to do startup handshake with client
|
// thread method to do client interaction
|
||||||
void handshakeClient(void*);
|
void runClient(void*);
|
||||||
|
CClientProxy* handshakeClient(IDataSocket*);
|
||||||
|
|
||||||
// thread method to accept incoming HTTP connections
|
// thread method to accept incoming HTTP connections
|
||||||
void acceptHTTPClients(void*);
|
void acceptHTTPClients(void*);
|
||||||
|
@ -190,11 +149,10 @@ private:
|
||||||
void processHTTPRequest(void*);
|
void processHTTPRequest(void*);
|
||||||
|
|
||||||
// connection list maintenance
|
// connection list maintenance
|
||||||
CScreenInfo* addConnection(const CString& name, IServerProtocol*);
|
void addConnection(IClient*);
|
||||||
void removeConnection(const CString& name);
|
void removeConnection(const CString& name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<CString, CScreenInfo*> CScreenList;
|
|
||||||
class CClipboardInfo {
|
class CClipboardInfo {
|
||||||
public:
|
public:
|
||||||
CClipboardInfo();
|
CClipboardInfo();
|
||||||
|
@ -204,7 +162,6 @@ private:
|
||||||
CString m_clipboardData;
|
CString m_clipboardData;
|
||||||
CString m_clipboardOwner;
|
CString m_clipboardOwner;
|
||||||
UInt32 m_clipboardSeqNum;
|
UInt32 m_clipboardSeqNum;
|
||||||
bool m_clipboardReady;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CMutex m_mutex;
|
CMutex m_mutex;
|
||||||
|
@ -212,6 +169,7 @@ private:
|
||||||
// the name of the primary screen
|
// the name of the primary screen
|
||||||
CString m_name;
|
CString m_name;
|
||||||
|
|
||||||
|
// how long to wait to bind our socket until we give up
|
||||||
double m_bindTimeout;
|
double m_bindTimeout;
|
||||||
|
|
||||||
ISocketFactory* m_socketFactory;
|
ISocketFactory* m_socketFactory;
|
||||||
|
@ -221,10 +179,21 @@ private:
|
||||||
CThreadList m_threads;
|
CThreadList m_threads;
|
||||||
|
|
||||||
// the screens
|
// the screens
|
||||||
IPrimaryScreen* m_primary;
|
typedef std::map<CString, IClient*> CClientList;
|
||||||
CScreenList m_screens;
|
typedef std::map<CString, CThread> CClientThreadList;
|
||||||
CScreenInfo* m_active;
|
|
||||||
CScreenInfo* m_primaryInfo;
|
// all clients indexed by name
|
||||||
|
CClientList m_clients;
|
||||||
|
|
||||||
|
// run thread of all secondary screen clients. does not include the
|
||||||
|
// primary screen's run thread.
|
||||||
|
CClientThreadList m_clientThreads;
|
||||||
|
|
||||||
|
// the primary screen client
|
||||||
|
CPrimaryClient* m_primaryClient;
|
||||||
|
|
||||||
|
// the client with focus
|
||||||
|
IClient* m_active;
|
||||||
|
|
||||||
// the sequence number of enter messages
|
// the sequence number of enter messages
|
||||||
UInt32 m_seqNum;
|
UInt32 m_seqNum;
|
||||||
|
@ -239,7 +208,7 @@ private:
|
||||||
CClipboardInfo m_clipboards[kClipboardEnd];
|
CClipboardInfo m_clipboards[kClipboardEnd];
|
||||||
|
|
||||||
// state saved when screen saver activates
|
// state saved when screen saver activates
|
||||||
CScreenInfo* m_activeSaver;
|
IClient* m_activeSaver;
|
||||||
SInt32 m_xSaver, m_ySaver;
|
SInt32 m_xSaver, m_ySaver;
|
||||||
|
|
||||||
// HTTP request processing stuff
|
// HTTP request processing stuff
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
#include "CServerProtocol.h"
|
|
||||||
#include "CServerProtocol1_0.h"
|
|
||||||
#include "ProtocolTypes.h"
|
|
||||||
#include "XSynergy.h"
|
|
||||||
#include "IOutputStream.h"
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
//
|
|
||||||
// CServerProtocol
|
|
||||||
//
|
|
||||||
|
|
||||||
CServerProtocol::CServerProtocol(CServer* server, const CString& client,
|
|
||||||
IInputStream* input, IOutputStream* output) :
|
|
||||||
m_server(server),
|
|
||||||
m_client(client),
|
|
||||||
m_input(input),
|
|
||||||
m_output(output)
|
|
||||||
{
|
|
||||||
assert(m_server != NULL);
|
|
||||||
assert(m_input != NULL);
|
|
||||||
assert(m_output != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
CServerProtocol::~CServerProtocol()
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
CServer*
|
|
||||||
CServerProtocol::getServer() const
|
|
||||||
{
|
|
||||||
return m_server;
|
|
||||||
}
|
|
||||||
|
|
||||||
CString
|
|
||||||
CServerProtocol::getClient() const
|
|
||||||
{
|
|
||||||
return m_client;
|
|
||||||
}
|
|
||||||
|
|
||||||
IInputStream*
|
|
||||||
CServerProtocol::getInputStream() const
|
|
||||||
{
|
|
||||||
return m_input;
|
|
||||||
}
|
|
||||||
|
|
||||||
IOutputStream*
|
|
||||||
CServerProtocol::getOutputStream() const
|
|
||||||
{
|
|
||||||
return m_output;
|
|
||||||
}
|
|
||||||
|
|
||||||
IServerProtocol*
|
|
||||||
CServerProtocol::create(SInt32 major, SInt32 minor,
|
|
||||||
CServer* server, const CString& client,
|
|
||||||
IInputStream* input, IOutputStream* output)
|
|
||||||
{
|
|
||||||
// disallow invalid version numbers
|
|
||||||
if (major < 0 || minor < 0) {
|
|
||||||
throw XIncompatibleClient(major, minor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// disallow connection from test versions to release versions
|
|
||||||
if (major == 0 && kProtocolMajorVersion != 0) {
|
|
||||||
throw XIncompatibleClient(major, minor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// hangup (with error) if version isn't supported
|
|
||||||
if (major > kProtocolMajorVersion ||
|
|
||||||
(major == kProtocolMajorVersion && minor > kProtocolMinorVersion)) {
|
|
||||||
throw XIncompatibleClient(major, minor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create highest version protocol object not higher than the
|
|
||||||
// given version.
|
|
||||||
return new CServerProtocol1_0(server, client, input, output);
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
#ifndef CSERVERPROTOCOL_H
|
|
||||||
#define CSERVERPROTOCOL_H
|
|
||||||
|
|
||||||
#include "IServerProtocol.h"
|
|
||||||
|
|
||||||
class CServer;
|
|
||||||
class IInputStream;
|
|
||||||
class IOutputStream;
|
|
||||||
|
|
||||||
class CServerProtocol : public IServerProtocol {
|
|
||||||
public:
|
|
||||||
CServerProtocol(CServer*, const CString& clientName,
|
|
||||||
IInputStream*, IOutputStream*);
|
|
||||||
~CServerProtocol();
|
|
||||||
|
|
||||||
// manipulators
|
|
||||||
|
|
||||||
// accessors
|
|
||||||
|
|
||||||
virtual CServer* getServer() const;
|
|
||||||
virtual CString getClient() const;
|
|
||||||
virtual IInputStream* getInputStream() const;
|
|
||||||
virtual IOutputStream* getOutputStream() const;
|
|
||||||
|
|
||||||
static IServerProtocol* create(SInt32 major, SInt32 minor,
|
|
||||||
CServer*, const CString& clientName,
|
|
||||||
IInputStream*, IOutputStream*);
|
|
||||||
|
|
||||||
// IServerProtocol overrides
|
|
||||||
virtual void run() = 0;
|
|
||||||
virtual void queryInfo() = 0;
|
|
||||||
virtual void sendClose() = 0;
|
|
||||||
virtual void sendEnter(SInt32 xAbs, SInt32 yAbs,
|
|
||||||
UInt32 seqNum, KeyModifierMask mask) = 0;
|
|
||||||
virtual void sendLeave() = 0;
|
|
||||||
virtual void sendClipboard(ClipboardID, const CString&) = 0;
|
|
||||||
virtual void sendGrabClipboard(ClipboardID) = 0;
|
|
||||||
virtual void sendScreenSaver(bool on) = 0;
|
|
||||||
virtual void sendInfoAcknowledgment() = 0;
|
|
||||||
virtual void sendKeyDown(KeyID, KeyModifierMask) = 0;
|
|
||||||
virtual void sendKeyRepeat(KeyID, KeyModifierMask, SInt32 count) = 0;
|
|
||||||
virtual void sendKeyUp(KeyID, KeyModifierMask) = 0;
|
|
||||||
virtual void sendMouseDown(ButtonID) = 0;
|
|
||||||
virtual void sendMouseUp(ButtonID) = 0;
|
|
||||||
virtual void sendMouseMove(SInt32 xAbs, SInt32 yAbs) = 0;
|
|
||||||
virtual void sendMouseWheel(SInt32 delta) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
//IServerProtocol overrides
|
|
||||||
virtual void recvInfo() = 0;
|
|
||||||
virtual void recvClipboard() = 0;
|
|
||||||
virtual void recvGrabClipboard() = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
CServer* m_server;
|
|
||||||
CString m_client;
|
|
||||||
IInputStream* m_input;
|
|
||||||
IOutputStream* m_output;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,283 +0,0 @@
|
||||||
#include "CServerProtocol1_0.h"
|
|
||||||
#include "CServer.h"
|
|
||||||
#include "CClipboard.h"
|
|
||||||
#include "CProtocolUtil.h"
|
|
||||||
#include "ProtocolTypes.h"
|
|
||||||
#include "XSynergy.h"
|
|
||||||
#include "IInputStream.h"
|
|
||||||
#include "IOutputStream.h"
|
|
||||||
#include "CThread.h"
|
|
||||||
#include "CLog.h"
|
|
||||||
#include "CStopwatch.h"
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
//
|
|
||||||
// CServerProtocol1_0
|
|
||||||
//
|
|
||||||
|
|
||||||
CServerProtocol1_0::CServerProtocol1_0(CServer* server, const CString& client,
|
|
||||||
IInputStream* input, IOutputStream* output) :
|
|
||||||
CServerProtocol(server, client, input, output)
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
CServerProtocol1_0::~CServerProtocol1_0()
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::run()
|
|
||||||
{
|
|
||||||
// handle messages until the client hangs up or stops sending heartbeats
|
|
||||||
CStopwatch heartTimer;
|
|
||||||
for (;;) {
|
|
||||||
CThread::testCancel();
|
|
||||||
|
|
||||||
// wait for a message
|
|
||||||
UInt8 code[4];
|
|
||||||
UInt32 n = getInputStream()->read(code, 4, kHeartRate);
|
|
||||||
CThread::testCancel();
|
|
||||||
|
|
||||||
// check if client hungup
|
|
||||||
if (n == 0) {
|
|
||||||
log((CLOG_NOTE "client \"%s\" disconnected", getClient().c_str()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if client has stopped sending heartbeats
|
|
||||||
if (n == (UInt32)-1) {
|
|
||||||
/* FIXME -- disabled to avoid masking bugs
|
|
||||||
if (heartTimer.getTime() > kHeartDeath) {
|
|
||||||
log((CLOG_NOTE "client \"%s\" is dead", getClient().c_str()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// got a message so reset heartbeat monitor
|
|
||||||
heartTimer.reset();
|
|
||||||
|
|
||||||
// verify we got an entire code
|
|
||||||
if (n != 4) {
|
|
||||||
log((CLOG_ERR "incomplete message from \"%s\": %d bytes", getClient().c_str(), n));
|
|
||||||
|
|
||||||
// client sent an incomplete message
|
|
||||||
throw XBadClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse message
|
|
||||||
log((CLOG_DEBUG2 "msg from \"%s\": %c%c%c%c", getClient().c_str(), code[0], code[1], code[2], code[3]));
|
|
||||||
if (memcmp(code, kMsgDInfo, 4) == 0) {
|
|
||||||
recvInfo();
|
|
||||||
}
|
|
||||||
else if (memcmp(code, kMsgCNoop, 4) == 0) {
|
|
||||||
// discard no-ops
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (memcmp(code, kMsgCClipboard, 4) == 0) {
|
|
||||||
recvGrabClipboard();
|
|
||||||
}
|
|
||||||
else if (memcmp(code, kMsgDClipboard, 4) == 0) {
|
|
||||||
recvClipboard();
|
|
||||||
}
|
|
||||||
// FIXME -- more message here
|
|
||||||
else {
|
|
||||||
log((CLOG_ERR "invalid message from client \"%s\"", getClient().c_str()));
|
|
||||||
|
|
||||||
// unknown message
|
|
||||||
throw XBadClient();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::queryInfo()
|
|
||||||
{
|
|
||||||
log((CLOG_DEBUG1 "querying client \"%s\" info", getClient().c_str()));
|
|
||||||
|
|
||||||
// send request
|
|
||||||
CProtocolUtil::writef(getOutputStream(), kMsgQInfo);
|
|
||||||
|
|
||||||
// wait for and verify reply
|
|
||||||
UInt8 code[4];
|
|
||||||
for (;;) {
|
|
||||||
UInt32 n = getInputStream()->read(code, 4, -1.0);
|
|
||||||
if (n == 4) {
|
|
||||||
if (memcmp(code, kMsgCNoop, 4) == 0) {
|
|
||||||
// discard heartbeats
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (memcmp(code, kMsgDInfo, 4) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw XBadClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle reply
|
|
||||||
recvInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::sendClose()
|
|
||||||
{
|
|
||||||
log((CLOG_DEBUG1 "send close to \"%s\"", getClient().c_str()));
|
|
||||||
CProtocolUtil::writef(getOutputStream(), kMsgCClose);
|
|
||||||
|
|
||||||
// force the close to be sent before we return
|
|
||||||
getOutputStream()->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::sendEnter(SInt32 xAbs, SInt32 yAbs,
|
|
||||||
UInt32 seqNum, KeyModifierMask mask)
|
|
||||||
{
|
|
||||||
log((CLOG_DEBUG1 "send enter to \"%s\", %d,%d %d %04x", getClient().c_str(), xAbs, yAbs, seqNum, mask));
|
|
||||||
CProtocolUtil::writef(getOutputStream(), kMsgCEnter,
|
|
||||||
xAbs, yAbs, seqNum, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::sendLeave()
|
|
||||||
{
|
|
||||||
log((CLOG_DEBUG1 "send leave to \"%s\"", getClient().c_str()));
|
|
||||||
CProtocolUtil::writef(getOutputStream(), kMsgCLeave);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::sendClipboard(ClipboardID id, const CString& data)
|
|
||||||
{
|
|
||||||
log((CLOG_DEBUG "send clipboard %d to \"%s\" size=%d", id, getClient().c_str(), data.size()));
|
|
||||||
CProtocolUtil::writef(getOutputStream(), kMsgDClipboard, id, 0, &data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::sendGrabClipboard(ClipboardID id)
|
|
||||||
{
|
|
||||||
log((CLOG_DEBUG "send grab clipboard %d to \"%s\"", id, getClient().c_str()));
|
|
||||||
CProtocolUtil::writef(getOutputStream(), kMsgCClipboard, id, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::sendScreenSaver(bool on)
|
|
||||||
{
|
|
||||||
log((CLOG_DEBUG1 "send screen saver to \"%s\" on=%d", getClient().c_str(), on ? 1 : 0));
|
|
||||||
CProtocolUtil::writef(getOutputStream(), kMsgCScreenSaver, on ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::sendInfoAcknowledgment()
|
|
||||||
{
|
|
||||||
log((CLOG_DEBUG1 "send info ack to \"%s\"", getClient().c_str()));
|
|
||||||
CProtocolUtil::writef(getOutputStream(), kMsgCInfoAck);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::sendKeyDown(KeyID key, KeyModifierMask mask)
|
|
||||||
{
|
|
||||||
log((CLOG_DEBUG1 "send key down to \"%s\" id=%d, mask=0x%04x", getClient().c_str(), key, mask));
|
|
||||||
CProtocolUtil::writef(getOutputStream(), kMsgDKeyDown, key, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::sendKeyRepeat(KeyID key, KeyModifierMask mask, SInt32 count)
|
|
||||||
{
|
|
||||||
log((CLOG_DEBUG1 "send key repeat to \"%s\" id=%d, mask=0x%04x, count=%d", getClient().c_str(), key, mask, count));
|
|
||||||
CProtocolUtil::writef(getOutputStream(), kMsgDKeyRepeat, key, mask, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::sendKeyUp(KeyID key, KeyModifierMask mask)
|
|
||||||
{
|
|
||||||
log((CLOG_DEBUG1 "send key up to \"%s\" id=%d, mask=0x%04x", getClient().c_str(), key, mask));
|
|
||||||
CProtocolUtil::writef(getOutputStream(), kMsgDKeyUp, key, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::sendMouseDown(ButtonID button)
|
|
||||||
{
|
|
||||||
log((CLOG_DEBUG1 "send mouse down to \"%s\" id=%d", getClient().c_str(), button));
|
|
||||||
CProtocolUtil::writef(getOutputStream(), kMsgDMouseDown, button);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::sendMouseUp(ButtonID button)
|
|
||||||
{
|
|
||||||
log((CLOG_DEBUG1 "send mouse up to \"%s\" id=%d", getClient().c_str(), button));
|
|
||||||
CProtocolUtil::writef(getOutputStream(), kMsgDMouseUp, button);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::sendMouseMove(SInt32 xAbs, SInt32 yAbs)
|
|
||||||
{
|
|
||||||
log((CLOG_DEBUG2 "send mouse move to \"%s\" %d,%d", getClient().c_str(), xAbs, yAbs));
|
|
||||||
CProtocolUtil::writef(getOutputStream(), kMsgDMouseMove, xAbs, yAbs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::sendMouseWheel(SInt32 delta)
|
|
||||||
{
|
|
||||||
log((CLOG_DEBUG2 "send mouse wheel to \"%s\" %+d", getClient().c_str(), delta));
|
|
||||||
CProtocolUtil::writef(getOutputStream(), kMsgDMouseWheel, delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::recvInfo()
|
|
||||||
{
|
|
||||||
// parse the message
|
|
||||||
SInt16 x, y, w, h, zoneInfo, mx, my;
|
|
||||||
CProtocolUtil::readf(getInputStream(), kMsgDInfo + 4,
|
|
||||||
&x, &y, &w, &h, &zoneInfo, &mx, &my);
|
|
||||||
log((CLOG_DEBUG "received client \"%s\" info shape=%d,%d %dx%d, zone=%d, pos=%d,%d", getClient().c_str(), x, y, w, h, zoneInfo, mx, my));
|
|
||||||
|
|
||||||
// validate
|
|
||||||
if (w <= 0 || h <= 0 || zoneInfo < 0) {
|
|
||||||
throw XBadClient();
|
|
||||||
}
|
|
||||||
if (mx < x || my < y || mx >= x + w || my >= y + h) {
|
|
||||||
throw XBadClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
// tell server of change
|
|
||||||
getServer()->setInfo(getClient(), x, y, w, h, zoneInfo, mx, my);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::recvClipboard()
|
|
||||||
{
|
|
||||||
// parse message
|
|
||||||
ClipboardID id;
|
|
||||||
UInt32 seqNum;
|
|
||||||
CString data;
|
|
||||||
CProtocolUtil::readf(getInputStream(), kMsgDClipboard + 4, &id, &seqNum, &data);
|
|
||||||
log((CLOG_DEBUG "received client \"%s\" clipboard %d seqnum=%d, size=%d", getClient().c_str(), id, seqNum, data.size()));
|
|
||||||
|
|
||||||
// validate
|
|
||||||
if (id >= kClipboardEnd) {
|
|
||||||
throw XBadClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
// send update
|
|
||||||
getServer()->setClipboard(id, seqNum, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CServerProtocol1_0::recvGrabClipboard()
|
|
||||||
{
|
|
||||||
// parse message
|
|
||||||
ClipboardID id;
|
|
||||||
UInt32 seqNum;
|
|
||||||
CProtocolUtil::readf(getInputStream(), kMsgCClipboard + 4, &id, &seqNum);
|
|
||||||
log((CLOG_DEBUG "received client \"%s\" grabbed clipboard %d seqnum=%d", getClient().c_str(), id, seqNum));
|
|
||||||
|
|
||||||
// validate
|
|
||||||
if (id >= kClipboardEnd) {
|
|
||||||
throw XBadClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
// send update
|
|
||||||
getServer()->grabClipboard(id, seqNum, getClient());
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
#ifndef CSERVERPROTOCOL1_0_H
|
|
||||||
#define CSERVERPROTOCOL1_0_H
|
|
||||||
|
|
||||||
#include "CServerProtocol.h"
|
|
||||||
|
|
||||||
class CServerProtocol1_0 : public CServerProtocol {
|
|
||||||
public:
|
|
||||||
CServerProtocol1_0(CServer*, const CString&, IInputStream*, IOutputStream*);
|
|
||||||
~CServerProtocol1_0();
|
|
||||||
|
|
||||||
// manipulators
|
|
||||||
|
|
||||||
// accessors
|
|
||||||
|
|
||||||
// IServerProtocol overrides
|
|
||||||
virtual void run();
|
|
||||||
virtual void queryInfo();
|
|
||||||
virtual void sendClose();
|
|
||||||
virtual void sendEnter(SInt32 xAbs, SInt32 yAbs,
|
|
||||||
UInt32 seqNum, KeyModifierMask mask);
|
|
||||||
virtual void sendLeave();
|
|
||||||
virtual void sendClipboard(ClipboardID, const CString&);
|
|
||||||
virtual void sendGrabClipboard(ClipboardID);
|
|
||||||
virtual void sendScreenSaver(bool on);
|
|
||||||
virtual void sendInfoAcknowledgment();
|
|
||||||
virtual void sendKeyDown(KeyID, KeyModifierMask);
|
|
||||||
virtual void sendKeyRepeat(KeyID, KeyModifierMask, SInt32 count);
|
|
||||||
virtual void sendKeyUp(KeyID, KeyModifierMask);
|
|
||||||
virtual void sendMouseDown(ButtonID);
|
|
||||||
virtual void sendMouseUp(ButtonID);
|
|
||||||
virtual void sendMouseMove(SInt32 xAbs, SInt32 yAbs);
|
|
||||||
virtual void sendMouseWheel(SInt32 delta);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// IServerProtocol overrides
|
|
||||||
virtual void recvInfo();
|
|
||||||
virtual void recvClipboard();
|
|
||||||
virtual void recvGrabClipboard();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,8 +1,9 @@
|
||||||
#include "CXWindowsPrimaryScreen.h"
|
#include "CXWindowsPrimaryScreen.h"
|
||||||
#include "CServer.h"
|
#include "IPrimaryReceiver.h"
|
||||||
#include "CXWindowsClipboard.h"
|
#include "CXWindowsClipboard.h"
|
||||||
#include "CXWindowsScreenSaver.h"
|
#include "CXWindowsScreenSaver.h"
|
||||||
#include "CXWindowsUtil.h"
|
#include "CXWindowsUtil.h"
|
||||||
|
#include "CClipboard.h"
|
||||||
#include "CThread.h"
|
#include "CThread.h"
|
||||||
#include "CLog.h"
|
#include "CLog.h"
|
||||||
#include "CStopwatch.h"
|
#include "CStopwatch.h"
|
||||||
|
@ -19,8 +20,8 @@
|
||||||
// CXWindowsPrimaryScreen
|
// CXWindowsPrimaryScreen
|
||||||
//
|
//
|
||||||
|
|
||||||
CXWindowsPrimaryScreen::CXWindowsPrimaryScreen() :
|
CXWindowsPrimaryScreen::CXWindowsPrimaryScreen(IPrimaryReceiver* receiver) :
|
||||||
m_server(NULL),
|
m_receiver(receiver),
|
||||||
m_active(false),
|
m_active(false),
|
||||||
m_window(None)
|
m_window(None)
|
||||||
{
|
{
|
||||||
|
@ -65,7 +66,7 @@ CXWindowsPrimaryScreen::run()
|
||||||
if (xevent.xclient.message_type == m_atomScreenSaver ||
|
if (xevent.xclient.message_type == m_atomScreenSaver ||
|
||||||
xevent.xclient.format == 32) {
|
xevent.xclient.format == 32) {
|
||||||
// screen saver activation/deactivation event
|
// screen saver activation/deactivation event
|
||||||
m_server->onScreenSaver(xevent.xclient.data.l[0] != 0);
|
m_receiver->onScreenSaver(xevent.xclient.data.l[0] != 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -75,12 +76,12 @@ CXWindowsPrimaryScreen::run()
|
||||||
const KeyModifierMask mask = mapModifier(xevent.xkey.state);
|
const KeyModifierMask mask = mapModifier(xevent.xkey.state);
|
||||||
const KeyID key = mapKey(&xevent.xkey);
|
const KeyID key = mapKey(&xevent.xkey);
|
||||||
if (key != kKeyNone) {
|
if (key != kKeyNone) {
|
||||||
m_server->onKeyDown(key, mask);
|
m_receiver->onKeyDown(key, mask);
|
||||||
if (key == XK_Caps_Lock && m_capsLockHalfDuplex) {
|
if (key == XK_Caps_Lock && m_capsLockHalfDuplex) {
|
||||||
m_server->onKeyUp(key, mask | KeyModifierCapsLock);
|
m_receiver->onKeyUp(key, mask | KeyModifierCapsLock);
|
||||||
}
|
}
|
||||||
else if (key == XK_Num_Lock && m_numLockHalfDuplex) {
|
else if (key == XK_Num_Lock && m_numLockHalfDuplex) {
|
||||||
m_server->onKeyUp(key, mask | KeyModifierNumLock);
|
m_receiver->onKeyUp(key, mask | KeyModifierNumLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,12 +111,12 @@ CXWindowsPrimaryScreen::run()
|
||||||
// no press event follows so it's a plain release
|
// no press event follows so it's a plain release
|
||||||
log((CLOG_DEBUG1 "event: KeyRelease code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
|
log((CLOG_DEBUG1 "event: KeyRelease code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
|
||||||
if (key == XK_Caps_Lock && m_capsLockHalfDuplex) {
|
if (key == XK_Caps_Lock && m_capsLockHalfDuplex) {
|
||||||
m_server->onKeyDown(key, mask);
|
m_receiver->onKeyDown(key, mask);
|
||||||
}
|
}
|
||||||
else if (key == XK_Num_Lock && m_numLockHalfDuplex) {
|
else if (key == XK_Num_Lock && m_numLockHalfDuplex) {
|
||||||
m_server->onKeyDown(key, mask);
|
m_receiver->onKeyDown(key, mask);
|
||||||
}
|
}
|
||||||
m_server->onKeyUp(key, mask);
|
m_receiver->onKeyUp(key, mask);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// found a press event following so it's a repeat.
|
// found a press event following so it's a repeat.
|
||||||
|
@ -123,7 +124,7 @@ CXWindowsPrimaryScreen::run()
|
||||||
// repeats but we'll just send a repeat of 1.
|
// repeats but we'll just send a repeat of 1.
|
||||||
// note that we discard the press event.
|
// note that we discard the press event.
|
||||||
log((CLOG_DEBUG1 "event: repeat code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
|
log((CLOG_DEBUG1 "event: repeat code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
|
||||||
m_server->onKeyRepeat(key, mask, 1);
|
m_receiver->onKeyRepeat(key, mask, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,7 +135,7 @@ CXWindowsPrimaryScreen::run()
|
||||||
log((CLOG_DEBUG1 "event: ButtonPress button=%d", xevent.xbutton.button));
|
log((CLOG_DEBUG1 "event: ButtonPress button=%d", xevent.xbutton.button));
|
||||||
const ButtonID button = mapButton(xevent.xbutton.button);
|
const ButtonID button = mapButton(xevent.xbutton.button);
|
||||||
if (button != kButtonNone) {
|
if (button != kButtonNone) {
|
||||||
m_server->onMouseDown(button);
|
m_receiver->onMouseDown(button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -144,15 +145,15 @@ CXWindowsPrimaryScreen::run()
|
||||||
log((CLOG_DEBUG1 "event: ButtonRelease button=%d", xevent.xbutton.button));
|
log((CLOG_DEBUG1 "event: ButtonRelease button=%d", xevent.xbutton.button));
|
||||||
const ButtonID button = mapButton(xevent.xbutton.button);
|
const ButtonID button = mapButton(xevent.xbutton.button);
|
||||||
if (button != kButtonNone) {
|
if (button != kButtonNone) {
|
||||||
m_server->onMouseUp(button);
|
m_receiver->onMouseUp(button);
|
||||||
}
|
}
|
||||||
else if (xevent.xbutton.button == 4) {
|
else if (xevent.xbutton.button == 4) {
|
||||||
// wheel forward (away from user)
|
// wheel forward (away from user)
|
||||||
m_server->onMouseWheel(120);
|
m_receiver->onMouseWheel(120);
|
||||||
}
|
}
|
||||||
else if (xevent.xbutton.button == 5) {
|
else if (xevent.xbutton.button == 5) {
|
||||||
// wheel backward (toward user)
|
// wheel backward (toward user)
|
||||||
m_server->onMouseWheel(-120);
|
m_receiver->onMouseWheel(-120);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -183,7 +184,7 @@ CXWindowsPrimaryScreen::run()
|
||||||
}
|
}
|
||||||
else if (!m_active) {
|
else if (!m_active) {
|
||||||
// motion on primary screen
|
// motion on primary screen
|
||||||
m_server->onMouseMovePrimary(m_x, m_y);
|
m_receiver->onMouseMovePrimary(m_x, m_y);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// motion on secondary screen. warp mouse back to
|
// motion on secondary screen. warp mouse back to
|
||||||
|
@ -214,7 +215,7 @@ CXWindowsPrimaryScreen::run()
|
||||||
// warping to the primary screen's enter position,
|
// warping to the primary screen's enter position,
|
||||||
// effectively overriding it.
|
// effectively overriding it.
|
||||||
if (x != 0 || y != 0) {
|
if (x != 0 || y != 0) {
|
||||||
m_server->onMouseMoveSecondary(x, y);
|
m_receiver->onMouseMoveSecondary(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,17 +232,11 @@ CXWindowsPrimaryScreen::stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CXWindowsPrimaryScreen::open(CServer* server)
|
CXWindowsPrimaryScreen::open()
|
||||||
{
|
{
|
||||||
assert(m_server == NULL);
|
|
||||||
assert(server != NULL);
|
|
||||||
|
|
||||||
// open the display
|
// open the display
|
||||||
openDisplay();
|
openDisplay();
|
||||||
|
|
||||||
// set the server
|
|
||||||
m_server = server;
|
|
||||||
|
|
||||||
// check for peculiarities
|
// check for peculiarities
|
||||||
// FIXME -- may have to get these from some database
|
// FIXME -- may have to get these from some database
|
||||||
m_numLockHalfDuplex = false;
|
m_numLockHalfDuplex = false;
|
||||||
|
@ -283,23 +278,18 @@ CXWindowsPrimaryScreen::open(CServer* server)
|
||||||
m_yCenter = y + (h >> 1);
|
m_yCenter = y + (h >> 1);
|
||||||
|
|
||||||
// send screen info
|
// send screen info
|
||||||
m_server->setInfo(x, y, w, h, getJumpZoneSize(), m_x, m_y);
|
m_receiver->onInfoChanged(x, y, w, h, 1, m_x, m_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CXWindowsPrimaryScreen::close()
|
CXWindowsPrimaryScreen::close()
|
||||||
{
|
{
|
||||||
assert(m_server != NULL);
|
|
||||||
|
|
||||||
// stop being notified of screen saver activation/deactivation
|
// stop being notified of screen saver activation/deactivation
|
||||||
getScreenSaver()->setNotify(None);
|
getScreenSaver()->setNotify(None);
|
||||||
m_atomScreenSaver = None;
|
m_atomScreenSaver = None;
|
||||||
|
|
||||||
// close the display
|
// close the display
|
||||||
closeDisplay();
|
closeDisplay();
|
||||||
|
|
||||||
// done with server
|
|
||||||
m_server = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -394,7 +384,7 @@ CXWindowsPrimaryScreen::leave()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CXWindowsPrimaryScreen::onConfigure()
|
CXWindowsPrimaryScreen::reconfigure()
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -475,19 +465,6 @@ CXWindowsPrimaryScreen::grabClipboard(ClipboardID id)
|
||||||
setDisplayClipboard(id, NULL);
|
setDisplayClipboard(id, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CXWindowsPrimaryScreen::getShape(
|
|
||||||
SInt32& x, SInt32& y, SInt32& w, SInt32& h) const
|
|
||||||
{
|
|
||||||
getScreenShape(x, y, w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
SInt32
|
|
||||||
CXWindowsPrimaryScreen::getJumpZoneSize() const
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CXWindowsPrimaryScreen::getClipboard(ClipboardID id,
|
CXWindowsPrimaryScreen::getClipboard(ClipboardID id,
|
||||||
IClipboard* clipboard) const
|
IClipboard* clipboard) const
|
||||||
|
@ -555,13 +532,6 @@ CXWindowsPrimaryScreen::isLockedToScreen() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
CXWindowsPrimaryScreen::isScreenSaverActive() const
|
|
||||||
{
|
|
||||||
CDisplayLock display(this);
|
|
||||||
return getScreenSaver()->isActive();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CXWindowsPrimaryScreen::onOpenDisplay(Display* display)
|
CXWindowsPrimaryScreen::onOpenDisplay(Display* display)
|
||||||
{
|
{
|
||||||
|
@ -616,16 +586,14 @@ void
|
||||||
CXWindowsPrimaryScreen::onUnexpectedClose()
|
CXWindowsPrimaryScreen::onUnexpectedClose()
|
||||||
{
|
{
|
||||||
// tell server to shutdown
|
// tell server to shutdown
|
||||||
if (m_server != NULL) {
|
m_receiver->onError();
|
||||||
m_server->shutdown();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CXWindowsPrimaryScreen::onLostClipboard(ClipboardID id)
|
CXWindowsPrimaryScreen::onLostClipboard(ClipboardID id)
|
||||||
{
|
{
|
||||||
// tell server that the clipboard was grabbed locally
|
// tell server that the clipboard was grabbed locally
|
||||||
m_server->grabClipboard(id);
|
m_receiver->onGrabClipboard(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -5,28 +5,27 @@
|
||||||
#include "IPrimaryScreen.h"
|
#include "IPrimaryScreen.h"
|
||||||
#include "MouseTypes.h"
|
#include "MouseTypes.h"
|
||||||
|
|
||||||
|
class IPrimaryReceiver;
|
||||||
|
|
||||||
class CXWindowsPrimaryScreen : public CXWindowsScreen, public IPrimaryScreen {
|
class CXWindowsPrimaryScreen : public CXWindowsScreen, public IPrimaryScreen {
|
||||||
public:
|
public:
|
||||||
CXWindowsPrimaryScreen();
|
CXWindowsPrimaryScreen(IPrimaryReceiver*);
|
||||||
virtual ~CXWindowsPrimaryScreen();
|
virtual ~CXWindowsPrimaryScreen();
|
||||||
|
|
||||||
// IPrimaryScreen overrides
|
// IPrimaryScreen overrides
|
||||||
virtual void run();
|
virtual void run();
|
||||||
virtual void stop();
|
virtual void stop();
|
||||||
virtual void open(CServer*);
|
virtual void open();
|
||||||
virtual void close();
|
virtual void close();
|
||||||
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute, bool);
|
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute, bool);
|
||||||
virtual bool leave();
|
virtual bool leave();
|
||||||
virtual void onConfigure();
|
virtual void reconfigure();
|
||||||
virtual void warpCursor(SInt32 xAbsolute, SInt32 yAbsolute);
|
virtual void warpCursor(SInt32 xAbsolute, SInt32 yAbsolute);
|
||||||
virtual void setClipboard(ClipboardID, const IClipboard*);
|
virtual void setClipboard(ClipboardID, const IClipboard*);
|
||||||
virtual void grabClipboard(ClipboardID);
|
virtual void grabClipboard(ClipboardID);
|
||||||
virtual void getShape(SInt32&, SInt32&, SInt32&, SInt32&) const;
|
|
||||||
virtual SInt32 getJumpZoneSize() const;
|
|
||||||
virtual void getClipboard(ClipboardID, IClipboard*) const;
|
virtual void getClipboard(ClipboardID, IClipboard*) const;
|
||||||
virtual KeyModifierMask getToggleMask() const;
|
virtual KeyModifierMask getToggleMask() const;
|
||||||
virtual bool isLockedToScreen() const;
|
virtual bool isLockedToScreen() const;
|
||||||
virtual bool isScreenSaverActive() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// CXWindowsScreen overrides
|
// CXWindowsScreen overrides
|
||||||
|
@ -61,7 +60,7 @@ private:
|
||||||
static Bool findKeyEvent(Display*, XEvent* xevent, XPointer arg);
|
static Bool findKeyEvent(Display*, XEvent* xevent, XPointer arg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CServer* m_server;
|
IPrimaryReceiver* m_receiver;
|
||||||
bool m_active;
|
bool m_active;
|
||||||
Window m_window;
|
Window m_window;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef IPRIMARYRECEIVER_H
|
||||||
|
#define IPRIMARYRECEIVER_H
|
||||||
|
|
||||||
|
#include "IInterface.h"
|
||||||
|
#include "ClipboardTypes.h"
|
||||||
|
#include "KeyTypes.h"
|
||||||
|
#include "MouseTypes.h"
|
||||||
|
#include "CString.h"
|
||||||
|
|
||||||
|
class IPrimaryReceiver : public IInterface {
|
||||||
|
public:
|
||||||
|
// manipulators
|
||||||
|
|
||||||
|
// notify of serious error. this implies that the primary screen
|
||||||
|
// cannot continue to function.
|
||||||
|
virtual void onError() = 0;
|
||||||
|
|
||||||
|
// notify of info change
|
||||||
|
virtual void onInfoChanged(SInt32 xScreen, SInt32 yScreen,
|
||||||
|
SInt32 wScreen, SInt32 hScreen,
|
||||||
|
SInt32 zoneSize,
|
||||||
|
SInt32 xMouse, SInt32 yMouse) = 0;
|
||||||
|
|
||||||
|
// notify of clipboard grab. returns true if the grab was honored,
|
||||||
|
// false otherwise.
|
||||||
|
virtual bool onGrabClipboard(ClipboardID) = 0;
|
||||||
|
|
||||||
|
// notify of new clipboard data. returns true if the clipboard data
|
||||||
|
// was accepted, false if the change was rejected.
|
||||||
|
virtual bool onClipboardChanged(ClipboardID,
|
||||||
|
const CString& data) = 0;
|
||||||
|
|
||||||
|
// call to notify of events. onMouseMovePrimary() returns
|
||||||
|
// true iff the mouse enters a jump zone and jumps.
|
||||||
|
virtual void onKeyDown(KeyID, KeyModifierMask) = 0;
|
||||||
|
virtual void onKeyUp(KeyID, KeyModifierMask) = 0;
|
||||||
|
virtual void onKeyRepeat(KeyID, KeyModifierMask, SInt32 count) = 0;
|
||||||
|
virtual void onMouseDown(ButtonID) = 0;
|
||||||
|
virtual void onMouseUp(ButtonID) = 0;
|
||||||
|
virtual bool onMouseMovePrimary(SInt32 x, SInt32 y) = 0;
|
||||||
|
virtual void onMouseMoveSecondary(SInt32 dx, SInt32 dy) = 0;
|
||||||
|
virtual void onMouseWheel(SInt32 delta) = 0;
|
||||||
|
virtual void onScreenSaver(bool activated) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -5,7 +5,6 @@
|
||||||
#include "KeyTypes.h"
|
#include "KeyTypes.h"
|
||||||
#include "ClipboardTypes.h"
|
#include "ClipboardTypes.h"
|
||||||
|
|
||||||
class CServer;
|
|
||||||
class IClipboard;
|
class IClipboard;
|
||||||
|
|
||||||
class IPrimaryScreen : public IInterface {
|
class IPrimaryScreen : public IInterface {
|
||||||
|
@ -21,7 +20,8 @@ public:
|
||||||
// cause run() to return
|
// cause run() to return
|
||||||
virtual void stop() = 0;
|
virtual void stop() = 0;
|
||||||
|
|
||||||
// initialize the screen and start reporting events to the server.
|
// initialize the screen and start reporting events to the receiver
|
||||||
|
// (which is set through some interface of the derived class).
|
||||||
// events should be reported no matter where on the screen they
|
// events should be reported no matter where on the screen they
|
||||||
// occur but do not interfere with normal event dispatch. the
|
// occur but do not interfere with normal event dispatch. the
|
||||||
// screen saver engaging should be reported as an event. if that
|
// screen saver engaging should be reported as an event. if that
|
||||||
|
@ -29,10 +29,11 @@ public:
|
||||||
// screen saver timer and should start the screen saver after
|
// screen saver timer and should start the screen saver after
|
||||||
// idling for an appropriate time.
|
// idling for an appropriate time.
|
||||||
//
|
//
|
||||||
// open() must call server->setInfo() to notify the server of the
|
// open() must call receiver->onInfoChanged() to notify of the
|
||||||
// primary screen's resolution and jump zone size. the mouse
|
// primary screen's initial resolution and jump zone size. it
|
||||||
// position is ignored and may be 0,0.
|
// must also call receiver->onClipboardChanged() for each
|
||||||
virtual void open(CServer* server) = 0;
|
// clipboard that the primary screen has.
|
||||||
|
virtual void open() = 0;
|
||||||
|
|
||||||
// close the screen. should restore the screen saver timer if it
|
// close the screen. should restore the screen saver timer if it
|
||||||
// was disabled.
|
// was disabled.
|
||||||
|
@ -44,24 +45,30 @@ public:
|
||||||
// call to leave() which preceeds it, however the screen should
|
// call to leave() which preceeds it, however the screen should
|
||||||
// assume an implicit call to enter() in the call to open().
|
// assume an implicit call to enter() in the call to open().
|
||||||
// if warpCursor is false then do not warp the mouse.
|
// if warpCursor is false then do not warp the mouse.
|
||||||
|
//
|
||||||
|
// enter() must not call any receiver methods except onError().
|
||||||
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute,
|
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute,
|
||||||
bool forScreenSaver) = 0;
|
bool forScreenSaver) = 0;
|
||||||
|
|
||||||
// called when the user navigates off the primary screen. hide
|
// called when the user navigates off the primary screen. hide the
|
||||||
// the cursor and grab exclusive access to the input devices.
|
// cursor and grab exclusive access to the input devices. return
|
||||||
// return true iff successful.
|
// true iff successful.
|
||||||
|
//
|
||||||
|
// leave() must not call any receiver methods except onError().
|
||||||
virtual bool leave() = 0;
|
virtual bool leave() = 0;
|
||||||
|
|
||||||
// called when the configuration has changed. subclasses may need
|
// called when the configuration has changed. subclasses may need
|
||||||
// to adjust things (like the jump zones) after the configuration
|
// to adjust things (like the jump zones) after the configuration
|
||||||
// changes.
|
// changes.
|
||||||
virtual void onConfigure() = 0;
|
virtual void reconfigure() = 0;
|
||||||
|
|
||||||
// warp the cursor to the given position
|
// warp the cursor to the given position
|
||||||
virtual void warpCursor(SInt32 xAbsolute, SInt32 yAbsolute) = 0;
|
virtual void warpCursor(SInt32 xAbsolute, SInt32 yAbsolute) = 0;
|
||||||
|
|
||||||
// set the screen's clipboard contents. this is usually called
|
// set the screen's clipboard contents. this is usually called
|
||||||
// soon after an enter().
|
// soon after an enter().
|
||||||
|
//
|
||||||
|
// setClipboard() must not call any receiver methods except onError().
|
||||||
virtual void setClipboard(ClipboardID, const IClipboard*) = 0;
|
virtual void setClipboard(ClipboardID, const IClipboard*) = 0;
|
||||||
|
|
||||||
// synergy should own the clipboard
|
// synergy should own the clipboard
|
||||||
|
@ -69,16 +76,9 @@ public:
|
||||||
|
|
||||||
// accessors
|
// accessors
|
||||||
|
|
||||||
// get the screen region
|
// return the contents of the given clipboard.
|
||||||
virtual void getShape(SInt32& x, SInt32& y,
|
//
|
||||||
SInt32& width, SInt32& height) const = 0;
|
// getClipboard() must not call any receiver methods except onError().
|
||||||
|
|
||||||
// get the size of jump zone
|
|
||||||
virtual SInt32 getJumpZoneSize() const = 0;
|
|
||||||
|
|
||||||
// get the screen's clipboard contents. the implementation can
|
|
||||||
// and should avoid setting the clipboard object if the screen's
|
|
||||||
// clipboard hasn't changed.
|
|
||||||
virtual void getClipboard(ClipboardID, IClipboard*) const = 0;
|
virtual void getClipboard(ClipboardID, IClipboard*) const = 0;
|
||||||
|
|
||||||
// get the primary screen's current toggle modifier key state.
|
// get the primary screen's current toggle modifier key state.
|
||||||
|
@ -90,9 +90,6 @@ public:
|
||||||
// any other reason that the user should not be allowed to switch
|
// any other reason that the user should not be allowed to switch
|
||||||
// screens.
|
// screens.
|
||||||
virtual bool isLockedToScreen() const = 0;
|
virtual bool isLockedToScreen() const = 0;
|
||||||
|
|
||||||
// return true if the screen saver is activated
|
|
||||||
virtual bool isScreenSaverActive() const = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
#ifndef ISERVERPROTOCOL_H
|
|
||||||
#define ISERVERPROTOCOL_H
|
|
||||||
|
|
||||||
#include "IInterface.h"
|
|
||||||
#include "ClipboardTypes.h"
|
|
||||||
#include "KeyTypes.h"
|
|
||||||
#include "MouseTypes.h"
|
|
||||||
#include "CString.h"
|
|
||||||
|
|
||||||
class IClipboard;
|
|
||||||
|
|
||||||
class IServerProtocol : public IInterface {
|
|
||||||
public:
|
|
||||||
// manipulators
|
|
||||||
|
|
||||||
// process messages from the client and insert the appropriate
|
|
||||||
// events into the server's event queue. return when the client
|
|
||||||
// disconnects.
|
|
||||||
virtual void run() = 0;
|
|
||||||
|
|
||||||
// send client info query and process reply
|
|
||||||
virtual void queryInfo() = 0;
|
|
||||||
|
|
||||||
// send various messages to client
|
|
||||||
virtual void sendClose() = 0;
|
|
||||||
virtual void sendEnter(SInt32 xAbs, SInt32 yAbs,
|
|
||||||
UInt32 seqNum, KeyModifierMask mask) = 0;
|
|
||||||
virtual void sendLeave() = 0;
|
|
||||||
virtual void sendClipboard(ClipboardID, const CString&) = 0;
|
|
||||||
virtual void sendGrabClipboard(ClipboardID) = 0;
|
|
||||||
virtual void sendScreenSaver(bool on) = 0;
|
|
||||||
virtual void sendInfoAcknowledgment() = 0;
|
|
||||||
virtual void sendKeyDown(KeyID, KeyModifierMask) = 0;
|
|
||||||
virtual void sendKeyRepeat(KeyID, KeyModifierMask, SInt32 count) = 0;
|
|
||||||
virtual void sendKeyUp(KeyID, KeyModifierMask) = 0;
|
|
||||||
virtual void sendMouseDown(ButtonID) = 0;
|
|
||||||
virtual void sendMouseUp(ButtonID) = 0;
|
|
||||||
virtual void sendMouseMove(SInt32 xAbs, SInt32 yAbs) = 0;
|
|
||||||
virtual void sendMouseWheel(SInt32 delta) = 0;
|
|
||||||
|
|
||||||
// accessors
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// manipulators
|
|
||||||
|
|
||||||
virtual void recvInfo() = 0;
|
|
||||||
virtual void recvClipboard() = 0;
|
|
||||||
virtual void recvGrabClipboard() = 0;
|
|
||||||
|
|
||||||
// accessors
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -4,20 +4,23 @@ DEPTH = ..
|
||||||
|
|
||||||
bin_PROGRAMS = synergyd
|
bin_PROGRAMS = synergyd
|
||||||
synergyd_SOURCES = \
|
synergyd_SOURCES = \
|
||||||
|
CClientProxy.cpp \
|
||||||
|
CClientProxy1_0.cpp \
|
||||||
CConfig.cpp \
|
CConfig.cpp \
|
||||||
CServerProtocol.cpp \
|
|
||||||
CServerProtocol1_0.cpp \
|
|
||||||
CXWindowsPrimaryScreen.cpp \
|
|
||||||
CServer.cpp \
|
|
||||||
CHTTPServer.cpp \
|
CHTTPServer.cpp \
|
||||||
|
CPrimaryClient.cpp \
|
||||||
|
CServer.cpp \
|
||||||
|
CXWindowsPrimaryScreen.cpp \
|
||||||
server.cpp \
|
server.cpp \
|
||||||
|
CClientProxy.h \
|
||||||
|
CClientProxy1_0.h \
|
||||||
CConfig.h \
|
CConfig.h \
|
||||||
CHTTPServer.h \
|
CHTTPServer.h \
|
||||||
|
CPrimaryClient.h \
|
||||||
CServer.h \
|
CServer.h \
|
||||||
CServerProtocol.h \
|
|
||||||
CServerProtocol1_0.h \
|
|
||||||
CSynergyHook.h \
|
|
||||||
CXWindowsPrimaryScreen.h \
|
CXWindowsPrimaryScreen.h \
|
||||||
|
IPrimaryReceiver.h \
|
||||||
|
IPrimaryScreen.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
synergyd_LDADD = \
|
synergyd_LDADD = \
|
||||||
$(DEPTH)/platform/libplatform.a \
|
$(DEPTH)/platform/libplatform.a \
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
#ifndef ICLIENT_H
|
||||||
|
#define ICLIENT_H
|
||||||
|
|
||||||
|
#include "IInterface.h"
|
||||||
|
#include "ClipboardTypes.h"
|
||||||
|
#include "KeyTypes.h"
|
||||||
|
#include "MouseTypes.h"
|
||||||
|
#include "CString.h"
|
||||||
|
|
||||||
|
class IClient : public IInterface {
|
||||||
|
public:
|
||||||
|
// manipulators
|
||||||
|
|
||||||
|
// open client
|
||||||
|
virtual void open() = 0;
|
||||||
|
|
||||||
|
// service client
|
||||||
|
virtual void run() = 0;
|
||||||
|
|
||||||
|
// close client
|
||||||
|
virtual void close() = 0;
|
||||||
|
|
||||||
|
// enter the screen. the cursor should be warped to xAbs,yAbs.
|
||||||
|
// the client should record seqNum for future reporting of
|
||||||
|
// clipboard changes. mask is the expected toggle button state.
|
||||||
|
// screenSaver is true if the screen is being entered because
|
||||||
|
// the screen saver is starting.
|
||||||
|
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
||||||
|
UInt32 seqNum, KeyModifierMask mask,
|
||||||
|
bool screenSaver) = 0;
|
||||||
|
|
||||||
|
// leave the screen. returns false if the user may not leave the
|
||||||
|
// client's screen.
|
||||||
|
virtual bool leave() = 0;
|
||||||
|
|
||||||
|
// FIXME -- methods for setting clipboard. on proxy side these
|
||||||
|
// will set/reset the gotClipboard flag and send the clipboard
|
||||||
|
// when not gotClipboard is false. grabbing goes in here too.
|
||||||
|
// basically, figure out semantics of these methods. note that
|
||||||
|
// ISecondaryScreen wants an IClipboard* passed to set not a
|
||||||
|
// string; will that be a problem?
|
||||||
|
|
||||||
|
// update the client's clipboard. this implies that the client's
|
||||||
|
// clipboard is now up to date. if the client's clipboard was
|
||||||
|
// already known to be up to date then this can do nothing.
|
||||||
|
virtual void setClipboard(ClipboardID, const CString&) = 0;
|
||||||
|
|
||||||
|
// grab the client's clipboard. since this is called when another
|
||||||
|
// client takes ownership of the clipboard it implies that the
|
||||||
|
// client's clipboard is dirty.
|
||||||
|
virtual void grabClipboard(ClipboardID) = 0;
|
||||||
|
|
||||||
|
// called to set the client's clipboard as dirty or clean
|
||||||
|
virtual void setClipboardDirty(ClipboardID, bool dirty) = 0;
|
||||||
|
|
||||||
|
// handle input events
|
||||||
|
virtual void keyDown(KeyID, KeyModifierMask) = 0;
|
||||||
|
virtual void keyRepeat(KeyID, KeyModifierMask, SInt32 count) = 0;
|
||||||
|
virtual void keyUp(KeyID, KeyModifierMask) = 0;
|
||||||
|
virtual void mouseDown(ButtonID) = 0;
|
||||||
|
virtual void mouseUp(ButtonID) = 0;
|
||||||
|
// FIXME -- if server uses IClient as interface to primary screen
|
||||||
|
// (should this class be renamed?) then be careful of absolute/relative
|
||||||
|
// coordinates here; move on primary and move on secondary take
|
||||||
|
// different values. probably not relevant, though.
|
||||||
|
virtual void mouseMove(SInt32 xAbs, SInt32 yAbs) = 0;
|
||||||
|
virtual void mouseWheel(SInt32 delta) = 0;
|
||||||
|
virtual void screenSaver(bool activate) = 0;
|
||||||
|
|
||||||
|
// accessors
|
||||||
|
|
||||||
|
// get the client's identifier
|
||||||
|
virtual CString getName() const = 0;
|
||||||
|
|
||||||
|
// get the screen's shape
|
||||||
|
// FIXME -- may want center pixel too
|
||||||
|
virtual void getShape(SInt32& x, SInt32& y,
|
||||||
|
SInt32& width, SInt32& height) const = 0;
|
||||||
|
|
||||||
|
// get the center pixel
|
||||||
|
virtual void getCenter(SInt32& x, SInt32& y) const = 0;
|
||||||
|
|
||||||
|
// get the size of jump zone
|
||||||
|
virtual SInt32 getJumpZoneSize() const = 0;
|
||||||
|
|
||||||
|
// what about getClipboard()? don't really want proxy to ask for it;
|
||||||
|
// it's a push data model. screen info is cached in proxy so it's
|
||||||
|
// different. will need to keep onClipboardChanged() in CClient.
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef ISERVER_H
|
||||||
|
#define ISERVER_H
|
||||||
|
|
||||||
|
#include "IInterface.h"
|
||||||
|
#include "ClipboardTypes.h"
|
||||||
|
#include "KeyTypes.h"
|
||||||
|
#include "MouseTypes.h"
|
||||||
|
#include "CString.h"
|
||||||
|
|
||||||
|
class IServer : public IInterface {
|
||||||
|
public:
|
||||||
|
// manipulators
|
||||||
|
|
||||||
|
// notify of serious error. this implies that the server should
|
||||||
|
// shutdown.
|
||||||
|
virtual void onError() = 0;
|
||||||
|
|
||||||
|
// notify of client info change (maybe IClient should be named IScreen)
|
||||||
|
virtual void onInfoChanged(const CString& clientName) = 0;
|
||||||
|
|
||||||
|
// notify of clipboard grab. returns true if the grab was honored,
|
||||||
|
// false otherwise.
|
||||||
|
virtual bool onGrabClipboard(ClipboardID,
|
||||||
|
UInt32 seqNum, const CString& clientName) = 0;
|
||||||
|
|
||||||
|
// notify of new clipboard data
|
||||||
|
virtual void onClipboardChanged(ClipboardID,
|
||||||
|
UInt32 seqNum, const CString& data) = 0;
|
||||||
|
|
||||||
|
// call to notify of events. onMouseMovePrimary() returns
|
||||||
|
// true iff the mouse enters a jump zone and jumps.
|
||||||
|
virtual void onKeyDown(KeyID, KeyModifierMask) = 0;
|
||||||
|
virtual void onKeyUp(KeyID, KeyModifierMask) = 0;
|
||||||
|
virtual void onKeyRepeat(KeyID, KeyModifierMask, SInt32 count) = 0;
|
||||||
|
virtual void onMouseDown(ButtonID) = 0;
|
||||||
|
virtual void onMouseUp(ButtonID) = 0;
|
||||||
|
virtual bool onMouseMovePrimary(SInt32 x, SInt32 y) = 0;
|
||||||
|
virtual void onMouseMoveSecondary(SInt32 dx, SInt32 dy) = 0;
|
||||||
|
virtual void onMouseWheel(SInt32 delta) = 0;
|
||||||
|
virtual void onScreenSaver(bool activated) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -17,10 +17,11 @@ libsynergy_a_SOURCES = \
|
||||||
CProtocolUtil.h \
|
CProtocolUtil.h \
|
||||||
CTCPSocketFactory.h \
|
CTCPSocketFactory.h \
|
||||||
ClipboardTypes.h \
|
ClipboardTypes.h \
|
||||||
|
IClient.h \
|
||||||
IClipboard.h \
|
IClipboard.h \
|
||||||
IScreenSaver.h \
|
IScreenSaver.h \
|
||||||
ISecondaryScreen.h \
|
ISecondaryScreen.h \
|
||||||
IServerProtocol.h \
|
IServer.h \
|
||||||
ISocketFactory.h \
|
ISocketFactory.h \
|
||||||
KeyTypes.h \
|
KeyTypes.h \
|
||||||
MouseTypes.h \
|
MouseTypes.h \
|
||||||
|
|
Loading…
Reference in New Issue