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
|
||||
# Common stub for a few missing GNU programs while installing.
|
||||
# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
# Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
|
||||
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# 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
|
||||
|
@ -18,11 +18,37 @@
|
|||
# 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.
|
||||
|
||||
if test $# -eq 0; then
|
||||
echo 1>&2 "Try \`$0 --help' for more information"
|
||||
exit 1
|
||||
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
|
||||
|
||||
-h|--h|--he|--hel|--help)
|
||||
|
@ -35,6 +61,7 @@ error status if there is no known handling for PROGRAM.
|
|||
Options:
|
||||
-h, --help display this help 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:
|
||||
aclocal touch file \`aclocal.m4'
|
||||
|
@ -43,13 +70,15 @@ Supported PROGRAM values:
|
|||
automake touch all \`Makefile.in' files
|
||||
bison create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||
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
|
||||
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]"
|
||||
;;
|
||||
|
||||
-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)
|
||||
echo 1>&2 "\
|
||||
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
|
||||
any GNU archive site."
|
||||
touch aclocal.m4
|
||||
|
@ -70,7 +99,7 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
|||
autoconf)
|
||||
echo 1>&2 "\
|
||||
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
|
||||
archive site."
|
||||
touch configure
|
||||
|
@ -79,10 +108,10 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
|||
autoheader)
|
||||
echo 1>&2 "\
|
||||
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
|
||||
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"
|
||||
touch_files=
|
||||
for f in $files; do
|
||||
|
@ -98,7 +127,7 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
|||
automake)
|
||||
echo 1>&2 "\
|
||||
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.
|
||||
Grab them from any GNU archive site."
|
||||
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
|
||||
;;
|
||||
|
||||
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)
|
||||
if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
|
||||
# We have makeinfo, but it failed.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
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
|
||||
;;
|
||||
|
||||
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 "\
|
||||
WARNING: \`$1' is needed, and you do not seem to have it handy on your
|
||||
|
|
|
@ -127,8 +127,7 @@ CThread::getResult() const
|
|||
void*
|
||||
CThread::getUserData()
|
||||
{
|
||||
CThreadPtr currentRep(CThreadRep::getCurrentThreadRep());
|
||||
return currentRep->getUserData();
|
||||
return m_rep->getUserData();
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -88,15 +88,14 @@ public:
|
|||
// return a thread object representing the calling thread
|
||||
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
|
||||
// this to make a function itself a cancellation point.
|
||||
// (cancellation point)
|
||||
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
|
||||
// by returning from the thread job). returns immediately if
|
||||
// the thread has already terminated. returns immediately with
|
||||
|
|
109
notes
109
notes
|
@ -7,16 +7,27 @@ hangup if invalid
|
|||
query info -->
|
||||
<-- 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
|
||||
should either ship with it fully enabled or fully disabled
|
||||
possibly make it part of startup negotiation
|
||||
|
||||
---
|
||||
sometimes jumping too far into secondary 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
|
||||
getting a stuttering when leaving win32 server screen
|
||||
|
||||
---
|
||||
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
|
||||
|
@ -33,20 +44,59 @@ HTTP stuff
|
|||
handy for debugging at least
|
||||
|
||||
---
|
||||
make generic input devices?
|
||||
replace mouse and keyboard with button and valuator devices?
|
||||
could fairly easily add new devices then
|
||||
valuators would have to come in groups that change together
|
||||
mouse position would be two ganged valuators
|
||||
key events are not simply button presses though
|
||||
they have a non-boolean character, shift state, and repeat count
|
||||
maybe another device type: {data, state, repeat}
|
||||
negotiation:
|
||||
use a generic negotiation message (name/value pair) or specific
|
||||
messages (name/values)? later allows more parsing to be done by
|
||||
CProtocolUtil but how can we skip unknown messages? would have
|
||||
to have a method on CInputPacketStream to discard to end of
|
||||
message and we'd need to know the stream is a CInputPacketStream.
|
||||
|
||||
must handle on-the-fly addition/removal of devices
|
||||
USB allows hotplugging and we should support, say, an added joystick
|
||||
how does negotiation proceed?
|
||||
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
|
||||
at very least it negotiates mouse/keyboard at start
|
||||
example: clipboard formats:
|
||||
# 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
|
||||
|
@ -72,6 +122,28 @@ allows compatibility with versions that are identical except for
|
|||
the support clipboard formats, obviating bumping up the protocol
|
||||
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
|
||||
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
|
||||
otherwise it cannot know when to stop the screen saver
|
||||
cos it can't grab mouse and keyboard
|
||||
|
||||
---
|
||||
all screensavers hidden when showing win32 screensaver 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
|
||||
cross over...
|
||||
|
||||
gspencer:
|
||||
bouncy mouse at edge of screen (win32 server). almost certainly
|
||||
related to changes that fixed mouse delta calculation.
|
||||
|
||||
|
||||
== fixed? ===
|
||||
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)
|
||||
Window lockOwner = XGetSelectionOwner(m_display, m_atomMotifClipLock);
|
||||
if (lockOwner != None) {
|
||||
log((CLOG_DEBUG1 "motif lock owner 0x%08x", lockOwner));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -536,6 +537,7 @@ CXWindowsClipboard::motifLockClipboard() const
|
|||
XSetSelectionOwner(m_display, m_atomMotifClipLock, m_window, time);
|
||||
lockOwner = XGetSelectionOwner(m_display, m_atomMotifClipLock);
|
||||
if (lockOwner != m_window) {
|
||||
log((CLOG_DEBUG1 "motif lock owner 0x%08x", lockOwner));
|
||||
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
|
||||
#define CSERVER_H
|
||||
|
||||
#include "IServer.h"
|
||||
#include "CConfig.h"
|
||||
#include "CClipboard.h"
|
||||
#include "ClipboardTypes.h"
|
||||
|
@ -13,14 +14,17 @@
|
|||
#include "stdlist.h"
|
||||
#include "stdmap.h"
|
||||
|
||||
class CClientProxy;
|
||||
class CHTTPServer;
|
||||
class CPrimaryClient;
|
||||
class CThread;
|
||||
class IClient;
|
||||
class IDataSocket;
|
||||
class IServerProtocol;
|
||||
class ISocketFactory;
|
||||
class ISecurityFactory;
|
||||
class IPrimaryScreen;
|
||||
class CHTTPServer;
|
||||
|
||||
class CServer {
|
||||
class CServer : public IServer {
|
||||
public:
|
||||
CServer(const CString& serverName);
|
||||
~CServer();
|
||||
|
@ -38,50 +42,12 @@ public:
|
|||
// after a successful open().
|
||||
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
|
||||
// accepted.
|
||||
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
|
||||
|
||||
// returns true if the mouse should be locked to the current screen
|
||||
bool isLockedToScreen() const;
|
||||
|
||||
// get the current screen map
|
||||
void getConfig(CConfig*) const;
|
||||
|
||||
|
@ -91,64 +57,58 @@ public:
|
|||
// get the sides of the primary screen that have neighbors
|
||||
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:
|
||||
bool onCommandKey(KeyID, KeyModifierMask, bool down);
|
||||
|
||||
private:
|
||||
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];
|
||||
};
|
||||
typedef std::list<CThread> CThreadList;
|
||||
|
||||
// handle mouse motion
|
||||
bool onMouseMovePrimaryNoLock(SInt32 x, SInt32 y);
|
||||
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
|
||||
void grabClipboardNoLock(ClipboardID,
|
||||
bool grabClipboardNoLock(ClipboardID,
|
||||
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
|
||||
bool isLockedToScreenNoLock() const;
|
||||
|
||||
// change the active screen
|
||||
void switchScreen(CScreenInfo*,
|
||||
void switchScreen(IClient*,
|
||||
SInt32 x, SInt32 y, bool forScreenSaver);
|
||||
|
||||
// lookup neighboring screen
|
||||
CScreenInfo* getNeighbor(CScreenInfo*, CConfig::EDirection) const;
|
||||
IClient* getNeighbor(IClient*, CConfig::EDirection) const;
|
||||
|
||||
// lookup neighboring screen. given a position relative to the
|
||||
// source screen, find the screen we should move onto and where.
|
||||
// if the position is sufficiently far from the source then we
|
||||
// cross multiple screens. if there is no suitable screen then
|
||||
// return NULL and x,y are not modified.
|
||||
CScreenInfo* getNeighbor(CScreenInfo*,
|
||||
IClient* getNeighbor(IClient*,
|
||||
CConfig::EDirection,
|
||||
SInt32& x, SInt32& y) const;
|
||||
|
||||
|
@ -156,15 +116,13 @@ private:
|
|||
void openPrimaryScreen();
|
||||
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
|
||||
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
|
||||
void startThread(IJob* adopted);
|
||||
|
||||
|
@ -180,8 +138,9 @@ private:
|
|||
// thread method to accept incoming client connections
|
||||
void acceptClients(void*);
|
||||
|
||||
// thread method to do startup handshake with client
|
||||
void handshakeClient(void*);
|
||||
// thread method to do client interaction
|
||||
void runClient(void*);
|
||||
CClientProxy* handshakeClient(IDataSocket*);
|
||||
|
||||
// thread method to accept incoming HTTP connections
|
||||
void acceptHTTPClients(void*);
|
||||
|
@ -190,11 +149,10 @@ private:
|
|||
void processHTTPRequest(void*);
|
||||
|
||||
// connection list maintenance
|
||||
CScreenInfo* addConnection(const CString& name, IServerProtocol*);
|
||||
void addConnection(IClient*);
|
||||
void removeConnection(const CString& name);
|
||||
|
||||
private:
|
||||
typedef std::map<CString, CScreenInfo*> CScreenList;
|
||||
class CClipboardInfo {
|
||||
public:
|
||||
CClipboardInfo();
|
||||
|
@ -204,7 +162,6 @@ private:
|
|||
CString m_clipboardData;
|
||||
CString m_clipboardOwner;
|
||||
UInt32 m_clipboardSeqNum;
|
||||
bool m_clipboardReady;
|
||||
};
|
||||
|
||||
CMutex m_mutex;
|
||||
|
@ -212,6 +169,7 @@ private:
|
|||
// the name of the primary screen
|
||||
CString m_name;
|
||||
|
||||
// how long to wait to bind our socket until we give up
|
||||
double m_bindTimeout;
|
||||
|
||||
ISocketFactory* m_socketFactory;
|
||||
|
@ -221,10 +179,21 @@ private:
|
|||
CThreadList m_threads;
|
||||
|
||||
// the screens
|
||||
IPrimaryScreen* m_primary;
|
||||
CScreenList m_screens;
|
||||
CScreenInfo* m_active;
|
||||
CScreenInfo* m_primaryInfo;
|
||||
typedef std::map<CString, IClient*> CClientList;
|
||||
typedef std::map<CString, CThread> CClientThreadList;
|
||||
|
||||
// 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
|
||||
UInt32 m_seqNum;
|
||||
|
@ -239,7 +208,7 @@ private:
|
|||
CClipboardInfo m_clipboards[kClipboardEnd];
|
||||
|
||||
// state saved when screen saver activates
|
||||
CScreenInfo* m_activeSaver;
|
||||
IClient* m_activeSaver;
|
||||
SInt32 m_xSaver, m_ySaver;
|
||||
|
||||
// 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 "CServer.h"
|
||||
#include "IPrimaryReceiver.h"
|
||||
#include "CXWindowsClipboard.h"
|
||||
#include "CXWindowsScreenSaver.h"
|
||||
#include "CXWindowsUtil.h"
|
||||
#include "CClipboard.h"
|
||||
#include "CThread.h"
|
||||
#include "CLog.h"
|
||||
#include "CStopwatch.h"
|
||||
|
@ -19,8 +20,8 @@
|
|||
// CXWindowsPrimaryScreen
|
||||
//
|
||||
|
||||
CXWindowsPrimaryScreen::CXWindowsPrimaryScreen() :
|
||||
m_server(NULL),
|
||||
CXWindowsPrimaryScreen::CXWindowsPrimaryScreen(IPrimaryReceiver* receiver) :
|
||||
m_receiver(receiver),
|
||||
m_active(false),
|
||||
m_window(None)
|
||||
{
|
||||
|
@ -65,7 +66,7 @@ CXWindowsPrimaryScreen::run()
|
|||
if (xevent.xclient.message_type == m_atomScreenSaver ||
|
||||
xevent.xclient.format == 32) {
|
||||
// screen saver activation/deactivation event
|
||||
m_server->onScreenSaver(xevent.xclient.data.l[0] != 0);
|
||||
m_receiver->onScreenSaver(xevent.xclient.data.l[0] != 0);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -75,12 +76,12 @@ CXWindowsPrimaryScreen::run()
|
|||
const KeyModifierMask mask = mapModifier(xevent.xkey.state);
|
||||
const KeyID key = mapKey(&xevent.xkey);
|
||||
if (key != kKeyNone) {
|
||||
m_server->onKeyDown(key, mask);
|
||||
m_receiver->onKeyDown(key, mask);
|
||||
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) {
|
||||
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
|
||||
log((CLOG_DEBUG1 "event: KeyRelease code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
|
||||
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) {
|
||||
m_server->onKeyDown(key, mask);
|
||||
m_receiver->onKeyDown(key, mask);
|
||||
}
|
||||
m_server->onKeyUp(key, mask);
|
||||
m_receiver->onKeyUp(key, mask);
|
||||
}
|
||||
else {
|
||||
// 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.
|
||||
// note that we discard the press event.
|
||||
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));
|
||||
const ButtonID button = mapButton(xevent.xbutton.button);
|
||||
if (button != kButtonNone) {
|
||||
m_server->onMouseDown(button);
|
||||
m_receiver->onMouseDown(button);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -144,15 +145,15 @@ CXWindowsPrimaryScreen::run()
|
|||
log((CLOG_DEBUG1 "event: ButtonRelease button=%d", xevent.xbutton.button));
|
||||
const ButtonID button = mapButton(xevent.xbutton.button);
|
||||
if (button != kButtonNone) {
|
||||
m_server->onMouseUp(button);
|
||||
m_receiver->onMouseUp(button);
|
||||
}
|
||||
else if (xevent.xbutton.button == 4) {
|
||||
// wheel forward (away from user)
|
||||
m_server->onMouseWheel(120);
|
||||
m_receiver->onMouseWheel(120);
|
||||
}
|
||||
else if (xevent.xbutton.button == 5) {
|
||||
// wheel backward (toward user)
|
||||
m_server->onMouseWheel(-120);
|
||||
m_receiver->onMouseWheel(-120);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -183,7 +184,7 @@ CXWindowsPrimaryScreen::run()
|
|||
}
|
||||
else if (!m_active) {
|
||||
// motion on primary screen
|
||||
m_server->onMouseMovePrimary(m_x, m_y);
|
||||
m_receiver->onMouseMovePrimary(m_x, m_y);
|
||||
}
|
||||
else {
|
||||
// motion on secondary screen. warp mouse back to
|
||||
|
@ -214,7 +215,7 @@ CXWindowsPrimaryScreen::run()
|
|||
// warping to the primary screen's enter position,
|
||||
// effectively overriding it.
|
||||
if (x != 0 || y != 0) {
|
||||
m_server->onMouseMoveSecondary(x, y);
|
||||
m_receiver->onMouseMoveSecondary(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -231,17 +232,11 @@ CXWindowsPrimaryScreen::stop()
|
|||
}
|
||||
|
||||
void
|
||||
CXWindowsPrimaryScreen::open(CServer* server)
|
||||
CXWindowsPrimaryScreen::open()
|
||||
{
|
||||
assert(m_server == NULL);
|
||||
assert(server != NULL);
|
||||
|
||||
// open the display
|
||||
openDisplay();
|
||||
|
||||
// set the server
|
||||
m_server = server;
|
||||
|
||||
// check for peculiarities
|
||||
// FIXME -- may have to get these from some database
|
||||
m_numLockHalfDuplex = false;
|
||||
|
@ -283,23 +278,18 @@ CXWindowsPrimaryScreen::open(CServer* server)
|
|||
m_yCenter = y + (h >> 1);
|
||||
|
||||
// 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
|
||||
CXWindowsPrimaryScreen::close()
|
||||
{
|
||||
assert(m_server != NULL);
|
||||
|
||||
// stop being notified of screen saver activation/deactivation
|
||||
getScreenSaver()->setNotify(None);
|
||||
m_atomScreenSaver = None;
|
||||
|
||||
// close the display
|
||||
closeDisplay();
|
||||
|
||||
// done with server
|
||||
m_server = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -394,7 +384,7 @@ CXWindowsPrimaryScreen::leave()
|
|||
}
|
||||
|
||||
void
|
||||
CXWindowsPrimaryScreen::onConfigure()
|
||||
CXWindowsPrimaryScreen::reconfigure()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
@ -475,19 +465,6 @@ CXWindowsPrimaryScreen::grabClipboard(ClipboardID id)
|
|||
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
|
||||
CXWindowsPrimaryScreen::getClipboard(ClipboardID id,
|
||||
IClipboard* clipboard) const
|
||||
|
@ -555,13 +532,6 @@ CXWindowsPrimaryScreen::isLockedToScreen() const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CXWindowsPrimaryScreen::isScreenSaverActive() const
|
||||
{
|
||||
CDisplayLock display(this);
|
||||
return getScreenSaver()->isActive();
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsPrimaryScreen::onOpenDisplay(Display* display)
|
||||
{
|
||||
|
@ -616,16 +586,14 @@ void
|
|||
CXWindowsPrimaryScreen::onUnexpectedClose()
|
||||
{
|
||||
// tell server to shutdown
|
||||
if (m_server != NULL) {
|
||||
m_server->shutdown();
|
||||
}
|
||||
m_receiver->onError();
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsPrimaryScreen::onLostClipboard(ClipboardID id)
|
||||
{
|
||||
// tell server that the clipboard was grabbed locally
|
||||
m_server->grabClipboard(id);
|
||||
m_receiver->onGrabClipboard(id);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -5,28 +5,27 @@
|
|||
#include "IPrimaryScreen.h"
|
||||
#include "MouseTypes.h"
|
||||
|
||||
class IPrimaryReceiver;
|
||||
|
||||
class CXWindowsPrimaryScreen : public CXWindowsScreen, public IPrimaryScreen {
|
||||
public:
|
||||
CXWindowsPrimaryScreen();
|
||||
CXWindowsPrimaryScreen(IPrimaryReceiver*);
|
||||
virtual ~CXWindowsPrimaryScreen();
|
||||
|
||||
// IPrimaryScreen overrides
|
||||
virtual void run();
|
||||
virtual void stop();
|
||||
virtual void open(CServer*);
|
||||
virtual void open();
|
||||
virtual void close();
|
||||
virtual void enter(SInt32 xAbsolute, SInt32 yAbsolute, bool);
|
||||
virtual bool leave();
|
||||
virtual void onConfigure();
|
||||
virtual void reconfigure();
|
||||
virtual void warpCursor(SInt32 xAbsolute, SInt32 yAbsolute);
|
||||
virtual void setClipboard(ClipboardID, const IClipboard*);
|
||||
virtual void grabClipboard(ClipboardID);
|
||||
virtual void getShape(SInt32&, SInt32&, SInt32&, SInt32&) const;
|
||||
virtual SInt32 getJumpZoneSize() const;
|
||||
virtual void getClipboard(ClipboardID, IClipboard*) const;
|
||||
virtual KeyModifierMask getToggleMask() const;
|
||||
virtual bool isLockedToScreen() const;
|
||||
virtual bool isScreenSaverActive() const;
|
||||
|
||||
protected:
|
||||
// CXWindowsScreen overrides
|
||||
|
@ -61,7 +60,7 @@ private:
|
|||
static Bool findKeyEvent(Display*, XEvent* xevent, XPointer arg);
|
||||
|
||||
private:
|
||||
CServer* m_server;
|
||||
IPrimaryReceiver* m_receiver;
|
||||
bool m_active;
|
||||
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 "ClipboardTypes.h"
|
||||
|
||||
class CServer;
|
||||
class IClipboard;
|
||||
|
||||
class IPrimaryScreen : public IInterface {
|
||||
|
@ -21,7 +20,8 @@ public:
|
|||
// cause run() to return
|
||||
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
|
||||
// occur but do not interfere with normal event dispatch. the
|
||||
// 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
|
||||
// idling for an appropriate time.
|
||||
//
|
||||
// open() must call server->setInfo() to notify the server of the
|
||||
// primary screen's resolution and jump zone size. the mouse
|
||||
// position is ignored and may be 0,0.
|
||||
virtual void open(CServer* server) = 0;
|
||||
// open() must call receiver->onInfoChanged() to notify of the
|
||||
// primary screen's initial resolution and jump zone size. it
|
||||
// must also call receiver->onClipboardChanged() for each
|
||||
// clipboard that the primary screen has.
|
||||
virtual void open() = 0;
|
||||
|
||||
// close the screen. should restore the screen saver timer if it
|
||||
// was disabled.
|
||||
|
@ -44,24 +45,30 @@ public:
|
|||
// call to leave() which preceeds it, however the screen should
|
||||
// assume an implicit call to enter() in the call to open().
|
||||
// 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,
|
||||
bool forScreenSaver) = 0;
|
||||
|
||||
// called when the user navigates off the primary screen. hide
|
||||
// the cursor and grab exclusive access to the input devices.
|
||||
// return true iff successful.
|
||||
// called when the user navigates off the primary screen. hide the
|
||||
// cursor and grab exclusive access to the input devices. return
|
||||
// true iff successful.
|
||||
//
|
||||
// leave() must not call any receiver methods except onError().
|
||||
virtual bool leave() = 0;
|
||||
|
||||
// called when the configuration has changed. subclasses may need
|
||||
// to adjust things (like the jump zones) after the configuration
|
||||
// changes.
|
||||
virtual void onConfigure() = 0;
|
||||
virtual void reconfigure() = 0;
|
||||
|
||||
// warp the cursor to the given position
|
||||
virtual void warpCursor(SInt32 xAbsolute, SInt32 yAbsolute) = 0;
|
||||
|
||||
// set the screen's clipboard contents. this is usually called
|
||||
// soon after an enter().
|
||||
//
|
||||
// setClipboard() must not call any receiver methods except onError().
|
||||
virtual void setClipboard(ClipboardID, const IClipboard*) = 0;
|
||||
|
||||
// synergy should own the clipboard
|
||||
|
@ -69,16 +76,9 @@ public:
|
|||
|
||||
// accessors
|
||||
|
||||
// get the screen region
|
||||
virtual void getShape(SInt32& x, SInt32& y,
|
||||
SInt32& width, SInt32& height) const = 0;
|
||||
|
||||
// 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.
|
||||
// return the contents of the given clipboard.
|
||||
//
|
||||
// getClipboard() must not call any receiver methods except onError().
|
||||
virtual void getClipboard(ClipboardID, IClipboard*) const = 0;
|
||||
|
||||
// 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
|
||||
// screens.
|
||||
virtual bool isLockedToScreen() const = 0;
|
||||
|
||||
// return true if the screen saver is activated
|
||||
virtual bool isScreenSaverActive() const = 0;
|
||||
};
|
||||
|
||||
#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
|
||||
synergyd_SOURCES = \
|
||||
CClientProxy.cpp \
|
||||
CClientProxy1_0.cpp \
|
||||
CConfig.cpp \
|
||||
CServerProtocol.cpp \
|
||||
CServerProtocol1_0.cpp \
|
||||
CXWindowsPrimaryScreen.cpp \
|
||||
CServer.cpp \
|
||||
CHTTPServer.cpp \
|
||||
CPrimaryClient.cpp \
|
||||
CServer.cpp \
|
||||
CXWindowsPrimaryScreen.cpp \
|
||||
server.cpp \
|
||||
CClientProxy.h \
|
||||
CClientProxy1_0.h \
|
||||
CConfig.h \
|
||||
CHTTPServer.h \
|
||||
CPrimaryClient.h \
|
||||
CServer.h \
|
||||
CServerProtocol.h \
|
||||
CServerProtocol1_0.h \
|
||||
CSynergyHook.h \
|
||||
CXWindowsPrimaryScreen.h \
|
||||
IPrimaryReceiver.h \
|
||||
IPrimaryScreen.h \
|
||||
$(NULL)
|
||||
synergyd_LDADD = \
|
||||
$(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 \
|
||||
CTCPSocketFactory.h \
|
||||
ClipboardTypes.h \
|
||||
IClient.h \
|
||||
IClipboard.h \
|
||||
IScreenSaver.h \
|
||||
ISecondaryScreen.h \
|
||||
IServerProtocol.h \
|
||||
IServer.h \
|
||||
ISocketFactory.h \
|
||||
KeyTypes.h \
|
||||
MouseTypes.h \
|
||||
|
|
Loading…
Reference in New Issue