mirror of
https://github.com/TigerVNC/tigervnc.git
synced 2025-08-24 04:57:24 +02:00
Initial revision
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2 3789f03b-4d11-0410-bbf8-ca57d06f2519
This commit is contained in:
parent
266bb36cd4
commit
47ed8d321c
435 changed files with 72719 additions and 0 deletions
340
LICENCE.TXT
Normal file
340
LICENCE.TXT
Normal file
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
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 of the License, 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.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
5
Makefile.in
Normal file
5
Makefile.in
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
SUBDIRS = @ZLIB_DIR@ rdr network Xregion rfb tx x0vncserver vncviewer \
|
||||
vncconfig vncpasswd
|
||||
|
||||
# followed by boilerplate.mk
|
284
README
Normal file
284
README
Normal file
|
@ -0,0 +1,284 @@
|
|||
|
||||
VNC 4.0 Source Distribution for Unix platforms
|
||||
==============================================
|
||||
|
||||
Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
|
||||
This software is distributed under the GNU General Public Licence as published
|
||||
by the Free Software Foundation. See the file LICENCE.TXT for the conditions
|
||||
under which this software is made available. VNC also contains code from other
|
||||
sources. See the Acknowledgements section below, and the individual files for
|
||||
details of the conditions under which they are made available.
|
||||
|
||||
|
||||
There are six programs here:
|
||||
|
||||
vncviewer - this is the VNC viewer, or client, program for X.
|
||||
|
||||
Xvnc - this is the X VNC server - it is both a VNC server and an X server
|
||||
with a "virtual" framebuffer. You normally use the vncserver script
|
||||
to start Xvnc.
|
||||
|
||||
vncserver - this is a wrapper script which makes starting an X VNC server
|
||||
(i.e. desktop) more convenient. It is written in Perl, so to use
|
||||
the script you need that.
|
||||
|
||||
vncpasswd - this program allows you to change the password used to access
|
||||
your X VNC desktops. The vncserver script uses this program when
|
||||
you first start a VNC server.
|
||||
|
||||
vncconfig - this program is used to configure and control a running instance
|
||||
of Xvnc.
|
||||
|
||||
x0vncserver - this is an inefficient VNC server which continuously polls any
|
||||
X display, allowing it to be controlled via VNC. It is
|
||||
intended mainly as a demonstration of a simple VNC server.
|
||||
|
||||
In addition to these standalone programs, this distribution can also be used to
|
||||
turn the native X server for a platform into a VNC server. For XFree86 version
|
||||
4 servers, this is done using a module loaded at run-time. For other X servers
|
||||
it requires replacing the native X server binary.
|
||||
|
||||
To build this distribution you need a C++ compiler as well as a C compiler.
|
||||
You also need a reasonably recent version of the X window system installed.
|
||||
This comes as standard with most unix machines. If you don't have it
|
||||
installed, see http://www.xfree86.org or http://www.x.org
|
||||
|
||||
To build everything but Xvnc, do:
|
||||
|
||||
% ./configure
|
||||
% make
|
||||
|
||||
This should build first some libraries - zlib, rdr, network, Xregion, rfb and
|
||||
tx - then vncviewer, vncconfig and vncpasswd. If you already have zlib
|
||||
installed on your system you can run "./configure --with-installed-zlib" if you
|
||||
prefer (this is strongly advised on FreeBSD, since we've been told there are
|
||||
problems otherwise).
|
||||
|
||||
Building Xvnc
|
||||
=============
|
||||
|
||||
Building Xvnc and the VNC support for native X servers is much more complex.
|
||||
If you don't need to build it, skip to the section below on installing.
|
||||
|
||||
Xvnc differs from the other programs in that it is built inside the X source
|
||||
tree. Unlike previous versions of Xvnc, we do not provide an X source tree
|
||||
with this distribution. We have designed the distribution to be as independent
|
||||
as possible of the X tree used.
|
||||
|
||||
We have successfully used XFree86 version 4.3.0, 4.2.0 and 3.3.6 (available
|
||||
from http://www.xfree86.org). You could also try the original X.org tree
|
||||
available from http://www.x.org but this does not build as easily because of
|
||||
lack of support for C++, no support for building server only, and other issues.
|
||||
Note that the X tree is enormous and notoriously difficult to deal with -
|
||||
building it is not for the faint-hearted!
|
||||
|
||||
Once you have a copy of the X source tree, make sure it is unpacked at the top
|
||||
level of this distribution, so that the xc directory of the X source tree
|
||||
matches the xc of this distribution, for example:
|
||||
|
||||
% tar xzf X420src-1.tgz
|
||||
|
||||
Then you must apply a patch to some files in the X source tree:
|
||||
|
||||
% patch -Np0 <xc.patch
|
||||
|
||||
If this works, you should be able to build the entire X tree, including Xvnc:
|
||||
|
||||
% cd xc
|
||||
% make World
|
||||
|
||||
This will take a long time, and will quite probably fail for one reason or
|
||||
another! If you are having trouble, we suggest you try to build the X tree in
|
||||
isolation first before attempting it with the VNC additions.
|
||||
|
||||
If successful, in the xc/programs/Xserver directory you should find an Xvnc
|
||||
binary, plus the native X server binary(ies) for your platform with VNC support
|
||||
compiled in. If you are building from an XFree86 version 4 tree on a supported
|
||||
platform, you should also find a vnc.so module in
|
||||
xc/programs/Xserver/vnc/modules.
|
||||
|
||||
Exactly which X extensions and features are built into Xvnc and the native X
|
||||
server binary is determined by the settings in xc/config/cf. The file vnc.def
|
||||
contains the settings we use to build our binary distributions. You may need
|
||||
to edit this and the other files as appropriate.
|
||||
|
||||
Installing
|
||||
==========
|
||||
|
||||
Different unix platforms have different conventions for where software should
|
||||
be installed. To copy the programs to some directory which is in your PATH
|
||||
environment variable, such as /usr/local/bin, there is a script called
|
||||
vncinstall which you can use:
|
||||
|
||||
% cd ..
|
||||
% ./vncinstall /usr/local/bin
|
||||
|
||||
This will also attempt to install the manual pages in an appropriate directory.
|
||||
You can specify an alternative directory as a second argument to vncinstall:
|
||||
|
||||
% ./vncinstall /usr/local/bin /usr/local/man
|
||||
|
||||
It will also try to install the vnc.so XFree86 version 4 module if appropriate.
|
||||
This will be copied to the /usr/X11R6/lib/modules/extensions directory and can
|
||||
be enabled like any other module by adding a Load "vnc" line to the Module
|
||||
section of XF86Config. The parameters listed in the Xvnc manual page can be
|
||||
set as options in XF86Config e.g. Option "passwordFile" "/root/.vnc/passwd".
|
||||
Note that for some reason options cannot be set in the Module section of
|
||||
XF86Config - try the Screen section.
|
||||
|
||||
If you want to use the Java VNC viewer, you should copy the files from
|
||||
the java directory to some suitable installation directory such as
|
||||
/usr/local/vnc/classes:
|
||||
|
||||
% mkdir -p /usr/local/vnc/classes
|
||||
% cp java/* /usr/local/vnc/classes
|
||||
|
||||
We recommend that you use the vncserver script to run Xvnc for you. You can
|
||||
edit the script as appropriate for your site. Things you may need to change
|
||||
include:
|
||||
|
||||
* The location of Perl - if Perl is not installed in /usr/bin you'll need
|
||||
to edit the "#!/usr/bin/perl" first line of vncserver.
|
||||
|
||||
* Xvnc's font path and color database. If you have an installation of
|
||||
X which is not in the standard place you may need to add arguments to the
|
||||
Xvnc command line to set these. These should be appended to the $cmd
|
||||
variable at the comment "# Add font path and color database...".
|
||||
|
||||
* $vncJavaFiles - this specifies the location of the files for
|
||||
the VNC viewer Java applet. The default is /usr/local/vnc/classes.
|
||||
|
||||
|
||||
ACKNOWLEDGEMENTS
|
||||
================
|
||||
|
||||
This distribution contains public domain DES software by Richard Outerbridge.
|
||||
This is:
|
||||
|
||||
Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
|
||||
(GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
|
||||
|
||||
|
||||
This distribution contains software from the X Window System. This is:
|
||||
|
||||
Copyright 1987, 1988, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
|
||||
Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
This distribution contains zlib compression software. This is:
|
||||
|
||||
Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Jean-loup Gailly Mark Adler
|
||||
jloup@gzip.org madler@alumni.caltech.edu
|
||||
|
||||
|
||||
This distribution contains Java DES software by Dave Zimmerman
|
||||
<dzimm@widget.com> and Jef Poskanzer <jef@acme.com>. This is:
|
||||
|
||||
Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for NON-COMMERCIAL or COMMERCIAL purposes and without fee
|
||||
is hereby granted, provided that this copyright notice is kept intact.
|
||||
|
||||
WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
|
||||
SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE
|
||||
LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
|
||||
MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
|
||||
THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
|
||||
CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
|
||||
PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
|
||||
NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
|
||||
SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
|
||||
SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
|
||||
PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET
|
||||
WORKSHOP SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF
|
||||
FITNESS FOR HIGH RISK ACTIVITIES.
|
||||
|
||||
Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights
|
||||
reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Visit the ACME Labs Java page for up-to-date versions of this and other
|
||||
fine Java utilities: http://www.acme.com/java/
|
39
README.hpux
Normal file
39
README.hpux
Normal file
|
@ -0,0 +1,39 @@
|
|||
I have managed to build Xvnc on HPUX but only with some ugly hacking of
|
||||
the X tree. The X tree I used as the basis for the build is the XFree86 4.2.0
|
||||
tree. The XFree86 4.3.0 tree is unsuitable as it seems to have had some HPUX
|
||||
stuff removed from it. I built using the aCC C++ compiler.
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
% CXX=/opt/aCC/bin/aCC
|
||||
% CFLAGS="+DAportable"
|
||||
% CXXFLAGS="+DAportable -AA +W749 +W740"
|
||||
% BOOTSTRAPCFLAGS=-Dhpux
|
||||
% export CXX CFLAGS CXXFLAGS BOOTSTRAPCFLAGS
|
||||
|
||||
Build the main part of the VNC distribution as normal:
|
||||
|
||||
% ./configure
|
||||
% make
|
||||
|
||||
Unpack the X tree and apply the patches in xc.patch:
|
||||
|
||||
% gunzip -c X420src-1.tgz | tar xf -
|
||||
% patch -Np0 <xc.patch
|
||||
|
||||
Then additionally apply the patches in hpux.patch:
|
||||
|
||||
% patch -Np0 <hpux.patch
|
||||
|
||||
Finally try building the X tree:
|
||||
|
||||
% cd xc
|
||||
% make World
|
||||
|
||||
If it all goes to plan you will be left with Xvnc in xc/programs/Xserver. You
|
||||
will probably have to modify the vncserver script to set up a sensible font
|
||||
path, since many of the font directories on HPUX are different from the
|
||||
defaults compiled into Xvnc.
|
||||
|
||||
If anyone can find a neater way of building a VNC-compatible X tree on HPUX
|
||||
please let us know (see http://www.realvnc.com for contact details).
|
126
README.txt
Normal file
126
README.txt
Normal file
|
@ -0,0 +1,126 @@
|
|||
|
||||
VNC 4 Source Distribution for Windows platforms
|
||||
=============================================
|
||||
|
||||
VNC 4 is Copyright RealVNC Ltd. 2002-2004. This software is
|
||||
distributed under the GNU General Public Licence as published by the
|
||||
Free Software Foundation. See the accompanying licence.txt file for
|
||||
the conditions under which the software is made available.
|
||||
|
||||
VNC 4 also contains code from other sources. See the Acknowledgements
|
||||
section below, and the individual files for details of the conditions
|
||||
under which they are made available.
|
||||
|
||||
The source tree contains a number of directories, and is most easily
|
||||
built by loading the VNC workspace file (vnc.dsw) into Microsoft
|
||||
Visual Studio 6/7. This will preserve the required dependencies
|
||||
between the sub-projects.
|
||||
|
||||
There are three main executable projects:
|
||||
|
||||
vncviewer - The VNC Viewer for Win32.
|
||||
|
||||
winvnc - The VNC Server for Win32 (command-line operation
|
||||
only).
|
||||
|
||||
vncconfig - The configuration applet and GUI front-end for VNC
|
||||
Server.
|
||||
|
||||
These projects are designed to be built using Microsoft Visual C++
|
||||
6.0, and should also compile with Microsoft Visual Studio .NET
|
||||
(version 7). Other compilers have not been tested but the code base
|
||||
is extremely portable.
|
||||
|
||||
|
||||
ACKNOWLEDGEMENTS
|
||||
================
|
||||
|
||||
This distribution contains zlib software by Jean-loup Gailly and Mark Adler.
|
||||
This is:
|
||||
|
||||
Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Jean-loup Gailly Mark Adler
|
||||
jloup@gzip.org madler@alumni.caltech.edu
|
||||
|
||||
|
||||
The data format used by the zlib library is described by RFCs (Request for
|
||||
Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
|
||||
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
|
||||
|
||||
|
||||
This distribution contains public domain DES software by Richard Outerbridge.
|
||||
This is:
|
||||
|
||||
Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
|
||||
(GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
|
||||
|
||||
|
||||
This distribution contains Java DES software by Dave Zimmerman
|
||||
<dzimm@widget.com> and Jef Poskanzer <jef@acme.com>. This is:
|
||||
|
||||
Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for NON-COMMERCIAL or COMMERCIAL purposes and without fee
|
||||
is hereby granted, provided that this copyright notice is kept intact.
|
||||
|
||||
WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
|
||||
SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE
|
||||
LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
|
||||
MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
|
||||
THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
|
||||
CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
|
||||
PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
|
||||
NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
|
||||
SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
|
||||
SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
|
||||
PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET
|
||||
WORKSHOP SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF
|
||||
FITNESS FOR HIGH RISK ACTIVITIES.
|
||||
|
||||
Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights
|
||||
reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Visit the ACME Labs Java page for up-to-date versions of this and other
|
||||
fine Java utilities: http://www.acme.com/java/
|
120
README_BINARY.txt
Normal file
120
README_BINARY.txt
Normal file
|
@ -0,0 +1,120 @@
|
|||
|
||||
VNC 4 Binary Distribution for Windows platforms
|
||||
=============================================
|
||||
|
||||
VNC 4 is Copyright RealVNC Ltd. 2002-2004. This software is
|
||||
distributed under the GNU General Public Licence as published by the
|
||||
Free Software Foundation. VNC also contains code from other sources,
|
||||
as outlined in the Acknowledgements section below.
|
||||
|
||||
The installer package contains two VNC components:
|
||||
|
||||
VNC Viewer - this is the VNC Viewer, or client, program for
|
||||
Win32.
|
||||
[Win9x, WinME, NT4, Win2000, WinXP,
|
||||
Windows 2003 Server]
|
||||
|
||||
VNC Server - this is the VNC Server for Win32. It allows a
|
||||
Windows desktop to be accessed remotely using a
|
||||
VNC Viewer.
|
||||
[Win9x, WinME, NT4, Win2000, WinXP(*),
|
||||
Windows 2003 Server]
|
||||
|
||||
(*) May not work if the in-built Fast User Switching or Remote
|
||||
Administration features are in use.
|
||||
|
||||
Both components were built using Microsoft Visual C++ 6.0, and are
|
||||
designed to operate upon the Win32 platforms listed above.
|
||||
|
||||
ACKNOWLEDGEMENTS
|
||||
================
|
||||
|
||||
This distribution contains zlib software by Jean-loup Gailly and Mark Adler.
|
||||
This is:
|
||||
|
||||
Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Jean-loup Gailly Mark Adler
|
||||
jloup@gzip.org madler@alumni.caltech.edu
|
||||
|
||||
|
||||
The data format used by the zlib library is described by RFCs (Request for
|
||||
Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
|
||||
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
|
||||
|
||||
|
||||
This distribution contains public domain DES software by Richard Outerbridge.
|
||||
This is:
|
||||
|
||||
Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
|
||||
(GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
|
||||
|
||||
|
||||
This distribution contains Java DES software by Dave Zimmerman
|
||||
<dzimm@widget.com> and Jef Poskanzer <jef@acme.com>. This is:
|
||||
|
||||
Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for NON-COMMERCIAL or COMMERCIAL purposes and without fee
|
||||
is hereby granted, provided that this copyright notice is kept intact.
|
||||
|
||||
WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
|
||||
SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE
|
||||
LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
|
||||
MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
|
||||
THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
|
||||
CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
|
||||
PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
|
||||
NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
|
||||
SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
|
||||
SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
|
||||
PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET
|
||||
WORKSHOP SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF
|
||||
FITNESS FOR HIGH RISK ACTIVITIES.
|
||||
|
||||
Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights
|
||||
reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Visit the ACME Labs Java page for up-to-date versions of this and other
|
||||
fine Java utilities: http://www.acme.com/java/
|
15
Xregion/Makefile.in
Normal file
15
Xregion/Makefile.in
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
SRCS = Region.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
library = libXregion.a
|
||||
|
||||
all:: $(library)
|
||||
|
||||
$(library): $(OBJS)
|
||||
rm -f $(library)
|
||||
$(AR) $(library) $(OBJS)
|
||||
$(RANLIB) $(library)
|
||||
|
||||
# followed by boilerplate.mk
|
1687
Xregion/Region.c
Normal file
1687
Xregion/Region.c
Normal file
File diff suppressed because it is too large
Load diff
132
Xregion/Xregion.dsp
Normal file
132
Xregion/Xregion.dsp
Normal file
|
@ -0,0 +1,132 @@
|
|||
# Microsoft Developer Studio Project File - Name="Xregion" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=Xregion - Win32 Debug Unicode
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Xregion.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Xregion.mak" CFG="Xregion - Win32 Debug Unicode"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Xregion - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "Xregion - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "Xregion - Win32 Debug Unicode" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "Xregion - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /D "NDEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x809 /d "NDEBUG"
|
||||
# ADD RSC /l 0x809 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "Xregion - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I ".." /D "_DEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "Xregion - Win32 Debug Unicode"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Xregion___Win32_Debug_Unicode"
|
||||
# PROP BASE Intermediate_Dir "Xregion___Win32_Debug_Unicode"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug_Unicode"
|
||||
# PROP Intermediate_Dir "Debug_Unicode"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I ".." /D "_DEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /FD /GZ /c
|
||||
# SUBTRACT BASE CPP /YX
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I ".." /D "_LIB" /D "_DEBUG" /D "WIN32" /D "_UNICODE" /D "UNICODE" /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "Xregion - Win32 Release"
|
||||
# Name "Xregion - Win32 Debug"
|
||||
# Name "Xregion - Win32 Debug Unicode"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Region.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\region.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Xregion.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
220
Xregion/Xregion.h
Normal file
220
Xregion/Xregion.h
Normal file
|
@ -0,0 +1,220 @@
|
|||
/* $Xorg: Xutil.h,v 1.8 2001/02/09 02:03:39 xorgcvs Exp $ */
|
||||
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
/* $XFree86: xc/lib/X11/Xutil.h,v 3.4 2001/12/14 19:54:10 dawes Exp $ */
|
||||
|
||||
#ifndef _XREGION_H_
|
||||
#define _XREGION_H_
|
||||
|
||||
// - Faked defines to fool the X11 region code
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define Bool int
|
||||
#define Xmalloc malloc
|
||||
#define Xfree free
|
||||
#define Xrealloc realloc
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define NeedFunctionPrototypes 1
|
||||
|
||||
// - Cribbed from Xlib.h
|
||||
|
||||
typedef struct {
|
||||
short x, y;
|
||||
} XPoint;
|
||||
|
||||
typedef struct {
|
||||
short x, y;
|
||||
unsigned short width, height;
|
||||
} XRectangle;
|
||||
|
||||
/*
|
||||
* opaque reference to Region data type
|
||||
*/
|
||||
typedef struct _XRegion *Region;
|
||||
|
||||
/* Return values from XRectInRegion() */
|
||||
|
||||
#define RectangleOut 0
|
||||
#define RectangleIn 1
|
||||
#define RectanglePart 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int XClipBox(
|
||||
#if NeedFunctionPrototypes
|
||||
Region /* r */,
|
||||
XRectangle* /* rect_return */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern Region XCreateRegion(
|
||||
#if NeedFunctionPrototypes
|
||||
void
|
||||
#endif
|
||||
);
|
||||
|
||||
extern const char *XDefaultString (void);
|
||||
|
||||
extern int XDestroyRegion(
|
||||
#if NeedFunctionPrototypes
|
||||
Region /* r */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int XEmptyRegion(
|
||||
#if NeedFunctionPrototypes
|
||||
Region /* r */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int XEqualRegion(
|
||||
#if NeedFunctionPrototypes
|
||||
Region /* r1 */,
|
||||
Region /* r2 */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int XIntersectRegion(
|
||||
#if NeedFunctionPrototypes
|
||||
Region /* sra */,
|
||||
Region /* srb */,
|
||||
Region /* dr_return */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int XOffsetRegion(
|
||||
#if NeedFunctionPrototypes
|
||||
Region /* r */,
|
||||
int /* dx */,
|
||||
int /* dy */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern Bool XPointInRegion(
|
||||
#if NeedFunctionPrototypes
|
||||
Region /* r */,
|
||||
int /* x */,
|
||||
int /* y */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern Region XPolygonRegion(
|
||||
#if NeedFunctionPrototypes
|
||||
XPoint* /* points */,
|
||||
int /* n */,
|
||||
int /* fill_rule */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int XRectInRegion(
|
||||
#if NeedFunctionPrototypes
|
||||
Region /* r */,
|
||||
int /* x */,
|
||||
int /* y */,
|
||||
unsigned int /* width */,
|
||||
unsigned int /* height */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int XShrinkRegion(
|
||||
#if NeedFunctionPrototypes
|
||||
Region /* r */,
|
||||
int /* dx */,
|
||||
int /* dy */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int XSubtractRegion(
|
||||
#if NeedFunctionPrototypes
|
||||
Region /* sra */,
|
||||
Region /* srb */,
|
||||
Region /* dr_return */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int XUnionRectWithRegion(
|
||||
#if NeedFunctionPrototypes
|
||||
XRectangle* /* rectangle */,
|
||||
Region /* src_region */,
|
||||
Region /* dest_region_return */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int XUnionRegion(
|
||||
#if NeedFunctionPrototypes
|
||||
Region /* sra */,
|
||||
Region /* srb */,
|
||||
Region /* dr_return */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int XXorRegion(
|
||||
#if NeedFunctionPrototypes
|
||||
Region /* sra */,
|
||||
Region /* srb */,
|
||||
Region /* dr_return */
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* _XUTIL_H_ */
|
190
Xregion/region.h
Normal file
190
Xregion/region.h
Normal file
|
@ -0,0 +1,190 @@
|
|||
/* $Xorg: region.h,v 1.4 2001/02/09 02:03:40 xorgcvs Exp $ */
|
||||
/************************************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
************************************************************************/
|
||||
|
||||
#ifndef _XREGION_H
|
||||
#define _XREGION_H
|
||||
|
||||
typedef struct {
|
||||
short x1, x2, y1, y2;
|
||||
} Box, BOX, BoxRec, *BoxPtr;
|
||||
|
||||
typedef struct {
|
||||
short x, y, width, height;
|
||||
}RECTANGLE, RectangleRec, *RectanglePtr;
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define MAXSHORT 32767
|
||||
#define MINSHORT -MAXSHORT
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* clip region
|
||||
*/
|
||||
|
||||
typedef struct _XRegion {
|
||||
long size;
|
||||
long numRects;
|
||||
BOX *rects;
|
||||
BOX extents;
|
||||
} REGION;
|
||||
|
||||
/* Xutil.h contains the declaration:
|
||||
* typedef struct _XRegion *Region;
|
||||
*/
|
||||
|
||||
/* 1 if two BOXs overlap.
|
||||
* 0 if two BOXs do not overlap.
|
||||
* Remember, x2 and y2 are not in the region
|
||||
*/
|
||||
#define EXTENTCHECK(r1, r2) \
|
||||
((r1)->x2 > (r2)->x1 && \
|
||||
(r1)->x1 < (r2)->x2 && \
|
||||
(r1)->y2 > (r2)->y1 && \
|
||||
(r1)->y1 < (r2)->y2)
|
||||
|
||||
/*
|
||||
* update region extents
|
||||
*/
|
||||
#define EXTENTS(r,idRect){\
|
||||
if((r)->x1 < (idRect)->extents.x1)\
|
||||
(idRect)->extents.x1 = (r)->x1;\
|
||||
if((r)->y1 < (idRect)->extents.y1)\
|
||||
(idRect)->extents.y1 = (r)->y1;\
|
||||
if((r)->x2 > (idRect)->extents.x2)\
|
||||
(idRect)->extents.x2 = (r)->x2;\
|
||||
if((r)->y2 > (idRect)->extents.y2)\
|
||||
(idRect)->extents.y2 = (r)->y2;\
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if there is enough memory in the present region.
|
||||
*/
|
||||
#define MEMCHECK(reg, rect, firstrect){\
|
||||
if ((reg)->numRects >= ((reg)->size - 1)){\
|
||||
(firstrect) = (BOX *) Xrealloc \
|
||||
((char *)(firstrect), (unsigned) (2 * (sizeof(BOX)) * ((reg)->size)));\
|
||||
if ((firstrect) == 0)\
|
||||
return(0);\
|
||||
(reg)->size *= 2;\
|
||||
(rect) = &(firstrect)[(reg)->numRects];\
|
||||
}\
|
||||
}
|
||||
|
||||
/* this routine checks to see if the previous rectangle is the same
|
||||
* or subsumes the new rectangle to add.
|
||||
*/
|
||||
|
||||
#define CHECK_PREVIOUS(Reg, R, Rx1, Ry1, Rx2, Ry2)\
|
||||
(!(((Reg)->numRects > 0)&&\
|
||||
((R-1)->y1 == (Ry1)) &&\
|
||||
((R-1)->y2 == (Ry2)) &&\
|
||||
((R-1)->x1 <= (Rx1)) &&\
|
||||
((R-1)->x2 >= (Rx2))))
|
||||
|
||||
/* add a rectangle to the given Region */
|
||||
#define ADDRECT(reg, r, rx1, ry1, rx2, ry2){\
|
||||
if (((rx1) < (rx2)) && ((ry1) < (ry2)) &&\
|
||||
CHECK_PREVIOUS((reg), (r), (rx1), (ry1), (rx2), (ry2))){\
|
||||
(r)->x1 = (rx1);\
|
||||
(r)->y1 = (ry1);\
|
||||
(r)->x2 = (rx2);\
|
||||
(r)->y2 = (ry2);\
|
||||
EXTENTS((r), (reg));\
|
||||
(reg)->numRects++;\
|
||||
(r)++;\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* add a rectangle to the given Region */
|
||||
#define ADDRECTNOX(reg, r, rx1, ry1, rx2, ry2){\
|
||||
if ((rx1 < rx2) && (ry1 < ry2) &&\
|
||||
CHECK_PREVIOUS((reg), (r), (rx1), (ry1), (rx2), (ry2))){\
|
||||
(r)->x1 = (rx1);\
|
||||
(r)->y1 = (ry1);\
|
||||
(r)->x2 = (rx2);\
|
||||
(r)->y2 = (ry2);\
|
||||
(reg)->numRects++;\
|
||||
(r)++;\
|
||||
}\
|
||||
}
|
||||
|
||||
#define EMPTY_REGION(pReg) pReg->numRects = 0
|
||||
|
||||
#define REGION_NOT_EMPTY(pReg) pReg->numRects
|
||||
|
||||
#define INBOX(r, x, y) \
|
||||
( ( ((r).x2 > x)) && \
|
||||
( ((r).x1 <= x)) && \
|
||||
( ((r).y2 > y)) && \
|
||||
( ((r).y1 <= y)) )
|
||||
|
||||
/*
|
||||
* number of points to buffer before sending them off
|
||||
* to scanlines() : Must be an even number
|
||||
*/
|
||||
#define NUMPTSTOBUFFER 200
|
||||
|
||||
/*
|
||||
* used to allocate buffers for points and link
|
||||
* the buffers together
|
||||
*/
|
||||
typedef struct _POINTBLOCK {
|
||||
XPoint pts[NUMPTSTOBUFFER];
|
||||
struct _POINTBLOCK *next;
|
||||
} POINTBLOCK;
|
||||
|
||||
#endif
|
35
boilerplate.mk
Normal file
35
boilerplate.mk
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
all::
|
||||
@subdirs="$(SUBDIRS)"; for d in $$subdirs; do (cd $$d; $(MAKE) $@) || exit 1; done
|
||||
|
||||
clean::
|
||||
@subdirs="$(SUBDIRS)"; for d in $$subdirs; do (cd $$d; $(MAKE) $@) || exit 1; done
|
||||
|
||||
clean::
|
||||
rm -f $(program) $(library) *.o
|
||||
|
||||
SHELL = @SHELL@
|
||||
top_srcdir = @top_srcdir@
|
||||
@SET_MAKE@
|
||||
CC = @CC@
|
||||
CFLAGS = @CFLAGS@ $(DIR_CFLAGS)
|
||||
CCLD = $(CC)
|
||||
CXX = @CXX@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CXXLD = $(CXX)
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
DEFS = @DEFS@
|
||||
ALL_CPPFLAGS = $(CPPFLAGS) $(DEFS) $(DIR_CPPFLAGS)
|
||||
LIBS = @LIBS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
RANLIB = @RANLIB@
|
||||
AR = ar cq
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .cxx .c .o
|
||||
|
||||
.c.o:
|
||||
$(CC) $(ALL_CPPFLAGS) $(CFLAGS) -c $<
|
||||
|
||||
.cxx.o:
|
||||
$(CXX) $(ALL_CPPFLAGS) $(CXXFLAGS) -c $<
|
99
configure.in
Normal file
99
configure.in
Normal file
|
@ -0,0 +1,99 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(rdr/InStream.h)
|
||||
|
||||
dnl dirty hack to prevent use of -g in CFLAGS and CXXFLAGS
|
||||
ac_cv_prog_cc_g=no
|
||||
ac_cv_prog_cxx_g=no
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_MAKE_SET
|
||||
AC_LANG_CPLUSPLUS
|
||||
|
||||
case "`(uname -sr) 2>/dev/null`" in
|
||||
"SunOS 5"*)
|
||||
SOLARIS=yes
|
||||
USE_MITSHM=yes
|
||||
;;
|
||||
"Linux"*)
|
||||
LINUX=yes
|
||||
USE_MITSHM=yes
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$USE_MITSHM" = yes; then
|
||||
MITSHM_CPPFLAGS="-DMITSHM"
|
||||
fi
|
||||
AC_SUBST(MITSHM_CPPFLAGS)
|
||||
|
||||
if test "$GCC" = yes; then
|
||||
CFLAGS="$CFLAGS -Wall"
|
||||
if test "$SOLARIS" = yes; then
|
||||
CFLAGS="$CFLAGS -Wno-unknown-pragmas -Wno-implicit-int"
|
||||
fi
|
||||
fi
|
||||
if test "$GXX" = yes; then
|
||||
CXXFLAGS="$CXXFLAGS -Wall"
|
||||
if test "$SOLARIS" = yes; then
|
||||
CXXFLAGS="$CXXFLAGS -Wno-unknown-pragmas -Wno-implicit-int -fpermissive"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_PATH_XTRA
|
||||
|
||||
AC_ARG_WITH(installed-zlib,
|
||||
[ --with-installed-zlib use the version of zlib which is installed on the
|
||||
system instead of the one distributed with VNC])
|
||||
|
||||
if test "$with_installed_zlib" = yes; then
|
||||
echo "using installed zlib"
|
||||
ZLIB_LIB=-lz
|
||||
else
|
||||
ZLIB_DIR=zlib
|
||||
ZLIB_INCLUDE='-I$(top_srcdir)/zlib'
|
||||
ZLIB_LIB='$(top_srcdir)/zlib/libz.a'
|
||||
echo "configuring zlib..."
|
||||
(cd zlib; ./configure)
|
||||
echo "...done configuring zlib"
|
||||
fi
|
||||
|
||||
AC_SUBST(ZLIB_DIR)
|
||||
AC_SUBST(ZLIB_INCLUDE)
|
||||
AC_SUBST(ZLIB_LIB)
|
||||
|
||||
AC_CHECK_FUNC(vsnprintf,VSNPRINTF_DEFINE='-DHAVE_VSNPRINTF',VSNPRINTF_DEFINE=)
|
||||
AC_SUBST(VSNPRINTF_DEFINE)
|
||||
|
||||
AC_MSG_CHECKING(for socklen_t)
|
||||
AC_TRY_COMPILE(
|
||||
[#include <sys/types.h>
|
||||
#include <sys/socket.h>],
|
||||
[socklen_t x;
|
||||
accept(0, 0, &x);],
|
||||
AC_MSG_RESULT(yes)
|
||||
SOCKLEN_T_DEFINE='-DVNC_SOCKLEN_T=socklen_t',
|
||||
AC_MSG_RESULT(using int)
|
||||
SOCKLEN_T_DEFINE='-DVNC_SOCKLEN_T=int')
|
||||
AC_SUBST(SOCKLEN_T_DEFINE)
|
||||
|
||||
BOILERPLATE=boilerplate.mk
|
||||
|
||||
if (sh -c "make --version" 2>/dev/null | grep GNU 2>&1 >/dev/null); then
|
||||
if sh -c "vncmkdepend" >/dev/null 2>&1; then
|
||||
BOILERPLATE="$BOILERPLATE:depend.mk"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_OUTPUT(Makefile:Makefile.in:$BOILERPLATE \
|
||||
rdr/Makefile:rdr/Makefile.in:$BOILERPLATE \
|
||||
network/Makefile:network/Makefile.in:$BOILERPLATE \
|
||||
Xregion/Makefile:Xregion/Makefile.in:$BOILERPLATE \
|
||||
rfb/Makefile:rfb/Makefile.in:$BOILERPLATE \
|
||||
tx/Makefile:tx/Makefile.in:$BOILERPLATE \
|
||||
x0vncserver/Makefile:x0vncserver/Makefile.in:$BOILERPLATE \
|
||||
vncviewer/Makefile:vncviewer/Makefile.in:$BOILERPLATE \
|
||||
vncconfig/Makefile:vncconfig/Makefile.in:$BOILERPLATE \
|
||||
vncpasswd/Makefile:vncpasswd/Makefile.in:$BOILERPLATE \
|
||||
)
|
76
depend.mk
Normal file
76
depend.mk
Normal file
|
@ -0,0 +1,76 @@
|
|||
#
|
||||
# C / C++ header dependency stuff
|
||||
#
|
||||
# Needs GNU make and vncmkdepend, a hacked version of makedepend
|
||||
|
||||
.SUFFIXES: .d
|
||||
|
||||
CMAKEDEPEND = vncmkdepend
|
||||
CXXMAKEDEPEND = vncmkdepend
|
||||
|
||||
#
|
||||
# The recommended method of doing dependency analysis in the GNU make manual
|
||||
# turns out to be painfully slow. This method is similar but it's
|
||||
# substantially faster and retains the desirable property that the user doesn't
|
||||
# need to manually invoke a "make depend" step.
|
||||
#
|
||||
# As with the method described in the manual, we generate a separate dependency
|
||||
# (.d) file for each source file. The .d file records the header files that
|
||||
# each C or C++ source file includes. Any source file recorded in SRCS or
|
||||
# CXXSRCS will cause us to try and include the corresponding .d file and GNU
|
||||
# make then treats each .d file as a target to be remade.
|
||||
#
|
||||
# Unlike the manual's method, the rule we provide for making the .d file is
|
||||
# actually a fake. All it does is record in a temporary file that the .d file
|
||||
# needs to be remade. But as well as all the .d files, we also try to include
|
||||
# a file called "depend.phony". This file never exists, but it causes GNU make
|
||||
# to try and make the target "depend.phony". The rule for depend.phony then
|
||||
# looks at the temporary files generated by the .d rules and then invokes the
|
||||
# "omkdepend" program on all of the source files in one go.
|
||||
#
|
||||
|
||||
#
|
||||
# We use simple assignment here to remove any of the depend.tmp files
|
||||
# at the time make parses this bit.
|
||||
#
|
||||
|
||||
dummyvariable := $(shell $(RM) cdepend.tmp cxxdepend.tmp)
|
||||
|
||||
#
|
||||
# Now the "fake" rules for generating .d files.
|
||||
#
|
||||
|
||||
%.d: %.c
|
||||
@echo "$<" >> cdepend.tmp
|
||||
|
||||
%.d: %.cxx
|
||||
@echo "$<" >> cxxdepend.tmp
|
||||
|
||||
#
|
||||
# The depend.phony rule which actually runs omkdepend.
|
||||
#
|
||||
|
||||
depend.phony:
|
||||
@if [ -f cdepend.tmp ]; then \
|
||||
echo $(CMAKEDEPEND) $(ALL_CPPFLAGS) `cat cdepend.tmp`; \
|
||||
$(CMAKEDEPEND) $(ALL_CPPFLAGS) `cat cdepend.tmp`; \
|
||||
rm -f cdepend.tmp; \
|
||||
fi; \
|
||||
if [ -f cxxdepend.tmp ]; then \
|
||||
echo $(CXXMAKEDEPEND) $(ALL_CPPFLAGS) `cat cxxdepend.tmp`; \
|
||||
$(CXXMAKEDEPEND) $(ALL_CPPFLAGS) `cat cxxdepend.tmp`; \
|
||||
rm -f cxxdepend.tmp; \
|
||||
fi
|
||||
|
||||
#
|
||||
# Now include the .d files and the "depend.phony" file which never exists.
|
||||
# For some reason GNU make evaluates the targets in reverse order, so we need
|
||||
# to include depend.phony first. The "-" tells make not to complain that it
|
||||
# can't find the file.
|
||||
#
|
||||
|
||||
-include depend.phony
|
||||
|
||||
ifdef SRCS
|
||||
-include $(patsubst %.c,%.d,$(patsubst %.cxx,%.d,$(SRCS)))
|
||||
endif
|
255
hpux.patch
Normal file
255
hpux.patch
Normal file
|
@ -0,0 +1,255 @@
|
|||
*** xc.orig/config/cf/X11.tmpl Tue Jan 15 22:55:26 2002
|
||||
--- xc/config/cf/X11.tmpl Sun Sep 7 19:52:01 2003
|
||||
***************
|
||||
*** 3120,3126 ****
|
||||
$(RM) index.raw file.nPS file.PS file.txt
|
||||
#endif
|
||||
|
||||
! #ifndef MakeSimpleDoc(file,srcs)
|
||||
#define MakeSimpleDoc(file,srcs) MakeDepSimpleDoc(file,srcs,srcs)
|
||||
#endif
|
||||
|
||||
--- 3120,3126 ----
|
||||
$(RM) index.raw file.nPS file.PS file.txt
|
||||
#endif
|
||||
|
||||
! #ifndef MakeSimpleDoc
|
||||
#define MakeSimpleDoc(file,srcs) MakeDepSimpleDoc(file,srcs,srcs)
|
||||
#endif
|
||||
|
||||
*** xc.orig/config/cf/hp.cf Wed Jan 17 16:22:31 2001
|
||||
--- xc/config/cf/hp.cf Mon Sep 8 19:54:52 2003
|
||||
***************
|
||||
*** 131,137 ****
|
||||
#endif
|
||||
#define HPFastScrolling YES
|
||||
#ifndef BuildServer
|
||||
! # define BuildServer __hp9000s700
|
||||
#endif
|
||||
#if OSMajorVersion < 10
|
||||
#define NeedBerklib (BuildServer|BuildFontServer)
|
||||
--- 131,137 ----
|
||||
#endif
|
||||
#define HPFastScrolling YES
|
||||
#ifndef BuildServer
|
||||
! # define BuildServer YES
|
||||
#endif
|
||||
#if OSMajorVersion < 10
|
||||
#define NeedBerklib (BuildServer|BuildFontServer)
|
||||
***************
|
||||
*** 139,145 ****
|
||||
#define XawI18nDefines -DHAS_WCHAR_H -DHAS_ISW_FUNCS
|
||||
|
||||
#if OSMajorVersion < 6 || (OSMajorVersion == 6 && OSMinorVersion < 2)
|
||||
! # define ConnectionFlags -DTCPCONN /* no unix sockets */
|
||||
#endif
|
||||
|
||||
#if OSMajorVersion > 8
|
||||
--- 139,145 ----
|
||||
#define XawI18nDefines -DHAS_WCHAR_H -DHAS_ISW_FUNCS
|
||||
|
||||
#if OSMajorVersion < 6 || (OSMajorVersion == 6 && OSMinorVersion < 2)
|
||||
! /*# define ConnectionFlags -DTCPCONN*/ /* no unix sockets */
|
||||
#endif
|
||||
|
||||
#if OSMajorVersion > 8
|
||||
*** xc/config/cf/site.def.orig Tue Sep 9 17:42:56 2003
|
||||
--- xc/config/cf/site.def Tue Sep 9 17:43:07 2003
|
||||
***************
|
||||
*** 84,90 ****
|
||||
#ifdef AfterVendorCF
|
||||
|
||||
#ifndef ProjectRoot
|
||||
! #define ProjectRoot /usr/X11R6
|
||||
#endif
|
||||
|
||||
/*
|
||||
--- 84,90 ----
|
||||
#ifdef AfterVendorCF
|
||||
|
||||
#ifndef ProjectRoot
|
||||
! /*#define ProjectRoot /usr/X11R6*/
|
||||
#endif
|
||||
|
||||
/*
|
||||
*** xc.orig/config/imake/imake.c Fri Dec 14 19:53:18 2001
|
||||
--- xc/config/imake/imake.c Mon Sep 8 19:35:33 2003
|
||||
***************
|
||||
*** 288,293 ****
|
||||
--- 288,294 ----
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
+ #define FIXUP_CPP_WHITESPACE
|
||||
#ifdef FIXUP_CPP_WHITESPACE
|
||||
int InRule = FALSE;
|
||||
# ifdef INLINE_SYNTAX
|
||||
***************
|
||||
*** 389,394 ****
|
||||
--- 390,401 ----
|
||||
FILE *tmpfd = NULL;
|
||||
char makeMacro[ BUFSIZ ];
|
||||
char makefileMacro[ BUFSIZ ];
|
||||
+
|
||||
+ #ifdef FIXUP_CPP_WHITESPACE
|
||||
+ fprintf(stderr,"\nFIXUP_CPP_WHITESPACE is defined!!\n\n");
|
||||
+ #else
|
||||
+ #error "FIXUP_CPP_WHITESPACE is not defined"
|
||||
+ #endif
|
||||
|
||||
program = argv[0];
|
||||
init();
|
||||
*** xc.orig/config/imake/imakemdep.h Fri Dec 14 19:53:19 2001
|
||||
--- xc/config/imake/imakemdep.h Tue Sep 9 16:38:18 2003
|
||||
***************
|
||||
*** 48,54 ****
|
||||
#ifdef hp9000s800
|
||||
#define imake_ccflags "-DSYSV"
|
||||
#else
|
||||
! #define imake_ccflags "-Wc,-Nd4000,-Ns3000 -DSYSV"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
--- 48,54 ----
|
||||
#ifdef hp9000s800
|
||||
#define imake_ccflags "-DSYSV"
|
||||
#else
|
||||
! #define imake_ccflags "-DSYSV"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
***************
|
||||
*** 211,217 ****
|
||||
* all colons). One way to tell if you need this is to see whether or not
|
||||
* your Makefiles have no tabs in them and lots of @@ strings.
|
||||
*/
|
||||
! #if defined(sun) || defined(SYSV) || defined(SVR4) || defined(hcx) || defined(WIN32) || defined(sco) || (defined(AMOEBA) && defined(CROSS_COMPILE)) || defined(__QNX__) || defined(__sgi)
|
||||
#define FIXUP_CPP_WHITESPACE
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
--- 211,217 ----
|
||||
* all colons). One way to tell if you need this is to see whether or not
|
||||
* your Makefiles have no tabs in them and lots of @@ strings.
|
||||
*/
|
||||
! #if defined(sun) || defined(SYSV) || defined(SVR4) || defined(hcx) || defined(WIN32) || defined(sco) || (defined(AMOEBA) && defined(CROSS_COMPILE)) || defined(__QNX__) || defined(__sgi) || defined(hpux)
|
||||
#define FIXUP_CPP_WHITESPACE
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
*** xc.orig/include/Xfuncs.h Fri Dec 14 19:53:25 2001
|
||||
--- xc/include/Xfuncs.h Sun Sep 7 20:10:35 2003
|
||||
***************
|
||||
*** 42,48 ****
|
||||
#else
|
||||
#if defined(SYSV)
|
||||
#include <memory.h>
|
||||
! void bcopy();
|
||||
#define bzero(b,len) memset(b, 0, len)
|
||||
#define bcmp(b1,b2,len) memcmp(b1, b2, len)
|
||||
#elif defined(__EMX__)
|
||||
--- 42,48 ----
|
||||
#else
|
||||
#if defined(SYSV)
|
||||
#include <memory.h>
|
||||
! /*void bcopy();*/
|
||||
#define bzero(b,len) memset(b, 0, len)
|
||||
#define bcmp(b1,b2,len) memcmp(b1, b2, len)
|
||||
#elif defined(__EMX__)
|
||||
*** xc.orig/include/extensions/security.h Fri Dec 14 19:53:29 2001
|
||||
--- xc/include/extensions/security.h Fri Aug 1 17:43:44 2003
|
||||
***************
|
||||
*** 110,115 ****
|
||||
--- 110,116 ----
|
||||
|
||||
#include "input.h" /* for DeviceIntPtr */
|
||||
#include "property.h" /* for PropertyPtr */
|
||||
+ #include "resource.h"
|
||||
|
||||
/* resource type to pass in LookupIDByType for authorizations */
|
||||
extern RESTYPE SecurityAuthorizationResType;
|
||||
*** xc.orig/lib/font/Type1/fontfcn.c Fri Nov 23 19:21:31 2001
|
||||
--- xc/lib/font/Type1/fontfcn.c Sun Sep 7 19:29:27 2003
|
||||
***************
|
||||
*** 47,52 ****
|
||||
--- 47,53 ----
|
||||
*/
|
||||
/* $XFree86: xc/lib/font/Type1/fontfcn.c,v 1.11 2001/11/23 19:21:31 dawes Exp $ */
|
||||
|
||||
+ #include <stdlib.h>
|
||||
#ifndef FONTMODULE
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
*** xc.orig/lib/font/Type1/objects.h Mon Aug 27 20:49:52 2001
|
||||
--- xc/lib/font/Type1/objects.h Sun Sep 7 19:29:37 2003
|
||||
***************
|
||||
*** 50,56 ****
|
||||
#include <Xdefs.h>
|
||||
#include <Xfuncproto.h>
|
||||
#ifndef FONTMODULE
|
||||
! #include <stdlib.h>
|
||||
#endif
|
||||
/*SHARED*/
|
||||
|
||||
--- 50,56 ----
|
||||
#include <Xdefs.h>
|
||||
#include <Xfuncproto.h>
|
||||
#ifndef FONTMODULE
|
||||
! /*#include <stdlib.h>*/
|
||||
#endif
|
||||
/*SHARED*/
|
||||
|
||||
*** xc.orig/lib/xtrans/Xtransutil.c Tue Sep 9 17:40:14 2003
|
||||
--- xc/lib/xtrans/Xtransutil.c Tue Sep 9 17:40:20 2003
|
||||
***************
|
||||
*** 503,514 ****
|
||||
if (updateOwner && !updatedOwner) {
|
||||
PRMSG(1, "mkdir: Owner of %s should be set to root\n",
|
||||
path, 0, 0);
|
||||
- sleep(5);
|
||||
}
|
||||
if (updateMode && !updatedMode) {
|
||||
PRMSG(1, "mkdir: Mode of %s should be set to %04o\n",
|
||||
path, mode, 0);
|
||||
- sleep(5);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
--- 503,512 ----
|
||||
*** xc.orig/programs/Xserver/vnc/Xvnc/xvnc.cc 12 Aug 2003 11:00:14 -0000
|
||||
--- xc/programs/Xserver/vnc/Xvnc/xvnc.cc 9 Sep 2003 16:15:53 -0000
|
||||
***************
|
||||
*** 1221,1223 ****
|
||||
--- 1221,1229 ----
|
||||
miRegisterPointerDevice(screenInfo.screens[0], p);
|
||||
(void)mieqInit ((DevicePtr)k, (DevicePtr)p);
|
||||
}
|
||||
+
|
||||
+ extern "C" {
|
||||
+ void XTestGenerateEvent() {}
|
||||
+ void XTestGetPointerPos() {}
|
||||
+ void XTestJumpPointer() {}
|
||||
+ }
|
||||
*** xc.orig/config/cf/vnc.def 7 Jul 2003 09:51:22
|
||||
--- xc/config/cf/vnc.def 9 Sep 2003 15:54:23
|
||||
***************
|
||||
*** 9,14 ****
|
||||
--- 9,20 ----
|
||||
#define XnestServer NO
|
||||
#define XprtServer NO
|
||||
|
||||
+ #define BuildXKB NO
|
||||
+ #define HasCplusplus YES
|
||||
+ #define CplusplusCmd /opt/aCC/bin/aCC
|
||||
+ #define CplusplusOptions -AA +W749 +W740
|
||||
+ #define ProjectRoot /usr
|
||||
+
|
||||
#ifdef SunArchitecture
|
||||
#define ProjectRoot /usr/openwin
|
||||
#define HasGcc2 YES
|
||||
***************
|
||||
*** 29,32 ****
|
||||
--- 34,38 ----
|
||||
|
||||
#define ServerTarget(server,subdirs,objects,libs,syslibs) @@\
|
||||
CCLINK = $(CXXENVSETUP) $(CXX) @@\
|
||||
+ CCOPTIONS = -AA @@\
|
||||
ServerTargetWithFlags(server,subdirs,objects,libs,syslibs,$(_NOOP_))
|
13
java/index.vnc
Normal file
13
java/index.vnc
Normal file
|
@ -0,0 +1,13 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>
|
||||
VNC viewer for Java
|
||||
</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<APPLET CODE=vncviewer/VNCViewer.class ARCHIVE=vncviewer.jar
|
||||
WIDTH=400 HEIGHT=250>
|
||||
<PARAM name="port" value="$PORT">
|
||||
</APPLET>
|
||||
</BODY>
|
||||
</HTML>
|
BIN
java/logo150x150.gif
Normal file
BIN
java/logo150x150.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
BIN
java/vncviewer.jar
Normal file
BIN
java/vncviewer.jar
Normal file
Binary file not shown.
202
logmessages/logmessages.dsp
Normal file
202
logmessages/logmessages.dsp
Normal file
|
@ -0,0 +1,202 @@
|
|||
# Microsoft Developer Studio Project File - Name="logmessages" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=logmessages - Win32 Debug Unicode
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "logmessages.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "logmessages.mak" CFG="logmessages - Win32 Debug Unicode"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "logmessages - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "logmessages - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "logmessages - Win32 Debug Unicode" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "logmessages - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "..\Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LOGMESSAGES_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "LOGMESSAGES_EXPORTS" /D "WIN32" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "NDEBUG"
|
||||
# ADD RSC /l 0x809 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 /nologo /dll /machine:I386 /out:"messages.mc"
|
||||
# Begin Custom Build
|
||||
InputPath=.\messages.mc
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
BuildCmds= \
|
||||
mc messages.mc \
|
||||
rc -r -fo messages.res messages.rc \
|
||||
link -dll -noentry -out:..\Release\logmessages.dll messages.res \
|
||||
|
||||
|
||||
"messages.res" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"messages.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"messages.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"..\Release\logmessages.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "logmessages - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "../Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LOGMESSAGES_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /D "LOGMESSAGES_EXPORTS" /D "WIN32" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 /nologo /dll /debug /machine:I386 /nodefaultlib /out:"messages.mc" /pdbtype:sept
|
||||
# Begin Custom Build
|
||||
InputPath=.\messages.mc
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
BuildCmds= \
|
||||
mc messages.mc \
|
||||
rc -r -fo messages.res messages.rc \
|
||||
link -dll -noentry -out:..\Debug\logmessages.dll messages.res \
|
||||
|
||||
|
||||
"messages.res" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"messages.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"messages.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"..\Debug\logmessages.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "logmessages - Win32 Debug Unicode"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "logmessages___Win32_Debug_Unicode"
|
||||
# PROP BASE Intermediate_Dir "logmessages___Win32_Debug_Unicode"
|
||||
# PROP BASE Ignore_Export_Lib 1
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "..\Debug_Unicode"
|
||||
# PROP Intermediate_Dir "Debug_Unicode"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /D "LOGMESSAGES_EXPORTS" /D "WIN32" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_WINDOWS" /D "_USRDLL" /D "LOGMESSAGES_EXPORTS" /D "_DEBUG" /D "WIN32" /D "_UNICODE" /D "UNICODE" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 /nologo /dll /debug /machine:I386 /nodefaultlib /out:"messages.mc" /pdbtype:sept
|
||||
# ADD LINK32 /nologo /dll /debug /machine:I386 /nodefaultlib /out:"messages.mc" /pdbtype:sept
|
||||
# Begin Custom Build
|
||||
InputPath=.\messages.mc
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
BuildCmds= \
|
||||
mc messages.mc \
|
||||
rc -r -fo messages.res messages.rc \
|
||||
link -dll -noentry -out:..\Debug\logmessages.dll messages.res \
|
||||
|
||||
|
||||
"messages.res" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"messages.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"messages.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"..\Debug\logmessages.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "logmessages - Win32 Release"
|
||||
# Name "logmessages - Win32 Debug"
|
||||
# Name "logmessages - Win32 Debug Unicode"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\messages.mc
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
47
logmessages/messages.h
Normal file
47
logmessages/messages.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// Values are 32 bit values layed out as follows:
|
||||
//
|
||||
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
|
||||
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
// +---+-+-+-----------------------+-------------------------------+
|
||||
// |Sev|C|R| Facility | Code |
|
||||
// +---+-+-+-----------------------+-------------------------------+
|
||||
//
|
||||
// where
|
||||
//
|
||||
// Sev - is the severity code
|
||||
//
|
||||
// 00 - Success
|
||||
// 01 - Informational
|
||||
// 10 - Warning
|
||||
// 11 - Error
|
||||
//
|
||||
// C - is the Customer code flag
|
||||
//
|
||||
// R - is a reserved bit
|
||||
//
|
||||
// Facility - is the facility code
|
||||
//
|
||||
// Code - is the facility's status code
|
||||
//
|
||||
//
|
||||
// Define the facility codes
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Define the severity codes
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// MessageId: VNC4LogMessage
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// %1: %2
|
||||
//
|
||||
//
|
||||
//
|
||||
#define VNC4LogMessage 0x00000001L
|
||||
|
7
logmessages/messages.mc
Normal file
7
logmessages/messages.mc
Normal file
|
@ -0,0 +1,7 @@
|
|||
MessageId=0x1
|
||||
Severity=Success
|
||||
SymbolicName=VNC4LogMessage
|
||||
Language=English
|
||||
%1: %2
|
||||
|
||||
|
2
logmessages/messages.rc
Normal file
2
logmessages/messages.rc
Normal file
|
@ -0,0 +1,2 @@
|
|||
LANGUAGE 0x9,0x1
|
||||
1 11 MSG00001.bin
|
17
network/Makefile.in
Normal file
17
network/Makefile.in
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
SRCS = TcpSocket.cxx
|
||||
|
||||
OBJS = $(SRCS:.cxx=.o)
|
||||
|
||||
DIR_CPPFLAGS = -I$(top_srcdir) @SOCKLEN_T_DEFINE@
|
||||
|
||||
library = libnetwork.a
|
||||
|
||||
all:: $(library)
|
||||
|
||||
$(library): $(OBJS)
|
||||
rm -f $(library)
|
||||
$(AR) $(library) $(OBJS)
|
||||
$(RANLIB) $(library)
|
||||
|
||||
# followed by boilerplate.mk
|
129
network/Socket.h
Normal file
129
network/Socket.h
Normal file
|
@ -0,0 +1,129 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
// -=- Socket.h - abstract base-class for any kind of network stream/socket
|
||||
|
||||
#ifndef __NETWORK_SOCKET_H__
|
||||
#define __NETWORK_SOCKET_H__
|
||||
|
||||
#include <rdr/FdInStream.h>
|
||||
#include <rdr/FdOutStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
namespace network {
|
||||
|
||||
class Socket {
|
||||
public:
|
||||
Socket(int fd)
|
||||
: instream(new rdr::FdInStream(fd)),
|
||||
outstream(new rdr::FdOutStream(fd)),
|
||||
own_streams(true) {}
|
||||
virtual ~Socket() {
|
||||
if (own_streams) {
|
||||
delete instream;
|
||||
delete outstream;
|
||||
}
|
||||
}
|
||||
rdr::FdInStream &inStream() {return *instream;}
|
||||
rdr::FdOutStream &outStream() {return *outstream;}
|
||||
int getFd() {return outstream->getFd();}
|
||||
virtual void shutdown() = 0;
|
||||
|
||||
// information about this end of the socket
|
||||
virtual char* getMyAddress() = 0; // a string e.g. "192.168.0.1"
|
||||
virtual int getMyPort() = 0;
|
||||
virtual char* getMyEndpoint() = 0; // <address>::<port>
|
||||
|
||||
// information about the remote end of the socket
|
||||
virtual char* getPeerAddress() = 0; // a string e.g. "192.168.0.1"
|
||||
virtual int getPeerPort() = 0;
|
||||
virtual char* getPeerEndpoint() = 0; // <address>::<port>
|
||||
|
||||
// Is the remote end on the same machine?
|
||||
virtual bool sameMachine() = 0;
|
||||
|
||||
protected:
|
||||
Socket() : instream(0), outstream(0), own_streams(false) {}
|
||||
Socket(rdr::FdInStream* i, rdr::FdOutStream* o, bool own)
|
||||
: instream(i), outstream(o), own_streams(own) {}
|
||||
rdr::FdInStream* instream;
|
||||
rdr::FdOutStream* outstream;
|
||||
bool own_streams;
|
||||
};
|
||||
|
||||
class ConnectionFilter {
|
||||
public:
|
||||
virtual bool verifyConnection(Socket* s) = 0;
|
||||
virtual bool queryUserAcceptConnection(Socket*) {return false;}
|
||||
};
|
||||
|
||||
class SocketListener {
|
||||
public:
|
||||
SocketListener() : fd(0), filter(0) {}
|
||||
virtual ~SocketListener() {}
|
||||
|
||||
// shutdown() stops the socket from accepting further connections
|
||||
virtual void shutdown() = 0;
|
||||
|
||||
// accept() returns a new Socket object if there is a connection
|
||||
// attempt in progress AND if the connection passes the filter
|
||||
// if one is installed. Otherwise, returns 0.
|
||||
virtual Socket* accept() = 0;
|
||||
|
||||
void setFilter(ConnectionFilter* f) {filter = f;}
|
||||
int getFd() {return fd;}
|
||||
protected:
|
||||
int fd;
|
||||
ConnectionFilter* filter;
|
||||
};
|
||||
|
||||
struct SocketException : public rdr::SystemException {
|
||||
SocketException(const char* text, int err_) : rdr::SystemException(text, err_) {}
|
||||
};
|
||||
|
||||
class SocketServer {
|
||||
public:
|
||||
virtual ~SocketServer() {}
|
||||
|
||||
// addClient() tells the server to manage the socket.
|
||||
// If the server can't manage the socket, it must shutdown() it.
|
||||
virtual void addClient(network::Socket* sock) = 0;
|
||||
|
||||
// processSocketEvent() tells the server there is a socket read event.
|
||||
// If there is an error, or the socket has been closed/shutdown then
|
||||
// the server MUST delete the socket AND return false.
|
||||
virtual bool processSocketEvent(network::Socket* sock) = 0;
|
||||
|
||||
// checkTimeouts() allows the server to check socket timeouts, etc. The
|
||||
// return value is the number of milliseconds to wait before
|
||||
// checkTimeouts() should be called again. If this number is zero then
|
||||
// there is no timeout and checkTimeouts() should be called the next time
|
||||
// an event occurs.
|
||||
virtual int checkTimeouts() = 0;
|
||||
|
||||
// soonestTimeout() is a function to help work out the soonest of several
|
||||
// timeouts.
|
||||
static void soonestTimeout(int* timeout, int newTimeout) {
|
||||
if (newTimeout && (!*timeout || newTimeout < *timeout))
|
||||
*timeout = newTimeout;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __NETWORK_SOCKET_H__
|
458
network/TcpSocket.cxx
Normal file
458
network/TcpSocket.cxx
Normal file
|
@ -0,0 +1,458 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
//#include <io.h>
|
||||
#include <winsock2.h>
|
||||
#define errorNumber WSAGetLastError()
|
||||
#define snprintf _snprintf
|
||||
#else
|
||||
#define errorNumber errno
|
||||
#define closesocket close
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <network/TcpSocket.h>
|
||||
#include <rfb/util.h>
|
||||
#include <rfb/LogWriter.h>
|
||||
|
||||
#ifndef VNC_SOCKLEN_T
|
||||
#define VNC_SOCKLEN_T int
|
||||
#endif
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE ((unsigned long)-1)
|
||||
#endif
|
||||
|
||||
using namespace network;
|
||||
using namespace rdr;
|
||||
|
||||
static rfb::LogWriter vlog("TcpSocket");
|
||||
|
||||
|
||||
void
|
||||
TcpSocket::initTcpSockets() {
|
||||
#ifdef WIN32
|
||||
WORD requiredVersion = MAKEWORD(2,0);
|
||||
WSADATA initResult;
|
||||
|
||||
if (WSAStartup(requiredVersion, &initResult) != 0)
|
||||
throw SocketException("unable to initialise Winsock2", errorNumber);
|
||||
#else
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
}
|
||||
|
||||
// -=- TcpSocket
|
||||
|
||||
TcpSocket::TcpSocket(int sock, bool close)
|
||||
: Socket(new FdInStream(sock), new FdOutStream(sock), true), closeFd(close)
|
||||
{
|
||||
}
|
||||
|
||||
TcpSocket::TcpSocket(const char *host, int port)
|
||||
: closeFd(true)
|
||||
{
|
||||
int sock;
|
||||
|
||||
// - Create a socket
|
||||
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
throw SocketException("unable to create socket", errorNumber);
|
||||
|
||||
#ifndef WIN32
|
||||
// - By default, close the socket on exec()
|
||||
fcntl(sock, F_SETFD, FD_CLOEXEC);
|
||||
#endif
|
||||
|
||||
// - Connect it to something
|
||||
|
||||
// Try processing the host as an IP address
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = inet_addr(host);
|
||||
addr.sin_port = htons(port);
|
||||
if ((int)addr.sin_addr.s_addr == -1) {
|
||||
// Host was not an IP address - try resolving as DNS name
|
||||
struct hostent *hostinfo;
|
||||
hostinfo = gethostbyname(host);
|
||||
if (hostinfo && hostinfo->h_addr) {
|
||||
addr.sin_addr.s_addr = ((struct in_addr *)hostinfo->h_addr)->s_addr;
|
||||
} else {
|
||||
int e = errorNumber;
|
||||
closesocket(sock);
|
||||
throw SocketException("unable to resolve host by name", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to connect to the remote host
|
||||
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
|
||||
int e = errorNumber;
|
||||
closesocket(sock);
|
||||
throw SocketException("unable to connect to host", e);
|
||||
}
|
||||
|
||||
int one = 1;
|
||||
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
|
||||
(char *)&one, sizeof(one)) < 0) {
|
||||
int e = errorNumber;
|
||||
closesocket(sock);
|
||||
throw SocketException("unable to setsockopt TCP_NODELAY", e);
|
||||
}
|
||||
|
||||
// Create the input and output streams
|
||||
instream = new FdInStream(sock);
|
||||
outstream = new FdOutStream(sock);
|
||||
own_streams = true;
|
||||
}
|
||||
|
||||
TcpSocket::~TcpSocket() {
|
||||
if (closeFd)
|
||||
closesocket(getFd());
|
||||
}
|
||||
|
||||
char* TcpSocket::getMyAddress() {
|
||||
struct sockaddr_in info;
|
||||
struct in_addr addr;
|
||||
VNC_SOCKLEN_T info_size = sizeof(info);
|
||||
|
||||
getsockname(getFd(), (struct sockaddr *)&info, &info_size);
|
||||
memcpy(&addr, &info.sin_addr, sizeof(addr));
|
||||
|
||||
char* name = inet_ntoa(addr);
|
||||
if (name) {
|
||||
return rfb::strDup(name);
|
||||
} else {
|
||||
return rfb::strDup("");
|
||||
}
|
||||
}
|
||||
|
||||
int TcpSocket::getMyPort() {
|
||||
return getSockPort(getFd());
|
||||
}
|
||||
|
||||
char* TcpSocket::getMyEndpoint() {
|
||||
rfb::CharArray address; address.buf = getMyAddress();
|
||||
int port = getMyPort();
|
||||
|
||||
int buflen = strlen(address.buf) + 32;
|
||||
char* buffer = new char[buflen];
|
||||
sprintf(buffer, "%s::%d", address.buf, port);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char* TcpSocket::getPeerAddress() {
|
||||
struct sockaddr_in info;
|
||||
struct in_addr addr;
|
||||
VNC_SOCKLEN_T info_size = sizeof(info);
|
||||
|
||||
getpeername(getFd(), (struct sockaddr *)&info, &info_size);
|
||||
memcpy(&addr, &info.sin_addr, sizeof(addr));
|
||||
|
||||
char* name = inet_ntoa(addr);
|
||||
if (name) {
|
||||
return rfb::strDup(name);
|
||||
} else {
|
||||
return rfb::strDup("");
|
||||
}
|
||||
}
|
||||
|
||||
int TcpSocket::getPeerPort() {
|
||||
struct sockaddr_in info;
|
||||
VNC_SOCKLEN_T info_size = sizeof(info);
|
||||
|
||||
getpeername(getFd(), (struct sockaddr *)&info, &info_size);
|
||||
return ntohs(info.sin_port);
|
||||
}
|
||||
|
||||
char* TcpSocket::getPeerEndpoint() {
|
||||
rfb::CharArray address; address.buf = getPeerAddress();
|
||||
int port = getPeerPort();
|
||||
|
||||
int buflen = strlen(address.buf) + 32;
|
||||
char* buffer = new char[buflen];
|
||||
sprintf(buffer, "%s::%d", address.buf, port);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
bool TcpSocket::sameMachine() {
|
||||
struct sockaddr_in peeraddr, myaddr;
|
||||
VNC_SOCKLEN_T addrlen = sizeof(struct sockaddr_in);
|
||||
|
||||
getpeername(getFd(), (struct sockaddr *)&peeraddr, &addrlen);
|
||||
getsockname(getFd(), (struct sockaddr *)&myaddr, &addrlen);
|
||||
|
||||
return (peeraddr.sin_addr.s_addr == myaddr.sin_addr.s_addr);
|
||||
}
|
||||
|
||||
void TcpSocket::shutdown()
|
||||
{
|
||||
::shutdown(getFd(), 2);
|
||||
}
|
||||
|
||||
bool TcpSocket::isSocket(int sock)
|
||||
{
|
||||
struct sockaddr_in info;
|
||||
VNC_SOCKLEN_T info_size = sizeof(info);
|
||||
return getsockname(sock, (struct sockaddr *)&info, &info_size) >= 0;
|
||||
}
|
||||
|
||||
bool TcpSocket::isConnected(int sock)
|
||||
{
|
||||
struct sockaddr_in info;
|
||||
VNC_SOCKLEN_T info_size = sizeof(info);
|
||||
return getpeername(sock, (struct sockaddr *)&info, &info_size) >= 0;
|
||||
}
|
||||
|
||||
int TcpSocket::getSockPort(int sock)
|
||||
{
|
||||
struct sockaddr_in info;
|
||||
VNC_SOCKLEN_T info_size = sizeof(info);
|
||||
if (getsockname(sock, (struct sockaddr *)&info, &info_size) < 0)
|
||||
return 0;
|
||||
return ntohs(info.sin_port);
|
||||
}
|
||||
|
||||
|
||||
TcpListener::TcpListener(int port, bool localhostOnly, int sock, bool close_)
|
||||
: closeFd(close_)
|
||||
{
|
||||
if (sock != -1) {
|
||||
fd = sock;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
throw SocketException("unable to create listening socket", errorNumber);
|
||||
|
||||
#ifndef WIN32
|
||||
// - By default, close the socket on exec()
|
||||
fcntl(sock, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
int one = 1;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
|
||||
(const char *)&one, sizeof(one)) < 0) {
|
||||
int e = errorNumber;
|
||||
closesocket(fd);
|
||||
throw SocketException("unable to create listening socket", e);
|
||||
}
|
||||
#endif
|
||||
|
||||
// - Bind it to the desired port
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
if (localhostOnly)
|
||||
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
else
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
int e = errorNumber;
|
||||
closesocket(fd);
|
||||
throw SocketException("unable to bind listening socket", e);
|
||||
}
|
||||
|
||||
// - Set it to be a listening socket
|
||||
if (listen(fd, 5) < 0) {
|
||||
int e = errorNumber;
|
||||
closesocket(fd);
|
||||
throw SocketException("unable to set socket to listening mode", e);
|
||||
}
|
||||
}
|
||||
|
||||
TcpListener::~TcpListener() {
|
||||
if (closeFd) closesocket(fd);
|
||||
}
|
||||
|
||||
void TcpListener::shutdown()
|
||||
{
|
||||
#ifdef WIN32
|
||||
closesocket(getFd());
|
||||
#else
|
||||
::shutdown(getFd(), 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Socket*
|
||||
TcpListener::accept() {
|
||||
int new_sock = -1;
|
||||
|
||||
// Accept an incoming connection
|
||||
if ((new_sock = ::accept(fd, 0, 0)) < 0)
|
||||
throw SocketException("unable to accept new connection", errorNumber);
|
||||
|
||||
#ifndef WIN32
|
||||
// - By default, close the socket on exec()
|
||||
fcntl(new_sock, F_SETFD, FD_CLOEXEC);
|
||||
#endif
|
||||
|
||||
// Disable Nagle's algorithm
|
||||
int one = 1;
|
||||
if (setsockopt(new_sock, IPPROTO_TCP, TCP_NODELAY,
|
||||
(char *)&one, sizeof(one)) < 0) {
|
||||
int e = errorNumber;
|
||||
closesocket(new_sock);
|
||||
throw SocketException("unable to setsockopt TCP_NODELAY", e);
|
||||
}
|
||||
|
||||
// Create the socket object & check connection is allowed
|
||||
TcpSocket* s = new TcpSocket(new_sock);
|
||||
if (filter && !filter->verifyConnection(s)) {
|
||||
delete s;
|
||||
return 0;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void TcpListener::getMyAddresses(std::list<char*>* result) {
|
||||
const hostent* addrs = gethostbyname(0);
|
||||
if (addrs == 0)
|
||||
throw rdr::SystemException("gethostbyname", errorNumber);
|
||||
if (addrs->h_addrtype != AF_INET)
|
||||
throw rdr::Exception("getMyAddresses: bad family");
|
||||
for (int i=0; addrs->h_addr_list[i] != 0; i++) {
|
||||
const char* addrC = inet_ntoa(*((struct in_addr*)addrs->h_addr_list[i]));
|
||||
char* addr = new char[strlen(addrC)+1];
|
||||
strcpy(addr, addrC);
|
||||
result->push_back(addr);
|
||||
}
|
||||
}
|
||||
|
||||
int TcpListener::getMyPort() {
|
||||
return TcpSocket::getSockPort(getFd());
|
||||
}
|
||||
|
||||
|
||||
TcpFilter::TcpFilter(const char* spec) {
|
||||
rfb::CharArray tmp;
|
||||
tmp.buf = rfb::strDup(spec);
|
||||
while (tmp.buf) {
|
||||
rfb::CharArray first;
|
||||
rfb::strSplit(tmp.buf, ',', &first.buf, &tmp.buf);
|
||||
if (strlen(first.buf))
|
||||
filter.push_back(parsePattern(first.buf));
|
||||
}
|
||||
}
|
||||
|
||||
TcpFilter::~TcpFilter() {
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
patternMatchIP(const TcpFilter::Pattern& pattern, const char* value) {
|
||||
unsigned long address = inet_addr(value);
|
||||
if (address == INADDR_NONE) return false;
|
||||
return ((pattern.address & pattern.mask) == (address & pattern.mask));
|
||||
}
|
||||
|
||||
bool
|
||||
TcpFilter::verifyConnection(Socket* s) {
|
||||
rfb::CharArray name;
|
||||
|
||||
name.buf = s->getPeerAddress();
|
||||
std::list<TcpFilter::Pattern>::iterator i;
|
||||
for (i=filter.begin(); i!=filter.end(); i++) {
|
||||
if (patternMatchIP(*i, name.buf)) {
|
||||
switch ((*i).action) {
|
||||
case Accept:
|
||||
vlog.debug("ACCEPT %s", name.buf);
|
||||
return true;
|
||||
case Query:
|
||||
vlog.debug("QUERY %s", name.buf);
|
||||
return queryUserAcceptConnection(s);
|
||||
case Reject:
|
||||
vlog.debug("REJECT %s", name.buf);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vlog.debug("[REJECT] %s", name.buf);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
TcpFilter::Pattern TcpFilter::parsePattern(const char* p) {
|
||||
TcpFilter::Pattern pattern;
|
||||
|
||||
bool expandMask = false;
|
||||
rfb::CharArray addr, mask;
|
||||
|
||||
if (rfb::strSplit(&p[1], '/', &addr.buf, &mask.buf)) {
|
||||
if (rfb::strContains(mask.buf, '.')) {
|
||||
pattern.mask = inet_addr(mask.buf);
|
||||
} else {
|
||||
pattern.mask = atoi(mask.buf);
|
||||
expandMask = true;
|
||||
}
|
||||
} else {
|
||||
pattern.mask = 32;
|
||||
expandMask = true;
|
||||
}
|
||||
if (expandMask) {
|
||||
unsigned long expanded = 0;
|
||||
// *** check endianness!
|
||||
for (int i=0; i<(int)pattern.mask; i++)
|
||||
expanded |= 1<<(31-i);
|
||||
pattern.mask = htonl(expanded);
|
||||
}
|
||||
|
||||
pattern.address = inet_addr(addr.buf) & pattern.mask;
|
||||
if ((pattern.address == INADDR_NONE) ||
|
||||
(pattern.address == 0)) pattern.mask = 0;
|
||||
|
||||
switch(p[0]) {
|
||||
case '+': pattern.action = TcpFilter::Accept; break;
|
||||
case '-': pattern.action = TcpFilter::Reject; break;
|
||||
case '?': pattern.action = TcpFilter::Query; break;
|
||||
};
|
||||
|
||||
return pattern;
|
||||
}
|
||||
|
||||
char* TcpFilter::patternToStr(const TcpFilter::Pattern& p) {
|
||||
in_addr tmp;
|
||||
rfb::CharArray addr, mask;
|
||||
tmp.s_addr = p.address;
|
||||
addr.buf = rfb::strDup(inet_ntoa(tmp));
|
||||
tmp.s_addr = p.mask;
|
||||
mask.buf = rfb::strDup(inet_ntoa(tmp));
|
||||
char* result = new char[strlen(addr.buf)+1+strlen(mask.buf)+1+1];
|
||||
switch (p.action) {
|
||||
case Accept: result[0] = '+'; break;
|
||||
case Reject: result[0] = '-'; break;
|
||||
case Query: result[0] = '?'; break;
|
||||
};
|
||||
result[1] = 0;
|
||||
strcat(result, addr.buf);
|
||||
strcat(result, "/");
|
||||
strcat(result, mask.buf);
|
||||
return result;
|
||||
}
|
100
network/TcpSocket.h
Normal file
100
network/TcpSocket.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
// -=- TcpSocket.h - base-class for TCP stream sockets.
|
||||
// This header also defines the TcpListener class, used
|
||||
// to listen for incoming socket connections over TCP
|
||||
//
|
||||
// NB: Any file descriptors created by the TcpSocket or
|
||||
// TcpListener classes are close-on-exec if the OS supports
|
||||
// it. TcpSockets initialised with a caller-supplied fd
|
||||
// are NOT set to close-on-exec.
|
||||
|
||||
#ifndef __NETWORK_TCP_SOCKET_H__
|
||||
#define __NETWORK_TCP_SOCKET_H__
|
||||
|
||||
#include <network/Socket.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace network {
|
||||
|
||||
class TcpSocket : public Socket {
|
||||
public:
|
||||
TcpSocket(int sock, bool close=true);
|
||||
TcpSocket(const char *name, int port);
|
||||
virtual ~TcpSocket();
|
||||
|
||||
virtual char* getMyAddress();
|
||||
virtual int getMyPort();
|
||||
virtual char* getMyEndpoint();
|
||||
|
||||
virtual char* getPeerAddress();
|
||||
virtual int getPeerPort();
|
||||
virtual char* getPeerEndpoint();
|
||||
virtual bool sameMachine();
|
||||
|
||||
virtual void shutdown();
|
||||
|
||||
static void initTcpSockets();
|
||||
|
||||
static bool isSocket(int sock);
|
||||
static bool isConnected(int sock);
|
||||
static int getSockPort(int sock);
|
||||
private:
|
||||
bool closeFd;
|
||||
};
|
||||
|
||||
class TcpListener : public SocketListener {
|
||||
public:
|
||||
TcpListener(int port, bool localhostOnly=false, int sock=-1,
|
||||
bool close=true);
|
||||
virtual ~TcpListener();
|
||||
|
||||
virtual void shutdown();
|
||||
virtual Socket* accept();
|
||||
|
||||
void getMyAddresses(std::list<char*>* addrs);
|
||||
int getMyPort();
|
||||
|
||||
private:
|
||||
bool closeFd;
|
||||
};
|
||||
|
||||
class TcpFilter : public ConnectionFilter {
|
||||
public:
|
||||
TcpFilter(const char* filter);
|
||||
virtual ~TcpFilter();
|
||||
|
||||
virtual bool verifyConnection(Socket* s);
|
||||
|
||||
typedef enum {Accept, Reject, Query} Action;
|
||||
struct Pattern {
|
||||
Action action;
|
||||
unsigned long address;
|
||||
unsigned long mask;
|
||||
};
|
||||
static Pattern parsePattern(const char* s);
|
||||
static char* patternToStr(const Pattern& p);
|
||||
protected:
|
||||
std::list<Pattern> filter;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __NETWORK_TCP_SOCKET_H__
|
18
network/msvcwarning.h
Normal file
18
network/msvcwarning.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#pragma warning( disable : 4800 ) // forcing bool 'true' or 'false'
|
129
network/network.dsp
Normal file
129
network/network.dsp
Normal file
|
@ -0,0 +1,129 @@
|
|||
# Microsoft Developer Studio Project File - Name="network" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=network - Win32 Debug Unicode
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "network.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "network.mak" CFG="network - Win32 Debug Unicode"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "network - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "network - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "network - Win32 Debug Unicode" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "network - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O1 /I ".." /FI"msvcwarning.h" /D "NDEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x809 /d "NDEBUG"
|
||||
# ADD RSC /l 0x809 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "network - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /FI"msvcwarning.h" /D "_DEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "network - Win32 Debug Unicode"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "network___Win32_Debug_Unicode"
|
||||
# PROP BASE Intermediate_Dir "network___Win32_Debug_Unicode"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug_Unicode"
|
||||
# PROP Intermediate_Dir "Debug_Unicode"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /FI"msvcwarning.h" /D "_DEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /FI"msvcwarning.h" /D "_LIB" /D "_DEBUG" /D "WIN32" /D "_UNICODE" /D "UNICODE" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "network - Win32 Release"
|
||||
# Name "network - Win32 Debug"
|
||||
# Name "network - Win32 Debug Unicode"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TcpSocket.cxx
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Socket.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TcpSocket.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
64
rdr/Exception.cxx
Normal file
64
rdr/Exception.cxx
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#include <rdr/Exception.h>
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
SystemException::SystemException(const char* s, int err_)
|
||||
: Exception(s, "rdr::SystemException"), err(err_)
|
||||
{
|
||||
strncat(str_, ": ", len-1-strlen(str_));
|
||||
#ifdef _WIN32
|
||||
// Windows error messages are crap, so use unix ones for common errors.
|
||||
const char* msg = 0;
|
||||
switch (err) {
|
||||
case WSAECONNREFUSED: msg = "Connection refused"; break;
|
||||
case WSAETIMEDOUT: msg = "Connection timed out"; break;
|
||||
case WSAECONNRESET: msg = "Connection reset by peer"; break;
|
||||
case WSAECONNABORTED: msg = "Connection aborted"; break;
|
||||
}
|
||||
if (msg) {
|
||||
strncat(str_, msg, len-1-strlen(str_));
|
||||
} else {
|
||||
#ifdef UNICODE
|
||||
WCHAR* tmsg = new WCHAR[len-strlen(str_)];
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
0, err, 0, tmsg, len-1-strlen(str_), 0);
|
||||
WideCharToMultiByte(CP_ACP, 0, tmsg, wcslen(tmsg)+1,
|
||||
str_+strlen(str_), len-strlen(str_), 0, 0);
|
||||
delete [] tmsg;
|
||||
#else
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
0, err, 0, str_+strlen(str_), len-1-strlen(str_), 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
strncat(str_, strerror(err), len-1-strlen(str_));
|
||||
#endif
|
||||
strncat(str_, " (", len-1-strlen(str_));
|
||||
char buf[20];
|
||||
sprintf(buf,"%d",err);
|
||||
strncat(str_, buf, len-1-strlen(str_));
|
||||
strncat(str_, ")", len-1-strlen(str_));
|
||||
}
|
59
rdr/Exception.h
Normal file
59
rdr/Exception.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_EXCEPTION_H__
|
||||
#define __RDR_EXCEPTION_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
struct Exception {
|
||||
enum { len = 256 };
|
||||
char str_[len];
|
||||
char type_[len];
|
||||
Exception(const char* s=0, const char* e="rdr::Exception") {
|
||||
str_[0] = 0;
|
||||
if (s)
|
||||
strncat(str_, s, len-1);
|
||||
else
|
||||
strcat(str_, "Exception");
|
||||
type_[0] = 0;
|
||||
strncat(type_, e, len-1);
|
||||
}
|
||||
virtual const char* str() const { return str_; }
|
||||
virtual const char* type() const { return type_; }
|
||||
};
|
||||
|
||||
struct SystemException : public Exception {
|
||||
int err;
|
||||
SystemException(const char* s, int err_);
|
||||
};
|
||||
|
||||
struct TimedOut : public Exception {
|
||||
TimedOut(const char* s="Timed out") : Exception(s,"rdr::TimedOut") {}
|
||||
};
|
||||
|
||||
struct EndOfStream : public Exception {
|
||||
EndOfStream(const char* s="End of stream")
|
||||
: Exception(s,"rdr::EndOfStream") {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
281
rdr/FdInStream.cxx
Normal file
281
rdr/FdInStream.cxx
Normal file
|
@ -0,0 +1,281 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#ifndef _WIN32_WCE
|
||||
#include <sys/timeb.h>
|
||||
#endif
|
||||
#define read(s,b,l) recv(s,(char*)b,l,0)
|
||||
#define close closesocket
|
||||
#undef errno
|
||||
#define errno WSAGetLastError()
|
||||
#undef EINTR
|
||||
#define EINTR WSAEINTR
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
// XXX should use autoconf HAVE_SYS_SELECT_H
|
||||
#ifdef _AIX
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#include <rdr/FdInStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
enum { DEFAULT_BUF_SIZE = 8192,
|
||||
MIN_BULK_SIZE = 1024 };
|
||||
|
||||
FdInStream::FdInStream(int fd_, int timeoutms_, int bufSize_,
|
||||
bool closeWhenDone_)
|
||||
: fd(fd_), closeWhenDone(closeWhenDone_),
|
||||
timeoutms(timeoutms_), blockCallback(0),
|
||||
timing(false), timeWaitedIn100us(5), timedKbits(0),
|
||||
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
|
||||
{
|
||||
ptr = end = start = new U8[bufSize];
|
||||
}
|
||||
|
||||
FdInStream::FdInStream(int fd_, FdInStreamBlockCallback* blockCallback_,
|
||||
int bufSize_)
|
||||
: fd(fd_), timeoutms(0), blockCallback(blockCallback_),
|
||||
timing(false), timeWaitedIn100us(5), timedKbits(0),
|
||||
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
|
||||
{
|
||||
ptr = end = start = new U8[bufSize];
|
||||
}
|
||||
|
||||
FdInStream::~FdInStream()
|
||||
{
|
||||
delete [] start;
|
||||
if (closeWhenDone) close(fd);
|
||||
}
|
||||
|
||||
|
||||
void FdInStream::setTimeout(int timeoutms_) {
|
||||
timeoutms = timeoutms_;
|
||||
}
|
||||
|
||||
void FdInStream::setBlockCallback(FdInStreamBlockCallback* blockCallback_)
|
||||
{
|
||||
blockCallback = blockCallback_;
|
||||
timeoutms = 0;
|
||||
}
|
||||
|
||||
int FdInStream::pos()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
void FdInStream::readBytes(void* data, int length)
|
||||
{
|
||||
if (length < MIN_BULK_SIZE) {
|
||||
InStream::readBytes(data, length);
|
||||
return;
|
||||
}
|
||||
|
||||
U8* dataPtr = (U8*)data;
|
||||
|
||||
int n = end - ptr;
|
||||
if (n > length) n = length;
|
||||
|
||||
memcpy(dataPtr, ptr, n);
|
||||
dataPtr += n;
|
||||
length -= n;
|
||||
ptr += n;
|
||||
|
||||
while (length > 0) {
|
||||
n = readWithTimeoutOrCallback(dataPtr, length);
|
||||
dataPtr += n;
|
||||
length -= n;
|
||||
offset += n;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int FdInStream::overrun(int itemSize, int nItems, bool wait)
|
||||
{
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("FdInStream overrun: max itemSize exceeded");
|
||||
|
||||
if (end - ptr != 0)
|
||||
memmove(start, ptr, end - ptr);
|
||||
|
||||
offset += ptr - start;
|
||||
end -= ptr - start;
|
||||
ptr = start;
|
||||
|
||||
while (end < start + itemSize) {
|
||||
int n = readWithTimeoutOrCallback((U8*)end, start + bufSize - end, wait);
|
||||
if (n == 0) return 0;
|
||||
end += n;
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static void gettimeofday(struct timeval* tv, void*)
|
||||
{
|
||||
LARGE_INTEGER counts, countsPerSec;
|
||||
static double usecPerCount = 0.0;
|
||||
|
||||
if (QueryPerformanceCounter(&counts)) {
|
||||
if (usecPerCount == 0.0) {
|
||||
QueryPerformanceFrequency(&countsPerSec);
|
||||
usecPerCount = 1000000.0 / countsPerSec.QuadPart;
|
||||
}
|
||||
|
||||
LONGLONG usecs = (LONGLONG)(counts.QuadPart * usecPerCount);
|
||||
tv->tv_usec = (long)(usecs % 1000000);
|
||||
tv->tv_sec = (long)(usecs / 1000000);
|
||||
|
||||
} else {
|
||||
#ifndef _WIN32_WCE
|
||||
struct timeb tb;
|
||||
ftime(&tb);
|
||||
tv->tv_sec = tb.time;
|
||||
tv->tv_usec = tb.millitm * 1000;
|
||||
#else
|
||||
throw SystemException("QueryPerformanceCounter", GetLastError());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// readWithTimeoutOrCallback() reads up to the given length in bytes from the
|
||||
// file descriptor into a buffer. If the wait argument is false, then zero is
|
||||
// returned if no bytes can be read without blocking. Otherwise if a
|
||||
// blockCallback is set, it will be called (repeatedly) instead of blocking.
|
||||
// If alternatively there is a timeout set and that timeout expires, it throws
|
||||
// a TimedOut exception. Otherwise it returns the number of bytes read. It
|
||||
// never attempts to read() unless select() indicates that the fd is readable -
|
||||
// this means it can be used on an fd which has been set non-blocking. It also
|
||||
// has to cope with the annoying possibility of both select() and read()
|
||||
// returning EINTR.
|
||||
//
|
||||
|
||||
int FdInStream::readWithTimeoutOrCallback(void* buf, int len, bool wait)
|
||||
{
|
||||
struct timeval before, after;
|
||||
if (timing)
|
||||
gettimeofday(&before, 0);
|
||||
|
||||
int n;
|
||||
while (true) {
|
||||
do {
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
struct timeval* tvp = &tv;
|
||||
|
||||
if (!wait) {
|
||||
tv.tv_sec = tv.tv_usec = 0;
|
||||
} else if (timeoutms != -1) {
|
||||
tv.tv_sec = timeoutms / 1000;
|
||||
tv.tv_usec = (timeoutms % 1000) * 1000;
|
||||
} else {
|
||||
tvp = 0;
|
||||
}
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
n = select(fd+1, &fds, 0, 0, tvp);
|
||||
} while (n < 0 && errno == EINTR);
|
||||
|
||||
if (n > 0) break;
|
||||
if (n < 0) throw SystemException("select",errno);
|
||||
if (!wait) return 0;
|
||||
if (!blockCallback) throw TimedOut();
|
||||
|
||||
blockCallback->blockCallback();
|
||||
}
|
||||
|
||||
do {
|
||||
n = ::read(fd, buf, len);
|
||||
} while (n < 0 && errno == EINTR);
|
||||
|
||||
if (n < 0) throw SystemException("read",errno);
|
||||
if (n == 0) throw EndOfStream();
|
||||
|
||||
if (timing) {
|
||||
gettimeofday(&after, 0);
|
||||
// fprintf(stderr,"%d.%06d\n",(after.tv_sec - before.tv_sec),
|
||||
// (after.tv_usec - before.tv_usec));
|
||||
int newTimeWaited = ((after.tv_sec - before.tv_sec) * 10000 +
|
||||
(after.tv_usec - before.tv_usec) / 100);
|
||||
int newKbits = n * 8 / 1000;
|
||||
|
||||
// if (newTimeWaited == 0) {
|
||||
// fprintf(stderr,"new kbps infinite t %d k %d\n",
|
||||
// newTimeWaited, newKbits);
|
||||
// } else {
|
||||
// fprintf(stderr,"new kbps %d t %d k %d\n",
|
||||
// newKbits * 10000 / newTimeWaited, newTimeWaited, newKbits);
|
||||
// }
|
||||
|
||||
// limit rate to between 10kbit/s and 40Mbit/s
|
||||
|
||||
if (newTimeWaited > newKbits*1000) newTimeWaited = newKbits*1000;
|
||||
if (newTimeWaited < newKbits/4) newTimeWaited = newKbits/4;
|
||||
|
||||
timeWaitedIn100us += newTimeWaited;
|
||||
timedKbits += newKbits;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void FdInStream::startTiming()
|
||||
{
|
||||
timing = true;
|
||||
|
||||
// Carry over up to 1s worth of previous rate for smoothing.
|
||||
|
||||
if (timeWaitedIn100us > 10000) {
|
||||
timedKbits = timedKbits * 10000 / timeWaitedIn100us;
|
||||
timeWaitedIn100us = 10000;
|
||||
}
|
||||
}
|
||||
|
||||
void FdInStream::stopTiming()
|
||||
{
|
||||
timing = false;
|
||||
if (timeWaitedIn100us < timedKbits/2)
|
||||
timeWaitedIn100us = timedKbits/2; // upper limit 20Mbit/s
|
||||
}
|
||||
|
||||
unsigned int FdInStream::kbitsPerSecond()
|
||||
{
|
||||
// The following calculation will overflow 32-bit arithmetic if we have
|
||||
// received more than about 50Mbytes (400Mbits) since we started timing, so
|
||||
// it should be OK for a single RFB update.
|
||||
|
||||
return timedKbits * 10000 / timeWaitedIn100us;
|
||||
}
|
77
rdr/FdInStream.h
Normal file
77
rdr/FdInStream.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// FdInStream streams from a file descriptor.
|
||||
//
|
||||
|
||||
#ifndef __RDR_FDINSTREAM_H__
|
||||
#define __RDR_FDINSTREAM_H__
|
||||
|
||||
#include <rdr/InStream.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class FdInStreamBlockCallback {
|
||||
public:
|
||||
virtual void blockCallback() = 0;
|
||||
};
|
||||
|
||||
class FdInStream : public InStream {
|
||||
|
||||
public:
|
||||
|
||||
FdInStream(int fd, int timeoutms=-1, int bufSize=0,
|
||||
bool closeWhenDone_=false);
|
||||
FdInStream(int fd, FdInStreamBlockCallback* blockCallback, int bufSize=0);
|
||||
virtual ~FdInStream();
|
||||
|
||||
void setTimeout(int timeoutms);
|
||||
void setBlockCallback(FdInStreamBlockCallback* blockCallback);
|
||||
int getFd() { return fd; }
|
||||
int pos();
|
||||
void readBytes(void* data, int length);
|
||||
|
||||
void startTiming();
|
||||
void stopTiming();
|
||||
unsigned int kbitsPerSecond();
|
||||
unsigned int timeWaited() { return timeWaitedIn100us; }
|
||||
|
||||
protected:
|
||||
int overrun(int itemSize, int nItems, bool wait);
|
||||
|
||||
private:
|
||||
int readWithTimeoutOrCallback(void* buf, int len, bool wait=true);
|
||||
|
||||
int fd;
|
||||
bool closeWhenDone;
|
||||
int timeoutms;
|
||||
FdInStreamBlockCallback* blockCallback;
|
||||
|
||||
bool timing;
|
||||
unsigned int timeWaitedIn100us;
|
||||
unsigned int timedKbits;
|
||||
|
||||
int bufSize;
|
||||
int offset;
|
||||
U8* start;
|
||||
};
|
||||
|
||||
} // end of namespace rdr
|
||||
|
||||
#endif
|
174
rdr/FdOutStream.cxx
Normal file
174
rdr/FdOutStream.cxx
Normal file
|
@ -0,0 +1,174 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#define write(s,b,l) send(s,(const char*)b,l,0)
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#undef errno
|
||||
#define errno WSAGetLastError()
|
||||
#undef EINTR
|
||||
#define EINTR WSAEINTR
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <rdr/FdOutStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
enum { DEFAULT_BUF_SIZE = 16384,
|
||||
MIN_BULK_SIZE = 1024 };
|
||||
|
||||
FdOutStream::FdOutStream(int fd_, int timeoutms_, int bufSize_)
|
||||
: fd(fd_), timeoutms(timeoutms_),
|
||||
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
|
||||
{
|
||||
ptr = start = new U8[bufSize];
|
||||
end = start + bufSize;
|
||||
}
|
||||
|
||||
FdOutStream::~FdOutStream()
|
||||
{
|
||||
try {
|
||||
flush();
|
||||
} catch (Exception&) {
|
||||
}
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
void FdOutStream::setTimeout(int timeoutms_) {
|
||||
timeoutms = timeoutms_;
|
||||
}
|
||||
|
||||
void FdOutStream::writeBytes(const void* data, int length)
|
||||
{
|
||||
if (length < MIN_BULK_SIZE) {
|
||||
OutStream::writeBytes(data, length);
|
||||
return;
|
||||
}
|
||||
|
||||
const U8* dataPtr = (const U8*)data;
|
||||
|
||||
flush();
|
||||
|
||||
while (length > 0) {
|
||||
int n = writeWithTimeout(dataPtr, length);
|
||||
length -= n;
|
||||
dataPtr += n;
|
||||
offset += n;
|
||||
}
|
||||
}
|
||||
|
||||
int FdOutStream::length()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
void FdOutStream::flush()
|
||||
{
|
||||
U8* sentUpTo = start;
|
||||
while (sentUpTo < ptr) {
|
||||
int n = writeWithTimeout((const void*) sentUpTo, ptr - sentUpTo);
|
||||
sentUpTo += n;
|
||||
offset += n;
|
||||
}
|
||||
|
||||
ptr = start;
|
||||
}
|
||||
|
||||
|
||||
int FdOutStream::overrun(int itemSize, int nItems)
|
||||
{
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("FdOutStream overrun: max itemSize exceeded");
|
||||
|
||||
flush();
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
//
|
||||
// writeWithTimeout() writes up to the given length in bytes from the given
|
||||
// buffer to the file descriptor. If there is a timeout set and that timeout
|
||||
// expires, it throws a TimedOut exception. Otherwise it returns the number of
|
||||
// bytes written. It never attempts to write() unless select() indicates that
|
||||
// the fd is writable - this means it can be used on an fd which has been set
|
||||
// non-blocking. It also has to cope with the annoying possibility of both
|
||||
// select() and write() returning EINTR.
|
||||
//
|
||||
|
||||
int FdOutStream::writeWithTimeout(const void* data, int length)
|
||||
{
|
||||
int n;
|
||||
|
||||
do {
|
||||
|
||||
do {
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
struct timeval* tvp = &tv;
|
||||
|
||||
if (timeoutms != -1) {
|
||||
tv.tv_sec = timeoutms / 1000;
|
||||
tv.tv_usec = (timeoutms % 1000) * 1000;
|
||||
} else {
|
||||
tvp = 0;
|
||||
}
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
#ifdef _WIN32_WCE
|
||||
// NB: This fixes a broken Winsock2 select() behaviour. select()
|
||||
// never returns for non-blocking sockets, unless they're already
|
||||
// ready to be written to...
|
||||
u_long zero = 0; ioctlsocket(fd, FIONBIO, &zero);
|
||||
#endif
|
||||
n = select(fd+1, 0, &fds, 0, tvp);
|
||||
#ifdef _WIN32_WCE
|
||||
u_long one = 0; ioctlsocket(fd, FIONBIO, &one);
|
||||
#endif
|
||||
} while (n < 0 && errno == EINTR);
|
||||
|
||||
if (n < 0) throw SystemException("select",errno);
|
||||
|
||||
if (n == 0) throw TimedOut();
|
||||
|
||||
do {
|
||||
n = ::write(fd, data, length);
|
||||
} while (n < 0 && (errno == EINTR));
|
||||
|
||||
// NB: This outer loop simply fixes a broken Winsock2 EWOULDBLOCK
|
||||
// condition, found only under Win98 (first edition), with slow
|
||||
// network connections. Should in fact never ever happen...
|
||||
} while (n < 0 && (errno == EWOULDBLOCK));
|
||||
|
||||
if (n < 0) throw SystemException("write",errno);
|
||||
|
||||
return n;
|
||||
}
|
56
rdr/FdOutStream.h
Normal file
56
rdr/FdOutStream.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// FdOutStream streams to a file descriptor.
|
||||
//
|
||||
|
||||
#ifndef __RDR_FDOUTSTREAM_H__
|
||||
#define __RDR_FDOUTSTREAM_H__
|
||||
|
||||
#include <rdr/OutStream.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class FdOutStream : public OutStream {
|
||||
|
||||
public:
|
||||
|
||||
FdOutStream(int fd, int timeoutms=-1, int bufSize=0);
|
||||
virtual ~FdOutStream();
|
||||
|
||||
void setTimeout(int timeoutms);
|
||||
int getFd() { return fd; }
|
||||
|
||||
void flush();
|
||||
int length();
|
||||
void writeBytes(const void* data, int length);
|
||||
|
||||
private:
|
||||
int overrun(int itemSize, int nItems);
|
||||
int writeWithTimeout(const void* data, int length);
|
||||
int fd;
|
||||
int timeoutms;
|
||||
int bufSize;
|
||||
int offset;
|
||||
U8* start;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
52
rdr/FixedMemOutStream.h
Normal file
52
rdr/FixedMemOutStream.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// A FixedMemOutStream writes to a buffer of a fixed length.
|
||||
//
|
||||
|
||||
#ifndef __RDR_FIXEDMEMOUTSTREAM_H__
|
||||
#define __RDR_FIXEDMEMOUTSTREAM_H__
|
||||
|
||||
#include <rdr/OutStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class FixedMemOutStream : public OutStream {
|
||||
|
||||
public:
|
||||
|
||||
FixedMemOutStream(void* buf, int len) {
|
||||
ptr = start = (U8*)buf;
|
||||
end = start + len;
|
||||
}
|
||||
|
||||
int length() { return ptr - start; }
|
||||
void reposition(int pos) { ptr = start + pos; }
|
||||
const void* data() { return (const void*)start; }
|
||||
|
||||
private:
|
||||
|
||||
int overrun(int itemSize, int nItems) { throw EndOfStream(); }
|
||||
U8* start;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
117
rdr/HexInStream.cxx
Normal file
117
rdr/HexInStream.cxx
Normal file
|
@ -0,0 +1,117 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <rdr/HexInStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
const int DEFAULT_BUF_LEN = 16384;
|
||||
|
||||
static inline int min(int a, int b) {return a<b ? a : b;}
|
||||
|
||||
HexInStream::HexInStream(InStream& is, int bufSize_)
|
||||
: bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_LEN), offset(0), in_stream(is)
|
||||
{
|
||||
ptr = end = start = new U8[bufSize];
|
||||
}
|
||||
|
||||
HexInStream::~HexInStream() {
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
|
||||
bool HexInStream::readHexAndShift(char c, int* v) {
|
||||
c=tolower(c);
|
||||
if ((c >= '0') && (c <= '9'))
|
||||
*v = (*v << 4) + (c - '0');
|
||||
else if ((c >= 'a') && (c <= 'f'))
|
||||
*v = (*v << 4) + (c - 'a' + 10);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HexInStream::hexStrToBin(const char* s, char** data, int* length) {
|
||||
int l=strlen(s);
|
||||
if ((l % 2) == 0) {
|
||||
delete [] *data;
|
||||
*data = 0; *length = 0;
|
||||
if (l == 0)
|
||||
return true;
|
||||
*data = new char[l/2];
|
||||
*length = l/2;
|
||||
for(int i=0;i<l;i+=2) {
|
||||
int byte = 0;
|
||||
if (!readHexAndShift(s[i], &byte) ||
|
||||
!readHexAndShift(s[i+1], &byte))
|
||||
goto decodeError;
|
||||
(*data)[i/2] = byte;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
decodeError:
|
||||
delete [] *data;
|
||||
*data = 0;
|
||||
*length = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int HexInStream::pos() {
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
int HexInStream::overrun(int itemSize, int nItems, bool wait) {
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("HexInStream overrun: max itemSize exceeded");
|
||||
|
||||
if (end - ptr != 0)
|
||||
memmove(start, ptr, end - ptr);
|
||||
|
||||
end -= ptr - start;
|
||||
offset += ptr - start;
|
||||
ptr = start;
|
||||
|
||||
while (end < ptr + itemSize) {
|
||||
int n = in_stream.check(2, 1, wait);
|
||||
if (n == 0) return 0;
|
||||
const U8* iptr = in_stream.getptr();
|
||||
const U8* eptr = in_stream.getend();
|
||||
int length = min((eptr - iptr)/2, start + bufSize - end);
|
||||
|
||||
U8* optr = (U8*) end;
|
||||
for (int i=0; i<length; i++) {
|
||||
int v = 0;
|
||||
readHexAndShift(iptr[i*2], &v);
|
||||
readHexAndShift(iptr[i*2+1], &v);
|
||||
optr[i] = v;
|
||||
}
|
||||
|
||||
in_stream.setptr(iptr + length*2);
|
||||
end += length;
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
50
rdr/HexInStream.h
Normal file
50
rdr/HexInStream.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_HEX_INSTREAM_H__
|
||||
#define __RDR_HEX_INSTREAM_H__
|
||||
|
||||
#include <rdr/InStream.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class HexInStream : public InStream {
|
||||
public:
|
||||
|
||||
HexInStream(InStream& is, int bufSize=0);
|
||||
virtual ~HexInStream();
|
||||
|
||||
int pos();
|
||||
|
||||
static bool readHexAndShift(char c, int* v);
|
||||
static bool hexStrToBin(const char* s, char** data, int* length);
|
||||
|
||||
protected:
|
||||
int overrun(int itemSize, int nItems, bool wait);
|
||||
|
||||
private:
|
||||
int bufSize;
|
||||
U8* start;
|
||||
int offset;
|
||||
|
||||
InStream& in_stream;
|
||||
};
|
||||
|
||||
} // end of namespace rdr
|
||||
|
||||
#endif
|
110
rdr/HexOutStream.cxx
Normal file
110
rdr/HexOutStream.cxx
Normal file
|
@ -0,0 +1,110 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <rdr/HexOutStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
const int DEFAULT_BUF_LEN = 16384;
|
||||
|
||||
static inline int min(int a, int b) {return a<b ? a : b;}
|
||||
|
||||
HexOutStream::HexOutStream(OutStream& os, int buflen)
|
||||
: out_stream(os), offset(0), bufSize(buflen ? buflen : DEFAULT_BUF_LEN)
|
||||
{
|
||||
if (bufSize % 2)
|
||||
bufSize--;
|
||||
ptr = start = new U8[bufSize];
|
||||
end = start + bufSize;
|
||||
}
|
||||
|
||||
HexOutStream::~HexOutStream() {
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
|
||||
char HexOutStream::intToHex(int i) {
|
||||
if ((i>=0) && (i<=9))
|
||||
return '0'+i;
|
||||
else if ((i>=10) && (i<=15))
|
||||
return 'a'+(i-10);
|
||||
else
|
||||
throw rdr::Exception("intToHex failed");
|
||||
}
|
||||
|
||||
char* HexOutStream::binToHexStr(const char* data, int length) {
|
||||
char* buffer = new char[length*2+1];
|
||||
for (int i=0; i<length; i++) {
|
||||
buffer[i*2] = intToHex((data[i] >> 4) & 15);
|
||||
buffer[i*2+1] = intToHex((data[i] & 15));
|
||||
if (!buffer[i*2] || !buffer[i*2+1]) {
|
||||
delete [] buffer;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
buffer[length*2] = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HexOutStream::writeBuffer() {
|
||||
U8* pos = start;
|
||||
while (pos != ptr) {
|
||||
out_stream.check(2);
|
||||
U8* optr = out_stream.getptr();
|
||||
U8* oend = out_stream.getend();
|
||||
int length = min(ptr-pos, (oend-optr)/2);
|
||||
|
||||
for (int i=0; i<length; i++) {
|
||||
optr[i*2] = intToHex((pos[i] >> 4) & 0xf);
|
||||
optr[i*2+1] = intToHex(pos[i] & 0xf);
|
||||
}
|
||||
|
||||
out_stream.setptr(optr + length*2);
|
||||
pos += length;
|
||||
}
|
||||
offset += ptr - start;
|
||||
ptr = start;
|
||||
}
|
||||
|
||||
int HexOutStream::length()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
void
|
||||
HexOutStream::flush() {
|
||||
writeBuffer();
|
||||
out_stream.flush();
|
||||
}
|
||||
|
||||
int
|
||||
HexOutStream::overrun(int itemSize, int nItems) {
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("HexOutStream overrun: max itemSize exceeded");
|
||||
|
||||
writeBuffer();
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
51
rdr/HexOutStream.h
Normal file
51
rdr/HexOutStream.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_HEX_OUTSTREAM_H__
|
||||
#define __RDR_HEX_OUTSTREAM_H__
|
||||
|
||||
#include <rdr/OutStream.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class HexOutStream : public OutStream {
|
||||
public:
|
||||
|
||||
HexOutStream(OutStream& os, int buflen=0);
|
||||
virtual ~HexOutStream();
|
||||
|
||||
void flush();
|
||||
int length();
|
||||
|
||||
static char intToHex(int i);
|
||||
static char* binToHexStr(const char* data, int length);
|
||||
|
||||
private:
|
||||
void writeBuffer();
|
||||
int overrun(int itemSize, int nItems);
|
||||
|
||||
OutStream& out_stream;
|
||||
|
||||
U8* start;
|
||||
int offset;
|
||||
int bufSize;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
35
rdr/InStream.cxx
Normal file
35
rdr/InStream.cxx
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <rdr/InStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
U32 InStream::maxStringLength = 65535;
|
||||
|
||||
char* InStream::readString()
|
||||
{
|
||||
U32 len = readU32();
|
||||
if (len > maxStringLength)
|
||||
throw Exception("InStream max string length exceeded");
|
||||
char* str = new char[len+1];
|
||||
readBytes(str, len);
|
||||
str[len] = 0;
|
||||
return str;
|
||||
}
|
153
rdr/InStream.h
Normal file
153
rdr/InStream.h
Normal file
|
@ -0,0 +1,153 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// rdr::InStream marshalls data from a buffer stored in RDR (RFB Data
|
||||
// Representation).
|
||||
//
|
||||
|
||||
#ifndef __RDR_INSTREAM_H__
|
||||
#define __RDR_INSTREAM_H__
|
||||
|
||||
#include <rdr/types.h>
|
||||
#include <string.h> // for memcpy
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class InStream {
|
||||
|
||||
public:
|
||||
|
||||
virtual ~InStream() {}
|
||||
|
||||
// check() ensures there is buffer data for at least one item of size
|
||||
// itemSize bytes. Returns the number of items in the buffer (up to a
|
||||
// maximum of nItems). If wait is false, then instead of blocking to wait
|
||||
// for the bytes, zero is returned if the bytes are not immediately
|
||||
// available.
|
||||
|
||||
inline int check(int itemSize, int nItems=1, bool wait=true)
|
||||
{
|
||||
if (ptr + itemSize * nItems > end) {
|
||||
if (ptr + itemSize > end)
|
||||
return overrun(itemSize, nItems, wait);
|
||||
|
||||
nItems = (end - ptr) / itemSize;
|
||||
}
|
||||
return nItems;
|
||||
}
|
||||
|
||||
// checkNoWait() tries to make sure that the given number of bytes can
|
||||
// be read without blocking. It returns true if this is the case, false
|
||||
// otherwise. The length must be "small" (less than the buffer size).
|
||||
|
||||
inline bool checkNoWait(int length) { return check(length, 1, false)!=0; }
|
||||
|
||||
// readU/SN() methods read unsigned and signed N-bit integers.
|
||||
|
||||
inline U8 readU8() { check(1); return *ptr++; }
|
||||
inline U16 readU16() { check(2); int b0 = *ptr++; int b1 = *ptr++;
|
||||
return b0 << 8 | b1; }
|
||||
inline U32 readU32() { check(4); int b0 = *ptr++; int b1 = *ptr++;
|
||||
int b2 = *ptr++; int b3 = *ptr++;
|
||||
return b0 << 24 | b1 << 16 | b2 << 8 | b3; }
|
||||
|
||||
inline S8 readS8() { return (S8) readU8(); }
|
||||
inline S16 readS16() { return (S16)readU16(); }
|
||||
inline S32 readS32() { return (S32)readU32(); }
|
||||
|
||||
// readString() reads a string - a U32 length followed by the data.
|
||||
// Returns a null-terminated string - the caller should delete[] it
|
||||
// afterwards.
|
||||
|
||||
char* readString();
|
||||
|
||||
// maxStringLength protects against allocating a huge buffer. Set it
|
||||
// higher if you need longer strings.
|
||||
|
||||
static U32 maxStringLength;
|
||||
|
||||
inline void skip(int bytes) {
|
||||
while (bytes > 0) {
|
||||
int n = check(1, bytes);
|
||||
ptr += n;
|
||||
bytes -= n;
|
||||
}
|
||||
}
|
||||
|
||||
// readBytes() reads an exact number of bytes.
|
||||
|
||||
virtual void readBytes(void* data, int length) {
|
||||
U8* dataPtr = (U8*)data;
|
||||
U8* dataEnd = dataPtr + length;
|
||||
while (dataPtr < dataEnd) {
|
||||
int n = check(1, dataEnd - dataPtr);
|
||||
memcpy(dataPtr, ptr, n);
|
||||
ptr += n;
|
||||
dataPtr += n;
|
||||
}
|
||||
}
|
||||
|
||||
// readOpaqueN() reads a quantity without byte-swapping.
|
||||
|
||||
inline U8 readOpaque8() { return readU8(); }
|
||||
inline U16 readOpaque16() { check(2); U16 r; ((U8*)&r)[0] = *ptr++;
|
||||
((U8*)&r)[1] = *ptr++; return r; }
|
||||
inline U32 readOpaque32() { check(4); U32 r; ((U8*)&r)[0] = *ptr++;
|
||||
((U8*)&r)[1] = *ptr++; ((U8*)&r)[2] = *ptr++;
|
||||
((U8*)&r)[3] = *ptr++; return r; }
|
||||
inline U32 readOpaque24A() { check(3); U32 r=0; ((U8*)&r)[0] = *ptr++;
|
||||
((U8*)&r)[1] = *ptr++; ((U8*)&r)[2] = *ptr++;
|
||||
return r; }
|
||||
inline U32 readOpaque24B() { check(3); U32 r=0; ((U8*)&r)[1] = *ptr++;
|
||||
((U8*)&r)[2] = *ptr++; ((U8*)&r)[3] = *ptr++;
|
||||
return r; }
|
||||
|
||||
// pos() returns the position in the stream.
|
||||
|
||||
virtual int pos() = 0;
|
||||
|
||||
// getptr(), getend() and setptr() are "dirty" methods which allow you to
|
||||
// manipulate the buffer directly. This is useful for a stream which is a
|
||||
// wrapper around an underlying stream.
|
||||
|
||||
inline const U8* getptr() const { return ptr; }
|
||||
inline const U8* getend() const { return end; }
|
||||
inline void setptr(const U8* p) { ptr = p; }
|
||||
|
||||
private:
|
||||
|
||||
// overrun() is implemented by a derived class to cope with buffer overrun.
|
||||
// It ensures there are at least itemSize bytes of buffer data. Returns
|
||||
// the number of items in the buffer (up to a maximum of nItems). itemSize
|
||||
// is supposed to be "small" (a few bytes). If wait is false, then
|
||||
// instead of blocking to wait for the bytes, zero is returned if the bytes
|
||||
// are not immediately available.
|
||||
|
||||
virtual int overrun(int itemSize, int nItems, bool wait=true) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
InStream() {}
|
||||
const U8* ptr;
|
||||
const U8* end;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
19
rdr/Makefile.in
Normal file
19
rdr/Makefile.in
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
SRCS = Exception.cxx FdInStream.cxx FdOutStream.cxx InStream.cxx \
|
||||
NullOutStream.cxx RandomStream.cxx ZlibInStream.cxx ZlibOutStream.cxx \
|
||||
HexInStream.cxx HexOutStream.cxx
|
||||
|
||||
OBJS = $(SRCS:.cxx=.o)
|
||||
|
||||
DIR_CPPFLAGS = -I$(top_srcdir) @ZLIB_INCLUDE@
|
||||
|
||||
library = librdr.a
|
||||
|
||||
all:: $(library)
|
||||
|
||||
$(library): $(OBJS)
|
||||
rm -f $(library)
|
||||
$(AR) $(library) $(OBJS)
|
||||
$(RANLIB) $(library)
|
||||
|
||||
# followed by boilerplate.mk
|
63
rdr/MemInStream.h
Normal file
63
rdr/MemInStream.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// rdr::MemInStream is an InStream which streams from a given memory buffer.
|
||||
// If the deleteWhenDone parameter is true then the buffer will be delete[]d in
|
||||
// the destructor. Note that it is delete[]d as a U8* - strictly speaking this
|
||||
// means it ought to be new[]ed as a U8* as well, but on most platforms this
|
||||
// doesn't matter.
|
||||
//
|
||||
|
||||
#ifndef __RDR_MEMINSTREAM_H__
|
||||
#define __RDR_MEMINSTREAM_H__
|
||||
|
||||
#include <rdr/InStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class MemInStream : public InStream {
|
||||
|
||||
public:
|
||||
|
||||
MemInStream(const void* data, int len, bool deleteWhenDone_=false)
|
||||
: start((const U8*)data), deleteWhenDone(deleteWhenDone_)
|
||||
{
|
||||
ptr = start;
|
||||
end = start + len;
|
||||
}
|
||||
|
||||
virtual ~MemInStream() {
|
||||
if (deleteWhenDone)
|
||||
delete [] (U8*)start;
|
||||
}
|
||||
|
||||
int pos() { return ptr - start; }
|
||||
void reposition(int pos) { ptr = start + pos; }
|
||||
|
||||
private:
|
||||
|
||||
int overrun(int itemSize, int nItems, bool wait) { throw EndOfStream(); }
|
||||
const U8* start;
|
||||
bool deleteWhenDone;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
82
rdr/MemOutStream.h
Normal file
82
rdr/MemOutStream.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// A MemOutStream grows as needed when data is written to it.
|
||||
//
|
||||
|
||||
#ifndef __RDR_MEMOUTSTREAM_H__
|
||||
#define __RDR_MEMOUTSTREAM_H__
|
||||
|
||||
#include <rdr/OutStream.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class MemOutStream : public OutStream {
|
||||
|
||||
public:
|
||||
|
||||
MemOutStream(int len=1024) {
|
||||
start = ptr = new U8[len];
|
||||
end = start + len;
|
||||
}
|
||||
|
||||
virtual ~MemOutStream() {
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
void writeBytes(const void* data, int length) {
|
||||
check(length);
|
||||
memcpy(ptr, data, length);
|
||||
ptr += length;
|
||||
}
|
||||
|
||||
int length() { return ptr - start; }
|
||||
void clear() { ptr = start; };
|
||||
void reposition(int pos) { ptr = start + pos; }
|
||||
|
||||
// data() returns a pointer to the buffer.
|
||||
|
||||
const void* data() { return (const void*)start; }
|
||||
|
||||
private:
|
||||
|
||||
// overrun() either doubles the buffer or adds enough space for nItems of
|
||||
// size itemSize bytes.
|
||||
|
||||
int overrun(int itemSize, int nItems) {
|
||||
int len = ptr - start + itemSize * nItems;
|
||||
if (len < (end - start) * 2)
|
||||
len = (end - start) * 2;
|
||||
|
||||
U8* newStart = new U8[len];
|
||||
memcpy(newStart, start, ptr - start);
|
||||
ptr = newStart + (ptr - start);
|
||||
delete [] start;
|
||||
start = newStart;
|
||||
end = newStart + len;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
U8* start;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
60
rdr/NullOutStream.cxx
Normal file
60
rdr/NullOutStream.cxx
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <rdr/NullOutStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
static const int bufferSize = 1024;
|
||||
|
||||
NullOutStream::NullOutStream()
|
||||
: offset(0)
|
||||
{
|
||||
start = ptr = new U8[bufferSize];
|
||||
end = start + bufferSize;
|
||||
}
|
||||
|
||||
NullOutStream::~NullOutStream()
|
||||
{
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
int NullOutStream::length()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
void NullOutStream::writeBytes(const void* data, int length)
|
||||
{
|
||||
offset += length;
|
||||
}
|
||||
|
||||
int NullOutStream::overrun(int itemSize, int nItems)
|
||||
{
|
||||
if (itemSize > bufferSize)
|
||||
throw Exception("NullOutStream overrun: max itemSize exceeded");
|
||||
|
||||
offset += ptr - start;
|
||||
ptr = start;
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
42
rdr/NullOutStream.h
Normal file
42
rdr/NullOutStream.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_NULLOUTSTREAM_H__
|
||||
#define __RDR_NULLOUTSTREAM_H__
|
||||
|
||||
#include <rdr/OutStream.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class NullOutStream : public OutStream {
|
||||
|
||||
public:
|
||||
NullOutStream();
|
||||
virtual ~NullOutStream();
|
||||
int length();
|
||||
void writeBytes(const void* data, int length);
|
||||
|
||||
private:
|
||||
int overrun(int itemSize, int nItems);
|
||||
int offset;
|
||||
U8* start;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
152
rdr/OutStream.h
Normal file
152
rdr/OutStream.h
Normal file
|
@ -0,0 +1,152 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// rdr::OutStream marshalls data into a buffer stored in RDR (RFB Data
|
||||
// Representation).
|
||||
//
|
||||
|
||||
#ifndef __RDR_OUTSTREAM_H__
|
||||
#define __RDR_OUTSTREAM_H__
|
||||
|
||||
#include <rdr/types.h>
|
||||
#include <string.h> // for memcpy
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class OutStream {
|
||||
|
||||
protected:
|
||||
|
||||
OutStream() {}
|
||||
|
||||
public:
|
||||
|
||||
virtual ~OutStream() {}
|
||||
|
||||
// check() ensures there is buffer space for at least one item of size
|
||||
// itemSize bytes. Returns the number of items which fit (up to a maximum
|
||||
// of nItems).
|
||||
|
||||
inline int check(int itemSize, int nItems=1)
|
||||
{
|
||||
if (ptr + itemSize * nItems > end) {
|
||||
if (ptr + itemSize > end)
|
||||
return overrun(itemSize, nItems);
|
||||
|
||||
nItems = (end - ptr) / itemSize;
|
||||
}
|
||||
return nItems;
|
||||
}
|
||||
|
||||
// writeU/SN() methods write unsigned and signed N-bit integers.
|
||||
|
||||
inline void writeU8( U8 u) { check(1); *ptr++ = u; }
|
||||
inline void writeU16(U16 u) { check(2); *ptr++ = u >> 8; *ptr++ = (U8)u; }
|
||||
inline void writeU32(U32 u) { check(4); *ptr++ = u >> 24; *ptr++ = u >> 16;
|
||||
*ptr++ = u >> 8; *ptr++ = u; }
|
||||
|
||||
inline void writeS8( S8 s) { writeU8((U8)s); }
|
||||
inline void writeS16(S16 s) { writeU16((U16)s); }
|
||||
inline void writeS32(S32 s) { writeU32((U32)s); }
|
||||
|
||||
// writeString() writes a string - a U32 length followed by the data. The
|
||||
// given string should be null-terminated (but the terminating null is not
|
||||
// written to the stream).
|
||||
|
||||
inline void writeString(const char* str) {
|
||||
U32 len = strlen(str);
|
||||
writeU32(len);
|
||||
writeBytes(str, len);
|
||||
}
|
||||
|
||||
inline void pad(int bytes) {
|
||||
while (bytes-- > 0) writeU8(0);
|
||||
}
|
||||
|
||||
inline void skip(int bytes) {
|
||||
while (bytes > 0) {
|
||||
int n = check(1, bytes);
|
||||
ptr += n;
|
||||
bytes -= n;
|
||||
}
|
||||
}
|
||||
|
||||
// writeBytes() writes an exact number of bytes.
|
||||
|
||||
virtual void writeBytes(const void* data, int length) {
|
||||
const U8* dataPtr = (const U8*)data;
|
||||
const U8* dataEnd = dataPtr + length;
|
||||
while (dataPtr < dataEnd) {
|
||||
int n = check(1, dataEnd - dataPtr);
|
||||
memcpy(ptr, dataPtr, n);
|
||||
ptr += n;
|
||||
dataPtr += n;
|
||||
}
|
||||
}
|
||||
|
||||
// writeOpaqueN() writes a quantity without byte-swapping.
|
||||
|
||||
inline void writeOpaque8( U8 u) { writeU8(u); }
|
||||
inline void writeOpaque16(U16 u) { check(2); *ptr++ = ((U8*)&u)[0];
|
||||
*ptr++ = ((U8*)&u)[1]; }
|
||||
inline void writeOpaque32(U32 u) { check(4); *ptr++ = ((U8*)&u)[0];
|
||||
*ptr++ = ((U8*)&u)[1];
|
||||
*ptr++ = ((U8*)&u)[2];
|
||||
*ptr++ = ((U8*)&u)[3]; }
|
||||
inline void writeOpaque24A(U32 u) { check(3); *ptr++ = ((U8*)&u)[0];
|
||||
*ptr++ = ((U8*)&u)[1];
|
||||
*ptr++ = ((U8*)&u)[2]; }
|
||||
inline void writeOpaque24B(U32 u) { check(3); *ptr++ = ((U8*)&u)[1];
|
||||
*ptr++ = ((U8*)&u)[2];
|
||||
*ptr++ = ((U8*)&u)[3]; }
|
||||
|
||||
// length() returns the length of the stream.
|
||||
|
||||
virtual int length() = 0;
|
||||
|
||||
// flush() requests that the stream be flushed.
|
||||
|
||||
virtual void flush() {}
|
||||
|
||||
// getptr(), getend() and setptr() are "dirty" methods which allow you to
|
||||
// manipulate the buffer directly. This is useful for a stream which is a
|
||||
// wrapper around an underlying stream.
|
||||
|
||||
inline U8* getptr() { return ptr; }
|
||||
inline U8* getend() { return end; }
|
||||
inline void setptr(U8* p) { ptr = p; }
|
||||
|
||||
private:
|
||||
|
||||
// overrun() is implemented by a derived class to cope with buffer overrun.
|
||||
// It ensures there are at least itemSize bytes of buffer space. Returns
|
||||
// the number of items which fit (up to a maximum of nItems). itemSize is
|
||||
// supposed to be "small" (a few bytes).
|
||||
|
||||
virtual int overrun(int itemSize, int nItems) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
U8* ptr;
|
||||
U8* end;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
118
rdr/RandomStream.cxx
Normal file
118
rdr/RandomStream.cxx
Normal file
|
@ -0,0 +1,118 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <rdr/RandomStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#else
|
||||
#define getpid() GetCurrentProcessId()
|
||||
#endif
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
const int DEFAULT_BUF_LEN = 256;
|
||||
|
||||
unsigned int RandomStream::seed;
|
||||
|
||||
RandomStream::RandomStream()
|
||||
: offset(0)
|
||||
{
|
||||
ptr = end = start = new U8[DEFAULT_BUF_LEN];
|
||||
|
||||
#ifdef WIN32
|
||||
provider = 0;
|
||||
if (!CryptAcquireContext(&provider, 0, 0, PROV_RSA_FULL, 0)) {
|
||||
if (GetLastError() == NTE_BAD_KEYSET) {
|
||||
if (!CryptAcquireContext(&provider, 0, 0, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
|
||||
fprintf(stderr, "RandomStream: unable to create keyset\n");
|
||||
provider = 0;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "RandomStream: unable to acquire context\n");
|
||||
provider = 0;
|
||||
}
|
||||
}
|
||||
if (!provider) {
|
||||
#else
|
||||
fp = fopen("/dev/urandom", "r");
|
||||
if (!fp)
|
||||
fp = fopen("/dev/random", "r");
|
||||
if (!fp) {
|
||||
#endif
|
||||
fprintf(stderr,"RandomStream: warning: no OS supplied random source - using rand()\n");
|
||||
seed += (unsigned int) time(0) + getpid() + getpid() * 987654 + rand();
|
||||
srand(seed);
|
||||
}
|
||||
}
|
||||
|
||||
RandomStream::~RandomStream() {
|
||||
delete [] start;
|
||||
|
||||
#ifdef WIN32
|
||||
if (provider) {
|
||||
CryptReleaseContext(provider, 0);
|
||||
}
|
||||
#else
|
||||
if (fp) fclose(fp);
|
||||
#endif
|
||||
}
|
||||
|
||||
int RandomStream::pos() {
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
int RandomStream::overrun(int itemSize, int nItems, bool wait) {
|
||||
if (itemSize > DEFAULT_BUF_LEN)
|
||||
throw Exception("RandomStream overrun: max itemSize exceeded");
|
||||
|
||||
if (end - ptr != 0)
|
||||
memmove(start, ptr, end - ptr);
|
||||
|
||||
end -= ptr - start;
|
||||
offset += ptr - start;
|
||||
ptr = start;
|
||||
|
||||
int length = start + DEFAULT_BUF_LEN - end;
|
||||
|
||||
#ifdef WIN32
|
||||
if (provider) {
|
||||
if (!CryptGenRandom(provider, length, (U8*)end))
|
||||
throw rdr::SystemException("unable to CryptGenRandom", GetLastError());
|
||||
end += length;
|
||||
#else
|
||||
if (fp) {
|
||||
int n = fread((U8*)end, length, 1, fp);
|
||||
if (n != 1)
|
||||
throw rdr::SystemException("reading /dev/urandom or /dev/random failed",
|
||||
errno);
|
||||
end += length;
|
||||
#endif
|
||||
} else {
|
||||
for (int i=0; i<length; i++)
|
||||
*(U8*)end++ = (int) (256.0*rand()/(RAND_MAX+1.0));
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
63
rdr/RandomStream.h
Normal file
63
rdr/RandomStream.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_RANDOMSTREAM_H__
|
||||
#define __RDR_RANDOMSTREAM_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <rdr/InStream.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
#endif
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class RandomStream : public InStream {
|
||||
|
||||
public:
|
||||
|
||||
RandomStream();
|
||||
virtual ~RandomStream();
|
||||
|
||||
int pos();
|
||||
|
||||
protected:
|
||||
int overrun(int itemSize, int nItems, bool wait);
|
||||
|
||||
private:
|
||||
U8* start;
|
||||
int offset;
|
||||
|
||||
static unsigned int seed;
|
||||
#ifdef WIN32
|
||||
HCRYPTPROV provider;
|
||||
#else
|
||||
FILE* fp;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
} // end of namespace rdr
|
||||
|
||||
#endif
|
102
rdr/SubstitutingInStream.h
Normal file
102
rdr/SubstitutingInStream.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_SUBSTITUTINGINSTREAM_H__
|
||||
#define __RDR_SUBSTITUTINGINSTREAM_H__
|
||||
|
||||
#include <rdr/InStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class Substitutor {
|
||||
public:
|
||||
virtual char* substitute(const char* varName) = 0;
|
||||
};
|
||||
|
||||
class SubstitutingInStream : public InStream {
|
||||
public:
|
||||
SubstitutingInStream(InStream* underlying_, Substitutor* s,
|
||||
int maxVarNameLen_)
|
||||
: underlying(underlying_), dollar(0), substitutor(s), subst(0),
|
||||
maxVarNameLen(maxVarNameLen_)
|
||||
{
|
||||
ptr = end = underlying->getptr();
|
||||
varName = new char[maxVarNameLen+1];
|
||||
}
|
||||
~SubstitutingInStream() {
|
||||
delete underlying;
|
||||
delete [] varName;
|
||||
delete [] subst;
|
||||
}
|
||||
|
||||
int pos() { return underlying->pos(); }
|
||||
|
||||
virtual int overrun(int itemSize, int nItems, bool wait=true) {
|
||||
if (itemSize != 1)
|
||||
throw new rdr::Exception("SubstitutingInStream: itemSize must be 1");
|
||||
|
||||
if (subst) {
|
||||
delete [] subst;
|
||||
subst = 0;
|
||||
} else {
|
||||
underlying->setptr(ptr);
|
||||
}
|
||||
|
||||
underlying->check(1);
|
||||
ptr = underlying->getptr();
|
||||
end = underlying->getend();
|
||||
dollar = (const U8*)memchr(ptr, '$', end-ptr);
|
||||
if (dollar) {
|
||||
if (dollar == ptr) {
|
||||
try {
|
||||
int i = 0;
|
||||
while (i < maxVarNameLen) {
|
||||
varName[i++] = underlying->readS8();
|
||||
varName[i] = 0;
|
||||
subst = substitutor->substitute(varName);
|
||||
if (subst) {
|
||||
ptr = (U8*)subst;
|
||||
end = (U8*)subst + strlen(subst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (EndOfStream&) {
|
||||
}
|
||||
|
||||
if (!subst)
|
||||
dollar = (const U8*)memchr(ptr+1, '$', end-ptr-1);
|
||||
}
|
||||
if (!subst && dollar) end = dollar;
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
InStream* underlying;
|
||||
const U8* dollar;
|
||||
Substitutor* substitutor;
|
||||
char* varName;
|
||||
char* subst;
|
||||
int maxVarNameLen;
|
||||
};
|
||||
}
|
||||
#endif
|
125
rdr/ZlibInStream.cxx
Normal file
125
rdr/ZlibInStream.cxx
Normal file
|
@ -0,0 +1,125 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <rdr/ZlibInStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
#include <zlib.h>
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
enum { DEFAULT_BUF_SIZE = 16384 };
|
||||
|
||||
ZlibInStream::ZlibInStream(int bufSize_)
|
||||
: underlying(0), bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0),
|
||||
bytesIn(0)
|
||||
{
|
||||
zs = new z_stream;
|
||||
zs->zalloc = Z_NULL;
|
||||
zs->zfree = Z_NULL;
|
||||
zs->opaque = Z_NULL;
|
||||
zs->next_in = Z_NULL;
|
||||
zs->avail_in = 0;
|
||||
if (inflateInit(zs) != Z_OK) {
|
||||
delete zs;
|
||||
throw Exception("ZlibInStream: inflateInit failed");
|
||||
}
|
||||
ptr = end = start = new U8[bufSize];
|
||||
}
|
||||
|
||||
ZlibInStream::~ZlibInStream()
|
||||
{
|
||||
delete [] start;
|
||||
inflateEnd(zs);
|
||||
delete zs;
|
||||
}
|
||||
|
||||
void ZlibInStream::setUnderlying(InStream* is, int bytesIn_)
|
||||
{
|
||||
underlying = is;
|
||||
bytesIn = bytesIn_;
|
||||
ptr = end = start;
|
||||
}
|
||||
|
||||
int ZlibInStream::pos()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
void ZlibInStream::reset()
|
||||
{
|
||||
ptr = end = start;
|
||||
if (!underlying) return;
|
||||
|
||||
while (bytesIn > 0) {
|
||||
decompress(true);
|
||||
end = start; // throw away any data
|
||||
}
|
||||
underlying = 0;
|
||||
}
|
||||
|
||||
int ZlibInStream::overrun(int itemSize, int nItems, bool wait)
|
||||
{
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("ZlibInStream overrun: max itemSize exceeded");
|
||||
if (!underlying)
|
||||
throw Exception("ZlibInStream overrun: no underlying stream");
|
||||
|
||||
if (end - ptr != 0)
|
||||
memmove(start, ptr, end - ptr);
|
||||
|
||||
offset += ptr - start;
|
||||
end -= ptr - start;
|
||||
ptr = start;
|
||||
|
||||
while (end - ptr < itemSize) {
|
||||
if (!decompress(wait))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
// decompress() calls the decompressor once. Note that this won't necessarily
|
||||
// generate any output data - it may just consume some input data. Returns
|
||||
// false if wait is false and we would block on the underlying stream.
|
||||
|
||||
bool ZlibInStream::decompress(bool wait)
|
||||
{
|
||||
zs->next_out = (U8*)end;
|
||||
zs->avail_out = start + bufSize - end;
|
||||
|
||||
int n = underlying->check(1, 1, wait);
|
||||
if (n == 0) return false;
|
||||
zs->next_in = (U8*)underlying->getptr();
|
||||
zs->avail_in = underlying->getend() - underlying->getptr();
|
||||
if ((int)zs->avail_in > bytesIn)
|
||||
zs->avail_in = bytesIn;
|
||||
|
||||
int rc = inflate(zs, Z_SYNC_FLUSH);
|
||||
if (rc != Z_OK) {
|
||||
throw Exception("ZlibInStream: inflate failed");
|
||||
}
|
||||
|
||||
bytesIn -= zs->next_in - underlying->getptr();
|
||||
end = zs->next_out;
|
||||
underlying->setptr(zs->next_in);
|
||||
return true;
|
||||
}
|
59
rdr/ZlibInStream.h
Normal file
59
rdr/ZlibInStream.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// ZlibInStream streams from a compressed data stream ("underlying"),
|
||||
// decompressing with zlib on the fly.
|
||||
//
|
||||
|
||||
#ifndef __RDR_ZLIBINSTREAM_H__
|
||||
#define __RDR_ZLIBINSTREAM_H__
|
||||
|
||||
#include <rdr/InStream.h>
|
||||
|
||||
struct z_stream_s;
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class ZlibInStream : public InStream {
|
||||
|
||||
public:
|
||||
|
||||
ZlibInStream(int bufSize=0);
|
||||
virtual ~ZlibInStream();
|
||||
|
||||
void setUnderlying(InStream* is, int bytesIn);
|
||||
void reset();
|
||||
int pos();
|
||||
|
||||
private:
|
||||
|
||||
int overrun(int itemSize, int nItems, bool wait);
|
||||
bool decompress(bool wait);
|
||||
|
||||
InStream* underlying;
|
||||
int bufSize;
|
||||
int offset;
|
||||
z_stream_s* zs;
|
||||
int bytesIn;
|
||||
U8* start;
|
||||
};
|
||||
|
||||
} // end of namespace rdr
|
||||
|
||||
#endif
|
140
rdr/ZlibOutStream.cxx
Normal file
140
rdr/ZlibOutStream.cxx
Normal file
|
@ -0,0 +1,140 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <rdr/ZlibOutStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
#include <zlib.h>
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
enum { DEFAULT_BUF_SIZE = 16384 };
|
||||
|
||||
ZlibOutStream::ZlibOutStream(OutStream* os, int bufSize_, int compressLevel)
|
||||
: underlying(os), bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
|
||||
{
|
||||
zs = new z_stream;
|
||||
zs->zalloc = Z_NULL;
|
||||
zs->zfree = Z_NULL;
|
||||
zs->opaque = Z_NULL;
|
||||
if (deflateInit(zs, compressLevel) != Z_OK) {
|
||||
delete zs;
|
||||
throw Exception("ZlibOutStream: deflateInit failed");
|
||||
}
|
||||
ptr = start = new U8[bufSize];
|
||||
end = start + bufSize;
|
||||
}
|
||||
|
||||
ZlibOutStream::~ZlibOutStream()
|
||||
{
|
||||
try {
|
||||
flush();
|
||||
} catch (Exception&) {
|
||||
}
|
||||
delete [] start;
|
||||
deflateEnd(zs);
|
||||
delete zs;
|
||||
}
|
||||
|
||||
void ZlibOutStream::setUnderlying(OutStream* os)
|
||||
{
|
||||
underlying = os;
|
||||
}
|
||||
|
||||
int ZlibOutStream::length()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
void ZlibOutStream::flush()
|
||||
{
|
||||
zs->next_in = start;
|
||||
zs->avail_in = ptr - start;
|
||||
|
||||
// fprintf(stderr,"zos flush: avail_in %d\n",zs->avail_in);
|
||||
|
||||
while (zs->avail_in != 0) {
|
||||
|
||||
do {
|
||||
underlying->check(1);
|
||||
zs->next_out = underlying->getptr();
|
||||
zs->avail_out = underlying->getend() - underlying->getptr();
|
||||
|
||||
// fprintf(stderr,"zos flush: calling deflate, avail_in %d, avail_out %d\n",
|
||||
// zs->avail_in,zs->avail_out);
|
||||
int rc = deflate(zs, Z_SYNC_FLUSH);
|
||||
if (rc != Z_OK) throw Exception("ZlibOutStream: deflate failed");
|
||||
|
||||
// fprintf(stderr,"zos flush: after deflate: %d bytes\n",
|
||||
// zs->next_out-underlying->getptr());
|
||||
|
||||
underlying->setptr(zs->next_out);
|
||||
} while (zs->avail_out == 0);
|
||||
}
|
||||
|
||||
offset += ptr - start;
|
||||
ptr = start;
|
||||
}
|
||||
|
||||
int ZlibOutStream::overrun(int itemSize, int nItems)
|
||||
{
|
||||
// fprintf(stderr,"ZlibOutStream overrun\n");
|
||||
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("ZlibOutStream overrun: max itemSize exceeded");
|
||||
|
||||
while (end - ptr < itemSize) {
|
||||
zs->next_in = start;
|
||||
zs->avail_in = ptr - start;
|
||||
|
||||
do {
|
||||
underlying->check(1);
|
||||
zs->next_out = underlying->getptr();
|
||||
zs->avail_out = underlying->getend() - underlying->getptr();
|
||||
|
||||
// fprintf(stderr,"zos overrun: calling deflate, avail_in %d, avail_out %d\n",
|
||||
// zs->avail_in,zs->avail_out);
|
||||
|
||||
int rc = deflate(zs, 0);
|
||||
if (rc != Z_OK) throw Exception("ZlibOutStream: deflate failed");
|
||||
|
||||
// fprintf(stderr,"zos overrun: after deflate: %d bytes\n",
|
||||
// zs->next_out-underlying->getptr());
|
||||
|
||||
underlying->setptr(zs->next_out);
|
||||
} while (zs->avail_out == 0);
|
||||
|
||||
// output buffer not full
|
||||
|
||||
if (zs->avail_in == 0) {
|
||||
offset += ptr - start;
|
||||
ptr = start;
|
||||
} else {
|
||||
// but didn't consume all the data? try shifting what's left to the
|
||||
// start of the buffer.
|
||||
fprintf(stderr,"z out buf not full, but in data not consumed\n");
|
||||
memmove(start, zs->next_in, ptr - zs->next_in);
|
||||
offset += zs->next_in - start;
|
||||
ptr -= zs->next_in - start;
|
||||
}
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
57
rdr/ZlibOutStream.h
Normal file
57
rdr/ZlibOutStream.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// ZlibOutStream streams to a compressed data stream (underlying), compressing
|
||||
// with zlib on the fly.
|
||||
//
|
||||
|
||||
#ifndef __RDR_ZLIBOUTSTREAM_H__
|
||||
#define __RDR_ZLIBOUTSTREAM_H__
|
||||
|
||||
#include <rdr/OutStream.h>
|
||||
|
||||
struct z_stream_s;
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class ZlibOutStream : public OutStream {
|
||||
|
||||
public:
|
||||
|
||||
ZlibOutStream(OutStream* os=0, int bufSize=0, int compressionLevel=-1);
|
||||
virtual ~ZlibOutStream();
|
||||
|
||||
void setUnderlying(OutStream* os);
|
||||
void flush();
|
||||
int length();
|
||||
|
||||
private:
|
||||
|
||||
int overrun(int itemSize, int nItems);
|
||||
|
||||
OutStream* underlying;
|
||||
int bufSize;
|
||||
int offset;
|
||||
z_stream_s* zs;
|
||||
U8* start;
|
||||
};
|
||||
|
||||
} // end of namespace rdr
|
||||
|
||||
#endif
|
18
rdr/msvcwarning.h
Normal file
18
rdr/msvcwarning.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#pragma warning( disable : 4800 ) // forcing bool 'true' or 'false'
|
231
rdr/rdr.dsp
Normal file
231
rdr/rdr.dsp
Normal file
|
@ -0,0 +1,231 @@
|
|||
# Microsoft Developer Studio Project File - Name="rdr" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=rdr - Win32 Debug Unicode
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "rdr.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "rdr.mak" CFG="rdr - Win32 Debug Unicode"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "rdr - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "rdr - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "rdr - Win32 Debug Unicode" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "rdr - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O1 /I ".." /FI"msvcwarning.h" /D "NDEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x809 /d "NDEBUG"
|
||||
# ADD RSC /l 0x809 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "rdr - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /FI"msvcwarning.h" /D "_DEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "rdr - Win32 Debug Unicode"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "rdr___Win32_Debug_Unicode"
|
||||
# PROP BASE Intermediate_Dir "rdr___Win32_Debug_Unicode"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug_Unicode"
|
||||
# PROP Intermediate_Dir "Debug_Unicode"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /FI"msvcwarning.h" /D "_DEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /FI"msvcwarning.h" /D "_LIB" /D "_DEBUG" /D "WIN32" /D "_UNICODE" /D "UNICODE" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "rdr - Win32 Release"
|
||||
# Name "rdr - Win32 Debug"
|
||||
# Name "rdr - Win32 Debug Unicode"
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Exception.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FdInStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FdOutStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FixedMemOutStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\HexInStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\HexOutStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\InStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MemInStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MemOutStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\msvcwarning.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\NullOutStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\OutStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\RandomStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\SubstitutingInStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\types.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZlibInStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZlibOutStream.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Exception.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FdInStream.cxx
|
||||
# ADD CPP /I "../zlib"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FdOutStream.cxx
|
||||
# ADD CPP /I "../zlib"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\HexInStream.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\HexOutStream.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\InStream.cxx
|
||||
# ADD CPP /I "../zlib"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\NullOutStream.cxx
|
||||
# ADD CPP /I "../zlib"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\RandomStream.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZlibInStream.cxx
|
||||
# ADD CPP /I "../zlib"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZlibOutStream.cxx
|
||||
# ADD CPP /I "../zlib"
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
56
rdr/types.h
Normal file
56
rdr/types.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_TYPES_H__
|
||||
#define __RDR_TYPES_H__
|
||||
|
||||
namespace rdr {
|
||||
|
||||
typedef unsigned char U8;
|
||||
typedef unsigned short U16;
|
||||
typedef unsigned int U32;
|
||||
typedef signed char S8;
|
||||
typedef signed short S16;
|
||||
typedef signed int S32;
|
||||
|
||||
class U8Array {
|
||||
public:
|
||||
U8Array() : buf(0) {}
|
||||
U8Array(U8* a) : buf(a) {} // note: assumes ownership
|
||||
U8Array(int len) : buf(new U8[len]) {}
|
||||
~U8Array() { delete [] buf; }
|
||||
|
||||
// Get the buffer pointer & clear it (i.e. caller takes ownership)
|
||||
U8* takeBuf() { U8* tmp = buf; buf = 0; return tmp; }
|
||||
|
||||
U8* buf;
|
||||
};
|
||||
|
||||
class U16Array {
|
||||
public:
|
||||
U16Array() : buf(0) {}
|
||||
U16Array(U16* a) : buf(a) {} // note: assumes ownership
|
||||
U16Array(int len) : buf(new U16[len]) {}
|
||||
~U16Array() { delete [] buf; }
|
||||
U16* takeBuf() { U16* tmp = buf; buf = 0; return tmp; }
|
||||
U16* buf;
|
||||
};
|
||||
|
||||
} // end of namespace rdr
|
||||
|
||||
#endif
|
86
rfb/Blacklist.cxx
Normal file
86
rfb/Blacklist.cxx
Normal file
|
@ -0,0 +1,86 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#include <rfb/Blacklist.h>
|
||||
#include <rfb/Configuration.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
IntParameter Blacklist::threshold("BlacklistThreshold",
|
||||
"The number of unauthenticated connection attempts allowed from any "
|
||||
"individual host before that host is black-listed",
|
||||
5);
|
||||
IntParameter Blacklist::initialTimeout("BlacklistTimeout",
|
||||
"The initial timeout applied when a host is first black-listed. "
|
||||
"The host cannot re-attempt a connection until the timeout expires.",
|
||||
10);
|
||||
|
||||
|
||||
Blacklist::Blacklist() {
|
||||
}
|
||||
|
||||
Blacklist::~Blacklist() {
|
||||
// Free the map keys
|
||||
BlacklistMap::iterator i;
|
||||
for (i=blm.begin(); i!=blm.end(); i++) {
|
||||
strFree((char*)(*i).first);
|
||||
}
|
||||
}
|
||||
|
||||
bool Blacklist::isBlackmarked(const char* name) {
|
||||
BlacklistMap::iterator i = blm.find(name);
|
||||
if (i == blm.end()) {
|
||||
// Entry is not already black-marked.
|
||||
// Create the entry unmarked, unblocked,
|
||||
// with suitable defaults set.
|
||||
BlacklistInfo bi;
|
||||
bi.marks = 1;
|
||||
bi.blockUntil = 0;
|
||||
bi.blockTimeout = initialTimeout;
|
||||
blm[strDup(name)] = bi;
|
||||
i = blm.find(name);
|
||||
}
|
||||
|
||||
// Entry exists - has it reached the threshold yet?
|
||||
if ((*i).second.marks >= threshold) {
|
||||
// Yes - entry is blocked - has the timeout expired?
|
||||
time_t now = time(0);
|
||||
if (now >= (*i).second.blockUntil) {
|
||||
// Timeout has expired. Reset timeout and allow
|
||||
// a re-try.
|
||||
(*i).second.blockUntil = now + (*i).second.blockTimeout;
|
||||
(*i).second.blockTimeout = (*i).second.blockTimeout * 2;
|
||||
return false;
|
||||
}
|
||||
// Blocked and timeout still in effect - reject!
|
||||
return true;
|
||||
}
|
||||
|
||||
// We haven't reached the threshold yet.
|
||||
// Increment the black-mark counter but allow
|
||||
// the entry to pass.
|
||||
(*i).second.marks++;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Blacklist::clearBlackmark(const char* name) {
|
||||
BlacklistMap::iterator i = blm.find(name);
|
||||
if (i != blm.end()) {
|
||||
strFree((char*)(*i).first);
|
||||
blm.erase(i);
|
||||
}
|
||||
}
|
91
rfb/Blacklist.h
Normal file
91
rfb/Blacklist.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// Blacklist.h - Handling of black-listed entities.
|
||||
// Just keeps a table mapping strings to timing information, including
|
||||
// how many times the entry has been black-listed and when to next
|
||||
// put it on probation (e.g. allow a connection in from the host, and
|
||||
// re-blacklist it if that fails).
|
||||
//
|
||||
|
||||
#ifndef __RFB_BLACKLIST_H__
|
||||
#define __RFB_BLACKLIST_H__
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <map>
|
||||
|
||||
#include <rfb/Configuration.h>
|
||||
#include <rfb/util.h>
|
||||
|
||||
namespace rfb {
|
||||
|
||||
//
|
||||
// -=- Blacklist handler
|
||||
//
|
||||
// Parameters include a threshold after which to blacklist the named
|
||||
// host, and a timeout after which to re-consider them.
|
||||
//
|
||||
// Threshold means that isBlackmarked can be called that number of times
|
||||
// before it will return true.
|
||||
//
|
||||
// Timeout means that after that many seconds, the next call to isBlackmarked
|
||||
// will return false. At the same time, the timeout is doubled, so that the
|
||||
// next calls will fail, until the timeout expires again or clearBlackmark is
|
||||
// called.
|
||||
//
|
||||
// When clearBlackMark is called, the corresponding entry is completely
|
||||
// removed, causing the next isBlackmarked call to return false.
|
||||
|
||||
// KNOWN BUG: Client can keep making rejected requests, thus increasing
|
||||
// their timeout. If client does this for 30 years, timeout may wrap round
|
||||
// to a very small value again.
|
||||
|
||||
// THIS CLASS IS NOT THREAD-SAFE!
|
||||
|
||||
class Blacklist {
|
||||
public:
|
||||
Blacklist();
|
||||
~Blacklist();
|
||||
|
||||
bool isBlackmarked(const char* name);
|
||||
void clearBlackmark(const char* name);
|
||||
|
||||
static IntParameter threshold;
|
||||
static IntParameter initialTimeout;
|
||||
|
||||
protected:
|
||||
struct ltStr {
|
||||
bool operator()(const char* s1, const char* s2) const {
|
||||
return strcmp(s1, s2) < 0;
|
||||
};
|
||||
};
|
||||
struct BlacklistInfo {
|
||||
int marks;
|
||||
time_t blockUntil;
|
||||
unsigned int blockTimeout;
|
||||
};
|
||||
typedef std::map<const char*,BlacklistInfo,ltStr> BlacklistMap;
|
||||
BlacklistMap blm;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
291
rfb/CConnection.cxx
Normal file
291
rfb/CConnection.cxx
Normal file
|
@ -0,0 +1,291 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <rfb/Exception.h>
|
||||
#include <rfb/CMsgReaderV3.h>
|
||||
#include <rfb/CMsgWriterV3.h>
|
||||
#include <rfb/CSecurity.h>
|
||||
#include <rfb/secTypes.h>
|
||||
#include <rfb/CConnection.h>
|
||||
#include <rfb/util.h>
|
||||
|
||||
#include <rfb/LogWriter.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
static LogWriter vlog("CConnection");
|
||||
|
||||
CConnection::CConnection()
|
||||
: is(0), os(0), reader_(0), writer_(0),
|
||||
shared(false), security(0), nSecTypes(0), clientSecTypeOrder(false),
|
||||
state_(RFBSTATE_UNINITIALISED), useProtocol3_3(false)
|
||||
{
|
||||
}
|
||||
|
||||
CConnection::~CConnection()
|
||||
{
|
||||
if (security) security->destroy();
|
||||
deleteReaderAndWriter();
|
||||
}
|
||||
|
||||
void CConnection::setServerName(const char* serverName_) {
|
||||
serverName.buf = strDup(serverName_);
|
||||
}
|
||||
|
||||
void CConnection::deleteReaderAndWriter()
|
||||
{
|
||||
delete reader_;
|
||||
reader_ = 0;
|
||||
delete writer_;
|
||||
writer_ = 0;
|
||||
}
|
||||
|
||||
void CConnection::setStreams(rdr::InStream* is_, rdr::OutStream* os_)
|
||||
{
|
||||
is = is_;
|
||||
os = os_;
|
||||
}
|
||||
|
||||
void CConnection::addSecType(rdr::U8 secType)
|
||||
{
|
||||
if (nSecTypes == maxSecTypes)
|
||||
throw Exception("too many security types");
|
||||
secTypes[nSecTypes++] = secType;
|
||||
}
|
||||
|
||||
void CConnection::setClientSecTypeOrder(bool clientOrder) {
|
||||
clientSecTypeOrder = clientOrder;
|
||||
}
|
||||
|
||||
void CConnection::initialiseProtocol()
|
||||
{
|
||||
state_ = RFBSTATE_PROTOCOL_VERSION;
|
||||
}
|
||||
|
||||
void CConnection::processMsg()
|
||||
{
|
||||
switch (state_) {
|
||||
|
||||
case RFBSTATE_PROTOCOL_VERSION: processVersionMsg(); break;
|
||||
case RFBSTATE_SECURITY_TYPES: processSecurityTypesMsg(); break;
|
||||
case RFBSTATE_SECURITY: processSecurityMsg(); break;
|
||||
case RFBSTATE_SECURITY_RESULT: processSecurityResultMsg(); break;
|
||||
case RFBSTATE_INITIALISATION: processInitMsg(); break;
|
||||
case RFBSTATE_NORMAL: reader_->readMsg(); break;
|
||||
case RFBSTATE_UNINITIALISED:
|
||||
throw Exception("CConnection::processMsg: not initialised yet?");
|
||||
default:
|
||||
throw Exception("CConnection::processMsg: invalid state");
|
||||
}
|
||||
}
|
||||
|
||||
void CConnection::processVersionMsg()
|
||||
{
|
||||
vlog.debug("reading protocol version");
|
||||
bool done;
|
||||
if (!cp.readVersion(is, &done)) {
|
||||
state_ = RFBSTATE_INVALID;
|
||||
throw Exception("reading version failed: not an RFB server?");
|
||||
}
|
||||
if (!done) return;
|
||||
|
||||
vlog.info("Server supports RFB protocol version %d.%d",
|
||||
cp.majorVersion, cp.minorVersion);
|
||||
|
||||
// The only official RFB protocol versions are currently 3.3, 3.7 and 3.8
|
||||
if (cp.beforeVersion(3,3)) {
|
||||
char msg[256];
|
||||
sprintf(msg,"Server gave unsupported RFB protocol version %d.%d",
|
||||
cp.majorVersion, cp.minorVersion);
|
||||
vlog.error(msg);
|
||||
state_ = RFBSTATE_INVALID;
|
||||
throw Exception(msg);
|
||||
} else if (useProtocol3_3 || cp.beforeVersion(3,7)) {
|
||||
cp.setVersion(3,3);
|
||||
} else if (cp.afterVersion(3,8)) {
|
||||
cp.setVersion(3,8);
|
||||
}
|
||||
|
||||
cp.writeVersion(os);
|
||||
state_ = RFBSTATE_SECURITY_TYPES;
|
||||
|
||||
vlog.info("Using RFB protocol version %d.%d",
|
||||
cp.majorVersion, cp.minorVersion);
|
||||
}
|
||||
|
||||
|
||||
void CConnection::processSecurityTypesMsg()
|
||||
{
|
||||
vlog.debug("processing security types message");
|
||||
|
||||
int secType = secTypeInvalid;
|
||||
|
||||
if (cp.isVersion(3,3)) {
|
||||
|
||||
// legacy 3.3 server may only offer "vnc authentication" or "none"
|
||||
|
||||
secType = is->readU32();
|
||||
if (secType == secTypeInvalid) {
|
||||
throwConnFailedException();
|
||||
|
||||
} else if (secType == secTypeNone || secType == secTypeVncAuth) {
|
||||
int j;
|
||||
for (j = 0; j < nSecTypes; j++)
|
||||
if (secTypes[j] == secType) break;
|
||||
if (j == nSecTypes)
|
||||
secType = secTypeInvalid;
|
||||
} else {
|
||||
vlog.error("Unknown 3.3 security type %d", secType);
|
||||
throw Exception("Unknown 3.3 security type");
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// >=3.7 server will offer us a list
|
||||
|
||||
int nServerSecTypes = is->readU8();
|
||||
if (nServerSecTypes == 0)
|
||||
throwConnFailedException();
|
||||
|
||||
int secTypePos = nSecTypes;
|
||||
for (int i = 0; i < nServerSecTypes; i++) {
|
||||
rdr::U8 serverSecType = is->readU8();
|
||||
vlog.debug("Server offers security type %s(%d)",
|
||||
secTypeName(serverSecType),serverSecType);
|
||||
|
||||
// If we haven't already chosen a secType, try this one
|
||||
// If we are using the client's preference for types,
|
||||
// we keep trying types, to find the one that matches and
|
||||
// which appears first in the client's list of supported types.
|
||||
if (secType == secTypeInvalid || clientSecTypeOrder) {
|
||||
for (int j = 0; j < nSecTypes; j++) {
|
||||
if (secTypes[j] == serverSecType && j < secTypePos) {
|
||||
secType = secTypes[j];
|
||||
secTypePos = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// NB: Continue reading the remaining server secTypes, but ignore them
|
||||
}
|
||||
}
|
||||
|
||||
// Inform the server of our decision
|
||||
if (secType != secTypeInvalid) {
|
||||
os->writeU8(secType);
|
||||
os->flush();
|
||||
vlog.debug("Choosing security type %s(%d)",secTypeName(secType),secType);
|
||||
}
|
||||
}
|
||||
|
||||
if (secType == secTypeInvalid) {
|
||||
state_ = RFBSTATE_INVALID;
|
||||
vlog.error("No matching security types");
|
||||
throw Exception("No matching security types");
|
||||
}
|
||||
|
||||
state_ = RFBSTATE_SECURITY;
|
||||
security = getCSecurity(secType);
|
||||
processSecurityMsg();
|
||||
}
|
||||
|
||||
void CConnection::processSecurityMsg()
|
||||
{
|
||||
vlog.debug("processing security message");
|
||||
bool done;
|
||||
if (!security->processMsg(this, &done))
|
||||
throwAuthFailureException();
|
||||
if (done) {
|
||||
state_ = RFBSTATE_SECURITY_RESULT;
|
||||
processSecurityResultMsg();
|
||||
}
|
||||
}
|
||||
|
||||
void CConnection::processSecurityResultMsg()
|
||||
{
|
||||
vlog.debug("processing security result message");
|
||||
int result;
|
||||
if (cp.beforeVersion(3,8) && security->getType() == secTypeNone) {
|
||||
result = secResultOK;
|
||||
} else {
|
||||
if (!is->checkNoWait(1)) return;
|
||||
result = is->readU32();
|
||||
}
|
||||
switch (result) {
|
||||
case secResultOK:
|
||||
securityCompleted();
|
||||
break;
|
||||
case secResultFailed:
|
||||
vlog.debug("auth failed");
|
||||
throwAuthFailureException();
|
||||
case secResultTooMany:
|
||||
vlog.debug("auth failed - too many tries");
|
||||
throwAuthFailureException();
|
||||
default:
|
||||
vlog.error("unknown security result");
|
||||
throwAuthFailureException();
|
||||
};
|
||||
}
|
||||
|
||||
void CConnection::processInitMsg()
|
||||
{
|
||||
vlog.debug("reading server initialisation");
|
||||
reader_->readServerInit();
|
||||
}
|
||||
|
||||
void CConnection::throwAuthFailureException()
|
||||
{
|
||||
CharArray reason;
|
||||
vlog.debug("state=%d, ver=%d.%d", state(), cp.majorVersion, cp.minorVersion);
|
||||
if (state()==RFBSTATE_SECURITY_RESULT && !cp.beforeVersion(3,8)) {
|
||||
reason.buf = is->readString();
|
||||
} else {
|
||||
reason.buf = strDup("Authentication failure");
|
||||
}
|
||||
state_ = RFBSTATE_INVALID;
|
||||
vlog.error(reason.buf);
|
||||
throw AuthFailureException(reason.buf);
|
||||
}
|
||||
|
||||
void CConnection::throwConnFailedException()
|
||||
{
|
||||
state_ = RFBSTATE_INVALID;
|
||||
CharArray reason;
|
||||
reason.buf = is->readString();
|
||||
throw ConnFailedException(reason.buf);
|
||||
}
|
||||
|
||||
void CConnection::securityCompleted()
|
||||
{
|
||||
state_ = RFBSTATE_INITIALISATION;
|
||||
reader_ = new CMsgReaderV3(this, is);
|
||||
writer_ = new CMsgWriterV3(&cp, os);
|
||||
vlog.debug("Authentication success!");
|
||||
authSuccess();
|
||||
writer_->writeClientInit(shared);
|
||||
}
|
||||
|
||||
void CConnection::authSuccess()
|
||||
{
|
||||
}
|
||||
|
||||
void CConnection::serverInit()
|
||||
{
|
||||
state_ = RFBSTATE_NORMAL;
|
||||
vlog.debug("initialisation done");
|
||||
}
|
178
rfb/CConnection.h
Normal file
178
rfb/CConnection.h
Normal file
|
@ -0,0 +1,178 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
//
|
||||
// CConnection - class on the client side representing a connection to a
|
||||
// server. A derived class should override methods appropriately.
|
||||
//
|
||||
|
||||
#ifndef __RFB_CCONNECTION_H__
|
||||
#define __RFB_CCONNECTION_H__
|
||||
|
||||
#include <rdr/InStream.h>
|
||||
#include <rdr/OutStream.h>
|
||||
#include <rfb/CMsgHandler.h>
|
||||
#include <rfb/util.h>
|
||||
|
||||
namespace rfb {
|
||||
|
||||
class CMsgReader;
|
||||
class CMsgWriter;
|
||||
class CSecurity;
|
||||
class IdentityVerifier;
|
||||
|
||||
class CConnection : public CMsgHandler {
|
||||
public:
|
||||
|
||||
CConnection();
|
||||
virtual ~CConnection();
|
||||
|
||||
// ***
|
||||
void setServerName(const char* serverName_);
|
||||
|
||||
// Methods to initialise the connection
|
||||
|
||||
// setStreams() sets the streams to be used for the connection. These must
|
||||
// be set before initialiseProtocol() and processMsg() are called. The
|
||||
// CSecurity object may call setStreams() again to provide alternative
|
||||
// streams over which the RFB protocol is sent (i.e. encrypting/decrypting
|
||||
// streams). Ownership of the streams remains with the caller
|
||||
// (i.e. SConnection will not delete them).
|
||||
void setStreams(rdr::InStream* is, rdr::OutStream* os);
|
||||
|
||||
// addSecType() should be called once for each security type which the
|
||||
// client supports. The order in which they're added is such that the
|
||||
// first one is most preferred.
|
||||
void addSecType(rdr::U8 secType);
|
||||
|
||||
// setClientSecTypeOrder() determines whether the client should obey
|
||||
// the server's security type preference, by picking the first server security
|
||||
// type that the client supports, or whether it should pick the first type
|
||||
// that the server supports, from the client-supported list of types.
|
||||
void setClientSecTypeOrder(bool clientOrder);
|
||||
|
||||
// setShared sets the value of the shared flag which will be sent to the
|
||||
// server upon initialisation.
|
||||
void setShared(bool s) { shared = s; }
|
||||
|
||||
// setProtocol3_3 configures whether or not the CConnection should
|
||||
// only ever support protocol version 3.3
|
||||
void setProtocol3_3(bool s) {useProtocol3_3 = s;}
|
||||
|
||||
// initialiseProtocol() should be called once the streams and security
|
||||
// types are set. Subsequently, processMsg() should be called whenever
|
||||
// there is data to read on the InStream.
|
||||
void initialiseProtocol();
|
||||
|
||||
// processMsg() should be called whenever there is either:
|
||||
// - data available on the underlying network stream
|
||||
// In this case, processMsg may return without processing an RFB message,
|
||||
// if the available data does not result in an RFB message being ready
|
||||
// to handle. e.g. if data is encrypted.
|
||||
// NB: This makes it safe to call processMsg() in response to select()
|
||||
// - data available on the CConnection's current InStream
|
||||
// In this case, processMsg should always process the available RFB
|
||||
// message before returning.
|
||||
// NB: In either case, you must have called initialiseProtocol() first.
|
||||
void processMsg();
|
||||
|
||||
|
||||
// Methods to be overridden in a derived class
|
||||
|
||||
// getCSecurity() gets the CSecurity object for the given type. The type
|
||||
// is guaranteed to be one of the secTypes passed in to addSecType(). The
|
||||
// CSecurity object's destroy() method will be called by the CConnection
|
||||
// from its destructor.
|
||||
virtual CSecurity* getCSecurity(int secType)=0;
|
||||
|
||||
// getCurrentCSecurity() gets the CSecurity instance used for this connection.
|
||||
const CSecurity* getCurrentCSecurity() const {return security;}
|
||||
|
||||
// getIdVerifier() returns the identity verifier associated with the connection.
|
||||
// Ownership of the IdentityVerifier is retained by the CConnection instance.
|
||||
virtual IdentityVerifier* getIdentityVerifier() {return 0;}
|
||||
|
||||
// authSuccess() is called when authentication has succeeded.
|
||||
virtual void authSuccess();
|
||||
|
||||
// serverInit() is called when the ServerInit message is received. The
|
||||
// derived class must call on to CConnection::serverInit().
|
||||
virtual void serverInit();
|
||||
|
||||
|
||||
// Other methods
|
||||
|
||||
// deleteReaderAndWriter() deletes the reader and writer associated with
|
||||
// this connection. This may be useful if you want to delete the streams
|
||||
// before deleting the SConnection to make sure that no attempt by the
|
||||
// SConnection is made to read or write.
|
||||
// XXX Do we really need this at all???
|
||||
void deleteReaderAndWriter();
|
||||
|
||||
CMsgReader* reader() { return reader_; }
|
||||
CMsgWriter* writer() { return writer_; }
|
||||
|
||||
rdr::InStream* getInStream() { return is; }
|
||||
rdr::OutStream* getOutStream() { return os; }
|
||||
|
||||
char* getServerName() {return strDup(serverName.buf);}
|
||||
|
||||
enum stateEnum {
|
||||
RFBSTATE_UNINITIALISED,
|
||||
RFBSTATE_PROTOCOL_VERSION,
|
||||
RFBSTATE_SECURITY_TYPES,
|
||||
RFBSTATE_SECURITY,
|
||||
RFBSTATE_SECURITY_RESULT,
|
||||
RFBSTATE_INITIALISATION,
|
||||
RFBSTATE_NORMAL,
|
||||
RFBSTATE_INVALID
|
||||
};
|
||||
|
||||
stateEnum state() { return state_; }
|
||||
|
||||
protected:
|
||||
void setState(stateEnum s) { state_ = s; }
|
||||
|
||||
private:
|
||||
void processVersionMsg();
|
||||
void processSecurityTypesMsg();
|
||||
void processSecurityMsg();
|
||||
void processSecurityResultMsg();
|
||||
void processInitMsg();
|
||||
void throwAuthFailureException();
|
||||
void throwConnFailedException();
|
||||
void securityCompleted();
|
||||
|
||||
rdr::InStream* is;
|
||||
rdr::OutStream* os;
|
||||
CMsgReader* reader_;
|
||||
CMsgWriter* writer_;
|
||||
bool deleteStreamsWhenDone;
|
||||
bool shared;
|
||||
CSecurity* security;
|
||||
enum { maxSecTypes = 8 };
|
||||
int nSecTypes;
|
||||
rdr::U8 secTypes[maxSecTypes];
|
||||
bool clientSecTypeOrder;
|
||||
stateEnum state_;
|
||||
|
||||
CharArray serverName;
|
||||
|
||||
bool useProtocol3_3;
|
||||
};
|
||||
}
|
||||
#endif
|
99
rfb/CMsgHandler.cxx
Normal file
99
rfb/CMsgHandler.cxx
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#include <rfb/Exception.h>
|
||||
#include <rfb/CMsgHandler.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
CMsgHandler::CMsgHandler()
|
||||
{
|
||||
}
|
||||
|
||||
CMsgHandler::~CMsgHandler()
|
||||
{
|
||||
}
|
||||
|
||||
void CMsgHandler::setDesktopSize(int width, int height)
|
||||
{
|
||||
cp.width = width;
|
||||
cp.height = height;
|
||||
}
|
||||
|
||||
void CMsgHandler::setCursor(const Point& hotspot, const Point& size, void* data, void* mask)
|
||||
{
|
||||
}
|
||||
|
||||
void CMsgHandler::setPixelFormat(const PixelFormat& pf)
|
||||
{
|
||||
cp.setPF(pf);
|
||||
}
|
||||
|
||||
void CMsgHandler::setName(const char* name)
|
||||
{
|
||||
cp.setName(name);
|
||||
}
|
||||
|
||||
void CMsgHandler::serverInit()
|
||||
{
|
||||
throw Exception("CMsgHandler::serverInit called");
|
||||
}
|
||||
|
||||
void CMsgHandler::framebufferUpdateStart()
|
||||
{
|
||||
}
|
||||
|
||||
void CMsgHandler::framebufferUpdateEnd()
|
||||
{
|
||||
}
|
||||
|
||||
void CMsgHandler::beginRect(const Rect& r, unsigned int encoding)
|
||||
{
|
||||
}
|
||||
|
||||
void CMsgHandler::endRect(const Rect& r, unsigned int encoding)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CMsgHandler::setColourMapEntries(int firstColour, int nColours,
|
||||
rdr::U16* rgbs)
|
||||
{
|
||||
throw Exception("CMsgHandler::setColourMapEntries called");
|
||||
}
|
||||
|
||||
void CMsgHandler::bell()
|
||||
{
|
||||
}
|
||||
|
||||
void CMsgHandler::serverCutText(const char* str, int len)
|
||||
{
|
||||
}
|
||||
|
||||
void CMsgHandler::fillRect(const Rect& r, Pixel pix)
|
||||
{
|
||||
}
|
||||
|
||||
void CMsgHandler::imageRect(const Rect& r, void* pixels)
|
||||
{
|
||||
}
|
||||
|
||||
void CMsgHandler::copyRect(const Rect& r, int srcX, int srcY)
|
||||
{
|
||||
}
|
||||
|
||||
|
62
rfb/CMsgHandler.h
Normal file
62
rfb/CMsgHandler.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
//
|
||||
// CMsgHandler - class to handle incoming messages on the client side.
|
||||
//
|
||||
|
||||
#ifndef __RFB_CMSGHANDLER_H__
|
||||
#define __RFB_CMSGHANDLER_H__
|
||||
|
||||
#include <rdr/types.h>
|
||||
#include <rfb/Pixel.h>
|
||||
#include <rfb/ConnParams.h>
|
||||
#include <rfb/Rect.h>
|
||||
|
||||
namespace rdr { class InStream; }
|
||||
|
||||
namespace rfb {
|
||||
|
||||
class CMsgHandler {
|
||||
public:
|
||||
CMsgHandler();
|
||||
virtual ~CMsgHandler();
|
||||
|
||||
virtual void setDesktopSize(int w, int h);
|
||||
virtual void setCursor(const Point& hotspot, const Point& size, void* data, void* mask);
|
||||
virtual void setPixelFormat(const PixelFormat& pf);
|
||||
virtual void setName(const char* name);
|
||||
virtual void serverInit();
|
||||
|
||||
virtual void framebufferUpdateStart();
|
||||
virtual void framebufferUpdateEnd();
|
||||
virtual void beginRect(const Rect& r, unsigned int encoding);
|
||||
virtual void endRect(const Rect& r, unsigned int encoding);
|
||||
|
||||
virtual void setColourMapEntries(int firstColour, int nColours,
|
||||
rdr::U16* rgbs);
|
||||
virtual void bell();
|
||||
virtual void serverCutText(const char* str, int len);
|
||||
|
||||
virtual void fillRect(const Rect& r, Pixel pix);
|
||||
virtual void imageRect(const Rect& r, void* pixels);
|
||||
virtual void copyRect(const Rect& r, int srcX, int srcY);
|
||||
|
||||
ConnParams cp;
|
||||
};
|
||||
}
|
||||
#endif
|
167
rfb/CMsgReader.cxx
Normal file
167
rfb/CMsgReader.cxx
Normal file
|
@ -0,0 +1,167 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <rdr/InStream.h>
|
||||
#include <rfb/Exception.h>
|
||||
#include <rfb/util.h>
|
||||
#include <rfb/CMsgHandler.h>
|
||||
#include <rfb/CMsgReader.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
CMsgReader::CMsgReader(CMsgHandler* handler_, rdr::InStream* is_)
|
||||
: imageBufIdealSize(0), handler(handler_), is(is_),
|
||||
imageBuf(0), imageBufSize(0)
|
||||
{
|
||||
for (unsigned int i = 0; i <= encodingMax; i++) {
|
||||
decoders[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CMsgReader::~CMsgReader()
|
||||
{
|
||||
for (unsigned int i = 0; i <= encodingMax; i++) {
|
||||
delete decoders[i];
|
||||
}
|
||||
delete [] imageBuf;
|
||||
}
|
||||
|
||||
void CMsgReader::endMsg()
|
||||
{
|
||||
}
|
||||
|
||||
void CMsgReader::readSetColourMapEntries()
|
||||
{
|
||||
is->skip(1);
|
||||
int firstColour = is->readU16();
|
||||
int nColours = is->readU16();
|
||||
rdr::U16Array rgbs(nColours * 3);
|
||||
for (int i = 0; i < nColours * 3; i++)
|
||||
rgbs.buf[i] = is->readU16();
|
||||
endMsg();
|
||||
handler->setColourMapEntries(firstColour, nColours, rgbs.buf);
|
||||
}
|
||||
|
||||
void CMsgReader::readBell()
|
||||
{
|
||||
endMsg();
|
||||
handler->bell();
|
||||
}
|
||||
|
||||
void CMsgReader::readServerCutText()
|
||||
{
|
||||
is->skip(3);
|
||||
int len = is->readU32();
|
||||
if (len > 256*1024) {
|
||||
is->skip(len);
|
||||
fprintf(stderr,"cut text too long (%d bytes) - ignoring\n",len);
|
||||
return;
|
||||
}
|
||||
CharArray ca(len+1);
|
||||
ca.buf[len] = 0;
|
||||
is->readBytes(ca.buf, len);
|
||||
endMsg();
|
||||
handler->serverCutText(ca.buf, len);
|
||||
}
|
||||
|
||||
void CMsgReader::readFramebufferUpdateStart()
|
||||
{
|
||||
endMsg();
|
||||
handler->framebufferUpdateStart();
|
||||
}
|
||||
|
||||
void CMsgReader::readFramebufferUpdateEnd()
|
||||
{
|
||||
endMsg();
|
||||
handler->framebufferUpdateEnd();
|
||||
}
|
||||
|
||||
void CMsgReader::readRect(const Rect& r, unsigned int encoding)
|
||||
{
|
||||
if ((r.br.x > handler->cp.width) || (r.br.y > handler->cp.height)) {
|
||||
fprintf(stderr, "Rect too big: %dx%d at %d,%d exceeds %dx%d\n",
|
||||
r.width(), r.height(), r.tl.x, r.tl.y,
|
||||
handler->cp.width, handler->cp.height);
|
||||
throw Exception("Rect too big");
|
||||
}
|
||||
|
||||
if (r.is_empty())
|
||||
fprintf(stderr, "Warning: zero size rect\n");
|
||||
|
||||
handler->beginRect(r, encoding);
|
||||
|
||||
if (encoding == encodingCopyRect) {
|
||||
readCopyRect(r);
|
||||
} else {
|
||||
if (!decoders[encoding]) {
|
||||
decoders[encoding] = Decoder::createDecoder(encoding, this);
|
||||
if (!decoders[encoding]) {
|
||||
fprintf(stderr, "Unknown rect encoding %d\n", encoding);
|
||||
throw Exception("Unknown rect encoding");
|
||||
}
|
||||
}
|
||||
decoders[encoding]->readRect(r, handler);
|
||||
}
|
||||
|
||||
handler->endRect(r, encoding);
|
||||
}
|
||||
|
||||
void CMsgReader::readCopyRect(const Rect& r)
|
||||
{
|
||||
int srcX = is->readU16();
|
||||
int srcY = is->readU16();
|
||||
handler->copyRect(r, srcX, srcY);
|
||||
}
|
||||
|
||||
void CMsgReader::readSetCursor(const Point& hotspot, const Point& size)
|
||||
{
|
||||
int data_len = size.x * size.y * (handler->cp.pf().bpp/8);
|
||||
int mask_len = ((size.x+7)/8) * size.y;
|
||||
rdr::U8Array data(data_len);
|
||||
rdr::U8Array mask(mask_len);
|
||||
|
||||
is->readBytes(data.buf, data_len);
|
||||
is->readBytes(mask.buf, mask_len);
|
||||
|
||||
handler->setCursor(hotspot, size, data.buf, mask.buf);
|
||||
}
|
||||
|
||||
rdr::U8* CMsgReader::getImageBuf(int required, int requested, int* nPixels)
|
||||
{
|
||||
int requiredBytes = required * (handler->cp.pf().bpp / 8);
|
||||
int requestedBytes = requested * (handler->cp.pf().bpp / 8);
|
||||
int size = requestedBytes;
|
||||
if (size > imageBufIdealSize) size = imageBufIdealSize;
|
||||
|
||||
if (size < requiredBytes)
|
||||
size = requiredBytes;
|
||||
|
||||
if (imageBufSize < size) {
|
||||
imageBufSize = size;
|
||||
delete [] imageBuf;
|
||||
imageBuf = new rdr::U8[imageBufSize];
|
||||
}
|
||||
if (nPixels)
|
||||
*nPixels = imageBufSize / (handler->cp.pf().bpp / 8);
|
||||
return imageBuf;
|
||||
}
|
||||
|
||||
int CMsgReader::bpp()
|
||||
{
|
||||
return handler->cp.pf().bpp;
|
||||
}
|
75
rfb/CMsgReader.h
Normal file
75
rfb/CMsgReader.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
//
|
||||
// CMsgReader - class for reading RFB messages on the server side
|
||||
// (i.e. messages from client to server).
|
||||
//
|
||||
|
||||
#ifndef __RFB_CMSGREADER_H__
|
||||
#define __RFB_CMSGREADER_H__
|
||||
|
||||
#include <rdr/types.h>
|
||||
#include <rfb/encodings.h>
|
||||
#include <rfb/Decoder.h>
|
||||
|
||||
namespace rdr { class InStream; }
|
||||
|
||||
namespace rfb {
|
||||
class CMsgHandler;
|
||||
struct Rect;
|
||||
|
||||
class CMsgReader {
|
||||
public:
|
||||
virtual ~CMsgReader();
|
||||
|
||||
virtual void readServerInit()=0;
|
||||
|
||||
// readMsg() reads a message, calling the handler as appropriate.
|
||||
virtual void readMsg()=0;
|
||||
|
||||
rdr::InStream* getInStream() { return is; }
|
||||
rdr::U8* getImageBuf(int required, int requested=0, int* nPixels=0);
|
||||
int bpp();
|
||||
|
||||
int imageBufIdealSize;
|
||||
|
||||
protected:
|
||||
virtual void readSetColourMapEntries();
|
||||
virtual void readBell();
|
||||
virtual void readServerCutText();
|
||||
|
||||
virtual void endMsg();
|
||||
|
||||
virtual void readFramebufferUpdateStart();
|
||||
virtual void readFramebufferUpdateEnd();
|
||||
virtual void readRect(const Rect& r, unsigned int encoding);
|
||||
|
||||
virtual void readCopyRect(const Rect& r);
|
||||
|
||||
virtual void readSetCursor(const Point& hotspot, const Point& size);
|
||||
|
||||
CMsgReader(CMsgHandler* handler, rdr::InStream* is);
|
||||
|
||||
CMsgHandler* handler;
|
||||
rdr::InStream* is;
|
||||
Decoder* decoders[encodingMax+1];
|
||||
rdr::U8* imageBuf;
|
||||
int imageBufSize;
|
||||
};
|
||||
}
|
||||
#endif
|
97
rfb/CMsgReaderV3.cxx
Normal file
97
rfb/CMsgReaderV3.cxx
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#include <rfb/PixelFormat.h>
|
||||
#include <rfb/msgTypes.h>
|
||||
#include <rfb/Exception.h>
|
||||
#include <rdr/InStream.h>
|
||||
#include <rfb/CMsgReaderV3.h>
|
||||
#include <rfb/CMsgHandler.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
CMsgReaderV3::CMsgReaderV3(CMsgHandler* handler, rdr::InStream* is)
|
||||
: CMsgReader(handler, is), nUpdateRectsLeft(0)
|
||||
{
|
||||
}
|
||||
|
||||
CMsgReaderV3::~CMsgReaderV3()
|
||||
{
|
||||
}
|
||||
|
||||
void CMsgReaderV3::readServerInit()
|
||||
{
|
||||
int width = is->readU16();
|
||||
int height = is->readU16();
|
||||
handler->setDesktopSize(width, height);
|
||||
PixelFormat pf;
|
||||
pf.read(is);
|
||||
handler->setPixelFormat(pf);
|
||||
char* name = is->readString();
|
||||
handler->setName(name);
|
||||
delete [] name;
|
||||
endMsg();
|
||||
handler->serverInit();
|
||||
}
|
||||
|
||||
void CMsgReaderV3::readMsg()
|
||||
{
|
||||
if (nUpdateRectsLeft == 0) {
|
||||
|
||||
int type = is->readU8();
|
||||
switch (type) {
|
||||
case msgTypeFramebufferUpdate: readFramebufferUpdate(); break;
|
||||
case msgTypeSetColourMapEntries: readSetColourMapEntries(); break;
|
||||
case msgTypeBell: readBell(); break;
|
||||
case msgTypeServerCutText: readServerCutText(); break;
|
||||
default:
|
||||
fprintf(stderr, "unknown message type %d\n", type);
|
||||
throw Exception("unknown message type");
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
int x = is->readU16();
|
||||
int y = is->readU16();
|
||||
int w = is->readU16();
|
||||
int h = is->readU16();
|
||||
unsigned int encoding = is->readU32();
|
||||
|
||||
switch (encoding) {
|
||||
case pseudoEncodingDesktopSize:
|
||||
handler->setDesktopSize(w, h);
|
||||
break;
|
||||
case pseudoEncodingCursor:
|
||||
readSetCursor(Point(x, y), Point(w, h));
|
||||
break;
|
||||
default:
|
||||
readRect(Rect(x, y, x+w, y+h), encoding);
|
||||
break;
|
||||
};
|
||||
|
||||
nUpdateRectsLeft--;
|
||||
if (nUpdateRectsLeft == 0) handler->framebufferUpdateEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void CMsgReaderV3::readFramebufferUpdate()
|
||||
{
|
||||
is->skip(1);
|
||||
nUpdateRectsLeft = is->readU16();
|
||||
endMsg();
|
||||
handler->framebufferUpdateStart();
|
||||
}
|
35
rfb/CMsgReaderV3.h
Normal file
35
rfb/CMsgReaderV3.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef __RFB_CMSGREADERV3_H__
|
||||
#define __RFB_CMSGREADERV3_H__
|
||||
|
||||
#include <rfb/CMsgReader.h>
|
||||
|
||||
namespace rfb {
|
||||
class CMsgReaderV3 : public CMsgReader {
|
||||
public:
|
||||
CMsgReaderV3(CMsgHandler* handler, rdr::InStream* is);
|
||||
virtual ~CMsgReaderV3();
|
||||
virtual void readServerInit();
|
||||
virtual void readMsg();
|
||||
private:
|
||||
void readFramebufferUpdate();
|
||||
int nUpdateRectsLeft;
|
||||
};
|
||||
}
|
||||
#endif
|
130
rfb/CMsgWriter.cxx
Normal file
130
rfb/CMsgWriter.cxx
Normal file
|
@ -0,0 +1,130 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <rdr/OutStream.h>
|
||||
#include <rfb/msgTypes.h>
|
||||
#include <rfb/PixelFormat.h>
|
||||
#include <rfb/Rect.h>
|
||||
#include <rfb/ConnParams.h>
|
||||
#include <rfb/Decoder.h>
|
||||
#include <rfb/CMsgWriter.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
CMsgWriter::CMsgWriter(ConnParams* cp_, rdr::OutStream* os_)
|
||||
: cp(cp_), os(os_)
|
||||
{
|
||||
}
|
||||
|
||||
CMsgWriter::~CMsgWriter()
|
||||
{
|
||||
}
|
||||
|
||||
void CMsgWriter::writeSetPixelFormat(const PixelFormat& pf)
|
||||
{
|
||||
startMsg(msgTypeSetPixelFormat);
|
||||
os->pad(3);
|
||||
pf.write(os);
|
||||
endMsg();
|
||||
}
|
||||
|
||||
void CMsgWriter::writeSetEncodings(int nEncodings, rdr::U32* encodings)
|
||||
{
|
||||
startMsg(msgTypeSetEncodings);
|
||||
os->skip(1);
|
||||
os->writeU16(nEncodings);
|
||||
for (int i = 0; i < nEncodings; i++)
|
||||
os->writeU32(encodings[i]);
|
||||
endMsg();
|
||||
}
|
||||
|
||||
// Ask for encodings based on which decoders are supported. Assumes higher
|
||||
// encoding numbers are more desirable.
|
||||
|
||||
void CMsgWriter::writeSetEncodings(int preferredEncoding, bool useCopyRect)
|
||||
{
|
||||
int nEncodings = 0;
|
||||
rdr::U32 encodings[encodingMax+2];
|
||||
if (cp->supportsLocalCursor)
|
||||
encodings[nEncodings++] = pseudoEncodingCursor;
|
||||
if (cp->supportsDesktopResize)
|
||||
encodings[nEncodings++] = pseudoEncodingDesktopSize;
|
||||
if (Decoder::supported(preferredEncoding)) {
|
||||
encodings[nEncodings++] = preferredEncoding;
|
||||
}
|
||||
if (useCopyRect) {
|
||||
encodings[nEncodings++] = encodingCopyRect;
|
||||
}
|
||||
for (int i = encodingMax; i >= 0; i--) {
|
||||
if (i != preferredEncoding && Decoder::supported(i)) {
|
||||
encodings[nEncodings++] = i;
|
||||
}
|
||||
}
|
||||
writeSetEncodings(nEncodings, encodings);
|
||||
}
|
||||
|
||||
void CMsgWriter::writeFramebufferUpdateRequest(const Rect& r, bool incremental)
|
||||
{
|
||||
startMsg(msgTypeFramebufferUpdateRequest);
|
||||
os->writeU8(incremental);
|
||||
os->writeU16(r.tl.x);
|
||||
os->writeU16(r.tl.y);
|
||||
os->writeU16(r.width());
|
||||
os->writeU16(r.height());
|
||||
endMsg();
|
||||
}
|
||||
|
||||
|
||||
void CMsgWriter::writeKeyEvent(rdr::U32 key, bool down)
|
||||
{
|
||||
startMsg(msgTypeKeyEvent);
|
||||
os->writeU8(down);
|
||||
os->pad(2);
|
||||
os->writeU32(key);
|
||||
endMsg();
|
||||
}
|
||||
|
||||
|
||||
void CMsgWriter::writePointerEvent(int x, int y, int buttonMask)
|
||||
{
|
||||
if (x < 0) x = 0;
|
||||
if (y < 0) y = 0;
|
||||
if (x >= cp->width) x = cp->width - 1;
|
||||
if (y >= cp->height) y = cp->height - 1;
|
||||
|
||||
startMsg(msgTypePointerEvent);
|
||||
os->writeU8(buttonMask);
|
||||
os->writeU16(x);
|
||||
os->writeU16(y);
|
||||
endMsg();
|
||||
}
|
||||
|
||||
|
||||
void CMsgWriter::writeClientCutText(const char* str, int len)
|
||||
{
|
||||
startMsg(msgTypeClientCutText);
|
||||
os->pad(3);
|
||||
os->writeU32(len);
|
||||
os->writeBytes(str, len);
|
||||
endMsg();
|
||||
}
|
||||
|
||||
void CMsgWriter::setOutStream(rdr::OutStream* os_)
|
||||
{
|
||||
os = os_;
|
||||
}
|
64
rfb/CMsgWriter.h
Normal file
64
rfb/CMsgWriter.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
//
|
||||
// CMsgWriter - class for writing RFB messages on the server side.
|
||||
//
|
||||
|
||||
#ifndef __RFB_CMSGWRITER_H__
|
||||
#define __RFB_CMSGWRITER_H__
|
||||
|
||||
#include <rdr/types.h>
|
||||
|
||||
namespace rdr { class OutStream; }
|
||||
|
||||
namespace rfb {
|
||||
|
||||
class PixelFormat;
|
||||
class ConnParams;
|
||||
struct Rect;
|
||||
|
||||
class CMsgWriter {
|
||||
public:
|
||||
virtual ~CMsgWriter();
|
||||
|
||||
virtual void writeClientInit(bool shared)=0;
|
||||
|
||||
virtual void writeSetPixelFormat(const PixelFormat& pf);
|
||||
virtual void writeSetEncodings(int nEncodings, rdr::U32* encodings);
|
||||
virtual void writeSetEncodings(int preferredEncoding, bool useCopyRect);
|
||||
virtual void writeFramebufferUpdateRequest(const Rect& r,bool incremental);
|
||||
virtual void writeKeyEvent(rdr::U32 key, bool down);
|
||||
virtual void writePointerEvent(int x, int y, int buttonMask);
|
||||
virtual void writeClientCutText(const char* str, int len);
|
||||
|
||||
virtual void startMsg(int type)=0;
|
||||
virtual void endMsg()=0;
|
||||
|
||||
virtual void setOutStream(rdr::OutStream* os);
|
||||
|
||||
ConnParams* getConnParams() { return cp; }
|
||||
rdr::OutStream* getOutStream() { return os; }
|
||||
|
||||
protected:
|
||||
CMsgWriter(ConnParams* cp, rdr::OutStream* os);
|
||||
|
||||
ConnParams* cp;
|
||||
rdr::OutStream* os;
|
||||
};
|
||||
}
|
||||
#endif
|
49
rfb/CMsgWriterV3.cxx
Normal file
49
rfb/CMsgWriterV3.cxx
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#include <rdr/OutStream.h>
|
||||
#include <rfb/msgTypes.h>
|
||||
#include <rfb/Exception.h>
|
||||
#include <rfb/ConnParams.h>
|
||||
#include <rfb/CMsgWriterV3.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
CMsgWriterV3::CMsgWriterV3(ConnParams* cp, rdr::OutStream* os)
|
||||
: CMsgWriter(cp, os)
|
||||
{
|
||||
}
|
||||
|
||||
CMsgWriterV3::~CMsgWriterV3()
|
||||
{
|
||||
}
|
||||
|
||||
void CMsgWriterV3::writeClientInit(bool shared)
|
||||
{
|
||||
os->writeU8(shared);
|
||||
endMsg();
|
||||
}
|
||||
|
||||
void CMsgWriterV3::startMsg(int type)
|
||||
{
|
||||
os->writeU8(type);
|
||||
}
|
||||
|
||||
void CMsgWriterV3::endMsg()
|
||||
{
|
||||
os->flush();
|
||||
}
|
35
rfb/CMsgWriterV3.h
Normal file
35
rfb/CMsgWriterV3.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef __RFB_CMSGWRITERV3_H__
|
||||
#define __RFB_CMSGWRITERV3_H__
|
||||
|
||||
#include <rfb/CMsgWriter.h>
|
||||
|
||||
namespace rfb {
|
||||
class CMsgWriterV3 : public CMsgWriter {
|
||||
public:
|
||||
CMsgWriterV3(ConnParams* cp, rdr::OutStream* os);
|
||||
virtual ~CMsgWriterV3();
|
||||
|
||||
virtual void writeClientInit(bool shared);
|
||||
virtual void startMsg(int type);
|
||||
virtual void endMsg();
|
||||
|
||||
};
|
||||
}
|
||||
#endif
|
48
rfb/CSecurity.h
Normal file
48
rfb/CSecurity.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
//
|
||||
// CSecurity - class on the client side for handling security handshaking. A
|
||||
// derived class for a particular security type overrides the processMsg()
|
||||
// method. processMsg() is called first when the security type has been
|
||||
// decided on, and will keep being called whenever there is data to read from
|
||||
// the server until either it returns false, indicating authentication/security
|
||||
// failure, or it returns with done set to true, to indicate success.
|
||||
//
|
||||
// Note that the first time processMsg() is called, there is no guarantee that
|
||||
// there is any data to read from the CConnection's InStream, but subsequent
|
||||
// calls guarantee there is at least one byte which can be read without
|
||||
// blocking.
|
||||
//
|
||||
// description is a string describing the level of encryption applied to the
|
||||
// session, or null if no encryption will be used.
|
||||
|
||||
#ifndef __RFB_CSECURITY_H__
|
||||
#define __RFB_CSECURITY_H__
|
||||
|
||||
namespace rfb {
|
||||
class CConnection;
|
||||
class CSecurity {
|
||||
public:
|
||||
virtual ~CSecurity() {}
|
||||
virtual bool processMsg(CConnection* cc, bool* done)=0;
|
||||
virtual void destroy() { delete this; }
|
||||
virtual int getType() const = 0;
|
||||
virtual const char* description() const = 0;
|
||||
};
|
||||
}
|
||||
#endif
|
38
rfb/CSecurityNone.h
Normal file
38
rfb/CSecurityNone.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
//
|
||||
// CSecurityNone.h
|
||||
//
|
||||
|
||||
#ifndef __CSECURITYNONE_H__
|
||||
#define __CSECURITYNONE_H__
|
||||
|
||||
#include <rfb/CSecurity.h>
|
||||
|
||||
namespace rfb {
|
||||
|
||||
class CSecurityNone : public CSecurity {
|
||||
public:
|
||||
virtual bool processMsg(CConnection* cc, bool* done) {
|
||||
*done = true; return true;
|
||||
}
|
||||
virtual int getType() const {return secTypeNone;}
|
||||
virtual const char* description() const {return "No Encryption";}
|
||||
};
|
||||
}
|
||||
#endif
|
63
rfb/CSecurityVncAuth.cxx
Normal file
63
rfb/CSecurityVncAuth.cxx
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
//
|
||||
// CSecurityVncAuth
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <rfb/CConnection.h>
|
||||
#include <rfb/UserPasswdGetter.h>
|
||||
#include <rfb/vncAuth.h>
|
||||
#include <rfb/CSecurityVncAuth.h>
|
||||
#include <rfb/LogWriter.h>
|
||||
#include <rfb/util.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
static LogWriter vlog("VncAuth");
|
||||
|
||||
CSecurityVncAuth::CSecurityVncAuth(UserPasswdGetter* upg_)
|
||||
: upg(upg_)
|
||||
{
|
||||
}
|
||||
|
||||
CSecurityVncAuth::~CSecurityVncAuth()
|
||||
{
|
||||
}
|
||||
|
||||
bool CSecurityVncAuth::processMsg(CConnection* cc, bool* done)
|
||||
{
|
||||
*done = false;
|
||||
rdr::InStream* is = cc->getInStream();
|
||||
rdr::OutStream* os = cc->getOutStream();
|
||||
|
||||
rdr::U8 challenge[vncAuthChallengeSize];
|
||||
is->readBytes(challenge, vncAuthChallengeSize);
|
||||
CharArray passwd;
|
||||
if (!upg->getUserPasswd(0, &passwd.buf)) {
|
||||
vlog.error("Getting password failed");
|
||||
return false;
|
||||
}
|
||||
vncAuthEncryptChallenge(challenge, passwd.buf);
|
||||
memset(passwd.buf, 0, strlen(passwd.buf));
|
||||
os->writeBytes(challenge, vncAuthChallengeSize);
|
||||
os->flush();
|
||||
*done = true;
|
||||
return true;
|
||||
}
|
40
rfb/CSecurityVncAuth.h
Normal file
40
rfb/CSecurityVncAuth.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef __RFB_CSECURITYVNCAUTH_H__
|
||||
#define __RFB_CSECURITYVNCAUTH_H__
|
||||
|
||||
#include <rfb/CSecurity.h>
|
||||
#include <rfb/secTypes.h>
|
||||
#include <rfb/vncAuth.h>
|
||||
|
||||
namespace rfb {
|
||||
|
||||
class UserPasswdGetter;
|
||||
|
||||
class CSecurityVncAuth : public CSecurity {
|
||||
public:
|
||||
CSecurityVncAuth(UserPasswdGetter* pg);
|
||||
virtual ~CSecurityVncAuth();
|
||||
virtual bool processMsg(CConnection* cc, bool* done);
|
||||
virtual int getType() const {return secTypeVncAuth;};
|
||||
virtual const char* description() const {return "No Encryption";}
|
||||
private:
|
||||
UserPasswdGetter* upg;
|
||||
};
|
||||
}
|
||||
#endif
|
96
rfb/ColourCube.h
Normal file
96
rfb/ColourCube.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
//
|
||||
// ColourCube - structure to represent a colour cube. The colour cube consists
|
||||
// of its dimensions (nRed x nGreen x nBlue) and a table mapping an (r,g,b)
|
||||
// triple to a pixel value.
|
||||
//
|
||||
// A colour cube is used in two cases. The first is internally in a viewer
|
||||
// when it cannot use a trueColour format, nor can it have exclusive access to
|
||||
// a writable colour map. This is most notably the case for an X viewer
|
||||
// wishing to use a PseudoColor X server's default colormap.
|
||||
//
|
||||
// The second use is on the server side when a client has asked for a colour
|
||||
// map and the server is trueColour. Instead of setting an uneven trueColour
|
||||
// format like bgr233, it can set the client's colour map up with a 6x6x6
|
||||
// colour cube. For this use the colour cube table has a null mapping, which
|
||||
// makes it easy to perform the reverse lookup operation from pixel value to
|
||||
// r,g,b values.
|
||||
|
||||
#ifndef __RFB_COLOURCUBE_H__
|
||||
#define __RFB_COLOURCUBE_H__
|
||||
|
||||
#include <rfb/Pixel.h>
|
||||
#include <rfb/ColourMap.h>
|
||||
|
||||
namespace rfb {
|
||||
|
||||
class ColourCube : public ColourMap {
|
||||
public:
|
||||
ColourCube(int nr, int ng, int nb, Pixel* table_=0)
|
||||
: nRed(nr), nGreen(ng), nBlue(nb), table(table_), deleteTable(false)
|
||||
{
|
||||
if (!table) {
|
||||
table = new Pixel[size()];
|
||||
deleteTable = true;
|
||||
// set a null mapping by default
|
||||
for (int i = 0; i < size(); i++)
|
||||
table[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
ColourCube() : deleteTable(false) {}
|
||||
|
||||
virtual ~ColourCube() {
|
||||
if (deleteTable) delete [] table;
|
||||
}
|
||||
|
||||
void set(int r, int g, int b, Pixel p) {
|
||||
table[(r * nGreen + g) * nBlue + b] = p;
|
||||
}
|
||||
|
||||
Pixel lookup(int r, int g, int b) const {
|
||||
return table[(r * nGreen + g) * nBlue + b];
|
||||
}
|
||||
|
||||
int size() const { return nRed*nGreen*nBlue; }
|
||||
int redMult() const { return nGreen*nBlue; }
|
||||
int greenMult() const { return nBlue; }
|
||||
int blueMult() const { return 1; }
|
||||
|
||||
// ColourMap lookup() method. Note that this only works when the table has
|
||||
// the default null mapping.
|
||||
virtual void lookup(int i, int* r, int* g, int* b) {
|
||||
if (i >= size()) return;
|
||||
*b = i % nBlue;
|
||||
i /= nBlue;
|
||||
*g = i % nGreen;
|
||||
*r = i / nGreen;
|
||||
*r = (*r * 65535 + (nRed-1) / 2) / (nRed-1);
|
||||
*g = (*g * 65535 + (nGreen-1) / 2) / (nGreen-1);
|
||||
*b = (*b * 65535 + (nBlue-1) / 2) / (nBlue-1);
|
||||
}
|
||||
|
||||
int nRed;
|
||||
int nGreen;
|
||||
int nBlue;
|
||||
Pixel* table;
|
||||
bool deleteTable;
|
||||
};
|
||||
}
|
||||
#endif
|
34
rfb/ColourMap.h
Normal file
34
rfb/ColourMap.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef __RFB_COLOURMAP_H__
|
||||
#define __RFB_COLOURMAP_H__
|
||||
namespace rfb {
|
||||
struct Colour {
|
||||
Colour() : r(0), g(0), b(0) {}
|
||||
Colour(int r_, int g_, int b_) : r(r_), g(g_), b(b_) {}
|
||||
int r, g, b;
|
||||
bool operator==(const Colour& c) const {return c.r == r && c.g == g && c.b == b;}
|
||||
bool operator!=(const Colour& c) const {return !(c == *this);}
|
||||
};
|
||||
|
||||
class ColourMap {
|
||||
public:
|
||||
virtual void lookup(int index, int* r, int* g, int* b)=0;
|
||||
};
|
||||
}
|
||||
#endif
|
151
rfb/ComparingUpdateTracker.cxx
Normal file
151
rfb/ComparingUpdateTracker.cxx
Normal file
|
@ -0,0 +1,151 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include <rdr/types.h>
|
||||
#include <rfb/Exception.h>
|
||||
#include <rfb/ComparingUpdateTracker.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
ComparingUpdateTracker::ComparingUpdateTracker(PixelBuffer* buffer)
|
||||
: SimpleUpdateTracker(true), fb(buffer),
|
||||
oldFb(fb->getPF(), 0, 0), firstCompare(true)
|
||||
{
|
||||
changed.assign_union(fb->getRect());
|
||||
}
|
||||
|
||||
ComparingUpdateTracker::~ComparingUpdateTracker()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ComparingUpdateTracker::flush_update(UpdateInfo* info,
|
||||
const Region& cliprgn, int maxArea)
|
||||
{
|
||||
throw rfb::Exception("flush_update(UpdateInfo*) not implemented");
|
||||
}
|
||||
|
||||
void ComparingUpdateTracker::flush_update(UpdateTracker &ut,
|
||||
const Region &cliprgn)
|
||||
{
|
||||
throw rfb::Exception("flush_update(UpdateTracker&) not implemented");
|
||||
}
|
||||
|
||||
|
||||
#define BLOCK_SIZE 16
|
||||
|
||||
void ComparingUpdateTracker::compare()
|
||||
{
|
||||
std::vector<Rect> rects;
|
||||
std::vector<Rect>::iterator i;
|
||||
|
||||
if (firstCompare) {
|
||||
// NB: We leave the change region untouched on this iteration,
|
||||
// since in effect the entire framebuffer has changed.
|
||||
oldFb.setSize(fb->width(), fb->height());
|
||||
for (int y=0; y<fb->height(); y+=BLOCK_SIZE) {
|
||||
Rect pos(0, y, fb->width(), min(fb->height(), y+BLOCK_SIZE));
|
||||
int srcStride;
|
||||
const rdr::U8* srcData = fb->getPixelsR(pos, &srcStride);
|
||||
oldFb.imageRect(pos, srcData, srcStride);
|
||||
}
|
||||
firstCompare = false;
|
||||
} else {
|
||||
copied.get_rects(&rects, copy_delta.x<=0, copy_delta.y<=0);
|
||||
for (i = rects.begin(); i != rects.end(); i++)
|
||||
oldFb.copyRect(*i, copy_delta);
|
||||
|
||||
Region to_check = changed.union_(copied);
|
||||
to_check.get_rects(&rects);
|
||||
|
||||
Region newChanged;
|
||||
for (i = rects.begin(); i != rects.end(); i++)
|
||||
compareRect(*i, &newChanged);
|
||||
|
||||
copied.assign_subtract(newChanged);
|
||||
changed = newChanged;
|
||||
}
|
||||
}
|
||||
|
||||
void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged)
|
||||
{
|
||||
if (!r.enclosed_by(fb->getRect())) {
|
||||
fprintf(stderr,"ComparingUpdateTracker: rect outside fb (%d,%d-%d,%d)\n", r.tl.x, r.tl.y, r.br.x, r.br.y);
|
||||
return;
|
||||
}
|
||||
|
||||
int bytesPerPixel = fb->getPF().bpp/8;
|
||||
int oldStride;
|
||||
rdr::U8* oldData = oldFb.getPixelsRW(r, &oldStride);
|
||||
int oldStrideBytes = oldStride * bytesPerPixel;
|
||||
|
||||
std::vector<Rect> changedBlocks;
|
||||
|
||||
for (int blockTop = r.tl.y; blockTop < r.br.y; blockTop += BLOCK_SIZE)
|
||||
{
|
||||
// Get a strip of the source buffer
|
||||
Rect pos(r.tl.x, blockTop, r.br.x, min(r.br.y, blockTop+BLOCK_SIZE));
|
||||
int fbStride;
|
||||
const rdr::U8* newBlockPtr = fb->getPixelsR(pos, &fbStride);
|
||||
int newStrideBytes = fbStride * bytesPerPixel;
|
||||
|
||||
rdr::U8* oldBlockPtr = oldData;
|
||||
int blockBottom = min(blockTop+BLOCK_SIZE, r.br.y);
|
||||
|
||||
for (int blockLeft = r.tl.x; blockLeft < r.br.x; blockLeft += BLOCK_SIZE)
|
||||
{
|
||||
const rdr::U8* newPtr = newBlockPtr;
|
||||
rdr::U8* oldPtr = oldBlockPtr;
|
||||
|
||||
int blockRight = min(blockLeft+BLOCK_SIZE, r.br.x);
|
||||
int blockWidthInBytes = (blockRight-blockLeft) * bytesPerPixel;
|
||||
|
||||
for (int y = blockTop; y < blockBottom; y++)
|
||||
{
|
||||
if (memcmp(oldPtr, newPtr, blockWidthInBytes) != 0)
|
||||
{
|
||||
// A block has changed - copy the remainder to the oldFb
|
||||
changedBlocks.push_back(Rect(blockLeft, blockTop,
|
||||
blockRight, blockBottom));
|
||||
for (int y2 = y; y2 < blockBottom; y2++)
|
||||
{
|
||||
memcpy(oldPtr, newPtr, blockWidthInBytes);
|
||||
newPtr += newStrideBytes;
|
||||
oldPtr += oldStrideBytes;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
newPtr += newStrideBytes;
|
||||
oldPtr += oldStrideBytes;
|
||||
}
|
||||
|
||||
oldBlockPtr += blockWidthInBytes;
|
||||
newBlockPtr += blockWidthInBytes;
|
||||
}
|
||||
|
||||
oldData += oldStrideBytes * BLOCK_SIZE;
|
||||
}
|
||||
|
||||
if (!changedBlocks.empty()) {
|
||||
Region temp;
|
||||
temp.setOrderedRects(changedBlocks);
|
||||
newChanged->assign_union(temp);
|
||||
}
|
||||
}
|
47
rfb/ComparingUpdateTracker.h
Normal file
47
rfb/ComparingUpdateTracker.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RFB_COMPARINGUPDATETRACKER_H__
|
||||
#define __RFB_COMPARINGUPDATETRACKER_H__
|
||||
|
||||
#include <rfb/UpdateTracker.h>
|
||||
|
||||
namespace rfb {
|
||||
|
||||
class ComparingUpdateTracker : public SimpleUpdateTracker {
|
||||
public:
|
||||
ComparingUpdateTracker(PixelBuffer* buffer);
|
||||
~ComparingUpdateTracker();
|
||||
|
||||
// compare() does the comparison and reduces its changed and copied regions
|
||||
// as appropriate.
|
||||
|
||||
virtual void compare();
|
||||
|
||||
virtual void flush_update(UpdateInfo* info, const Region& cliprgn,
|
||||
int maxArea);
|
||||
virtual void flush_update(UpdateTracker &info, const Region &cliprgn);
|
||||
private:
|
||||
void compareRect(const Rect& r, Region* newchanged);
|
||||
PixelBuffer* fb;
|
||||
ManagedPixelBuffer oldFb;
|
||||
bool firstCompare;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
410
rfb/Configuration.cxx
Normal file
410
rfb/Configuration.cxx
Normal file
|
@ -0,0 +1,410 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
// -=- Configuration.cxx
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#ifdef WIN32
|
||||
#define strcasecmp _stricmp
|
||||
#define strncasecmp _strnicmp
|
||||
#endif
|
||||
|
||||
#include <rfb/util.h>
|
||||
#include <rfb/Configuration.h>
|
||||
#include <rfb/LogWriter.h>
|
||||
#include <rfb/Exception.h>
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
// Under Win32, we use these routines from several threads,
|
||||
// so we must provide suitable locking.
|
||||
#include <rfb/Threading.h>
|
||||
|
||||
static rfb::Mutex configLock;
|
||||
|
||||
#endif
|
||||
|
||||
#include <rdr/HexOutStream.h>
|
||||
#include <rdr/HexInStream.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
static LogWriter vlog("Config");
|
||||
|
||||
|
||||
// -=- Configuration
|
||||
|
||||
VoidParameter* Configuration::head = 0;
|
||||
|
||||
bool Configuration::setParam(const char* n, const char* v, bool immutable) {
|
||||
return setParam(n, strlen(n), v, immutable);
|
||||
}
|
||||
|
||||
bool Configuration::setParam(const char* name, int len,
|
||||
const char* val, bool immutable)
|
||||
{
|
||||
VoidParameter* current = head;
|
||||
while (current) {
|
||||
if ((int)strlen(current->getName()) == len &&
|
||||
strncasecmp(current->getName(), name, len) == 0)
|
||||
{
|
||||
bool b = current->setParam(val);
|
||||
if (b && immutable)
|
||||
current->setImmutable();
|
||||
return b;
|
||||
}
|
||||
current = current->_next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Configuration::setParam(const char* config, bool immutable) {
|
||||
bool hyphen = false;
|
||||
if (config[0] == '-') {
|
||||
hyphen = true;
|
||||
config++;
|
||||
if (config[0] == '-') config++; // allow gnu-style --<option>
|
||||
}
|
||||
const char* equal = strchr(config, '=');
|
||||
if (equal) {
|
||||
return setParam(config, equal-config, equal+1, immutable);
|
||||
} else if (hyphen) {
|
||||
VoidParameter* current = head;
|
||||
while (current) {
|
||||
if (strcasecmp(current->getName(), config) == 0) {
|
||||
bool b = current->setParam();
|
||||
if (b && immutable)
|
||||
current->setImmutable();
|
||||
return b;
|
||||
}
|
||||
current = current->_next;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
VoidParameter* Configuration::getParam(const char* param)
|
||||
{
|
||||
VoidParameter* current = head;
|
||||
while (current) {
|
||||
if (strcasecmp(current->getName(), param) == 0)
|
||||
return current;
|
||||
current = current->_next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Configuration::listParams(int width, int nameWidth) {
|
||||
VoidParameter* current = head;
|
||||
while (current) {
|
||||
char* def_str = current->getDefaultStr();
|
||||
const char* desc = current->getDescription();
|
||||
fprintf(stderr," %-*s -", nameWidth, current->getName());
|
||||
int column = strlen(current->getName());
|
||||
if (column < nameWidth) column = nameWidth;
|
||||
column += 4;
|
||||
while (true) {
|
||||
const char* s = strchr(desc, ' ');
|
||||
int wordLen;
|
||||
if (s) wordLen = s-desc;
|
||||
else wordLen = strlen(desc);
|
||||
|
||||
if (column + wordLen + 1 > width) {
|
||||
fprintf(stderr,"\n%*s",nameWidth+4,"");
|
||||
column = nameWidth+4;
|
||||
}
|
||||
fprintf(stderr," %.*s",wordLen,desc);
|
||||
column += wordLen + 1;
|
||||
desc += wordLen + 1;
|
||||
if (!s) break;
|
||||
}
|
||||
|
||||
if (def_str) {
|
||||
if (column + (int)strlen(def_str) + 11 > width)
|
||||
fprintf(stderr,"\n%*s",nameWidth+4,"");
|
||||
fprintf(stderr," (default=%s)\n",def_str);
|
||||
strFree(def_str);
|
||||
} else {
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
current = current->_next;
|
||||
}
|
||||
}
|
||||
|
||||
// -=- VoidParameter
|
||||
|
||||
VoidParameter::VoidParameter(const char* name_, const char* desc_)
|
||||
: immutable(false), name(name_), description(desc_) {
|
||||
_next = Configuration::head;
|
||||
Configuration::head = this;
|
||||
}
|
||||
|
||||
VoidParameter::~VoidParameter() {
|
||||
}
|
||||
|
||||
const char*
|
||||
VoidParameter::getName() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
const char*
|
||||
VoidParameter::getDescription() const {
|
||||
return description;
|
||||
}
|
||||
|
||||
bool VoidParameter::setParam() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VoidParameter::isBool() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
VoidParameter::setImmutable() {
|
||||
vlog.debug("set immutable %s", getName());
|
||||
immutable = true;
|
||||
}
|
||||
|
||||
// -=- AliasParameter
|
||||
|
||||
AliasParameter::AliasParameter(const char* name_, const char* desc_,
|
||||
VoidParameter* param_)
|
||||
: VoidParameter(name_, desc_), param(param_) {
|
||||
}
|
||||
|
||||
bool
|
||||
AliasParameter::setParam(const char* v) {
|
||||
return param->setParam(v);
|
||||
}
|
||||
|
||||
bool AliasParameter::setParam() {
|
||||
return param->setParam();
|
||||
}
|
||||
|
||||
char*
|
||||
AliasParameter::getDefaultStr() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* AliasParameter::getValueStr() const {
|
||||
return param->getValueStr();
|
||||
}
|
||||
|
||||
bool AliasParameter::isBool() const {
|
||||
return param->isBool();
|
||||
}
|
||||
|
||||
// -=- BoolParameter
|
||||
|
||||
BoolParameter::BoolParameter(const char* name_, const char* desc_, bool v)
|
||||
: VoidParameter(name_, desc_), value(v), def_value(v) {
|
||||
}
|
||||
|
||||
bool
|
||||
BoolParameter::setParam(const char* v) {
|
||||
if (immutable) return true;
|
||||
|
||||
if (*v == 0 || strcasecmp(v, "1") == 0 || strcasecmp(v, "on") == 0
|
||||
|| strcasecmp(v, "true") == 0 || strcasecmp(v, "yes") == 0)
|
||||
value = 1;
|
||||
else if (strcasecmp(v, "0") == 0 || strcasecmp(v, "off") == 0
|
||||
|| strcasecmp(v, "false") == 0 || strcasecmp(v, "no") == 0)
|
||||
value = 0;
|
||||
else {
|
||||
vlog.error("Bool parameter %s: invalid value '%s'", getName(), v);
|
||||
return false;
|
||||
}
|
||||
|
||||
vlog.debug("set %s(Bool) to %s(%d)", getName(), v, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BoolParameter::setParam() {
|
||||
setParam(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BoolParameter::setParam(bool b) {
|
||||
if (immutable) return;
|
||||
value = b;
|
||||
vlog.debug("set %s(Bool) to %d", getName(), value);
|
||||
}
|
||||
|
||||
char*
|
||||
BoolParameter::getDefaultStr() const {
|
||||
char* result = new char[8];
|
||||
sprintf(result, "%d", (int)def_value);
|
||||
return result;
|
||||
}
|
||||
|
||||
char* BoolParameter::getValueStr() const {
|
||||
char* result = new char[8];
|
||||
sprintf(result, "%d", (int)value);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool BoolParameter::isBool() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
BoolParameter::operator bool() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
// -=- IntParameter
|
||||
|
||||
IntParameter::IntParameter(const char* name_, const char* desc_, int v)
|
||||
: VoidParameter(name_, desc_), value(v), def_value(v) {
|
||||
}
|
||||
|
||||
bool
|
||||
IntParameter::setParam(const char* v) {
|
||||
if (immutable) return true;
|
||||
vlog.debug("set %s(Int) to %s", getName(), v);
|
||||
value = atoi(v);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IntParameter::setParam(int v) {
|
||||
if (immutable) return true;
|
||||
vlog.debug("set %s(Int) to %d", getName(), v);
|
||||
value = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
char*
|
||||
IntParameter::getDefaultStr() const {
|
||||
char* result = new char[16];
|
||||
sprintf(result, "%d", def_value);
|
||||
return result;
|
||||
}
|
||||
|
||||
char* IntParameter::getValueStr() const {
|
||||
char* result = new char[16];
|
||||
sprintf(result, "%d", value);
|
||||
return result;
|
||||
}
|
||||
|
||||
IntParameter::operator int() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
// -=- StringParameter
|
||||
|
||||
StringParameter::StringParameter(const char* name_, const char* desc_,
|
||||
const char* v)
|
||||
: VoidParameter(name_, desc_), value(strDup(v)), def_value(v)
|
||||
{
|
||||
if (!v) {
|
||||
fprintf(stderr,"Default value <null> for %s not allowed\n",name_);
|
||||
throw rfb::Exception("Default value <null> not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
StringParameter::~StringParameter() {
|
||||
strFree(value);
|
||||
}
|
||||
|
||||
bool StringParameter::setParam(const char* v) {
|
||||
#ifdef WIN32
|
||||
Lock l(configLock);
|
||||
#endif
|
||||
if (immutable) return true;
|
||||
if (!v)
|
||||
throw rfb::Exception("setParam(<null>) not allowed");
|
||||
vlog.debug("set %s(String) to %s", getName(), v);
|
||||
strFree(value);
|
||||
value = strDup(v);
|
||||
return value != 0;
|
||||
}
|
||||
|
||||
char* StringParameter::getDefaultStr() const {
|
||||
return strDup(def_value);
|
||||
}
|
||||
|
||||
char* StringParameter::getValueStr() const {
|
||||
#ifdef WIN32
|
||||
Lock l(configLock);
|
||||
#endif
|
||||
return strDup(value);
|
||||
}
|
||||
|
||||
// -=- BinaryParameter
|
||||
|
||||
BinaryParameter::BinaryParameter(const char* name_, const char* desc_, const void* v, int l)
|
||||
: VoidParameter(name_, desc_), value(0), length(0), def_value((char*)v), def_length(l) {
|
||||
if (l) {
|
||||
value = new char[l];
|
||||
length = l;
|
||||
memcpy(value, v, l);
|
||||
}
|
||||
}
|
||||
BinaryParameter::~BinaryParameter() {
|
||||
if (value)
|
||||
delete [] value;
|
||||
}
|
||||
|
||||
bool BinaryParameter::setParam(const char* v) {
|
||||
#ifdef WIN32
|
||||
Lock l(configLock);
|
||||
#endif
|
||||
if (immutable) return true;
|
||||
vlog.debug("set %s(Binary) to %s", getName(), v);
|
||||
return rdr::HexInStream::hexStrToBin(v, &value, &length);
|
||||
}
|
||||
|
||||
void BinaryParameter::setParam(const void* v, int len) {
|
||||
#ifdef WIN32
|
||||
Lock l(configLock);
|
||||
#endif
|
||||
if (immutable) return;
|
||||
vlog.debug("set %s(Binary)", getName());
|
||||
delete [] value; value = 0;
|
||||
if (len) {
|
||||
value = new char[len];
|
||||
length = len;
|
||||
memcpy(value, v, len);
|
||||
}
|
||||
}
|
||||
|
||||
char* BinaryParameter::getDefaultStr() const {
|
||||
return rdr::HexOutStream::binToHexStr(def_value, def_length);
|
||||
}
|
||||
|
||||
char* BinaryParameter::getValueStr() const {
|
||||
#ifdef WIN32
|
||||
Lock l(configLock);
|
||||
#endif
|
||||
return rdr::HexOutStream::binToHexStr(value, length);
|
||||
}
|
||||
|
||||
void BinaryParameter::getData(void** data_, int* length_) const {
|
||||
#ifdef WIN32
|
||||
Lock l(configLock);
|
||||
#endif
|
||||
if (length_) *length_ = length;
|
||||
if (data_) {
|
||||
*data_ = new char[length];
|
||||
memcpy(*data_, value, length);
|
||||
}
|
||||
}
|
167
rfb/Configuration.h
Normal file
167
rfb/Configuration.h
Normal file
|
@ -0,0 +1,167 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
// -=- Configuration.h
|
||||
//
|
||||
// This header defines a set of classes used to represent configuration
|
||||
// parameters of different types. Instances of the different parameter
|
||||
// types are associated with instances of the Configuration class, and
|
||||
// are each given a unique name. The Configuration class provides a
|
||||
// generic API through which parameters may be located by name and their
|
||||
// value set, thus removing the need to write platform-specific code.
|
||||
// Simply defining a new parameter and associating it with a Configuration
|
||||
// will allow it to be configured by the user.
|
||||
//
|
||||
// The Configuration class is used to allow multiple distinct configurations
|
||||
// to co-exist at the same time. A process serving several desktops, for
|
||||
// instance, can create a Configuration instance for each, to allow them
|
||||
// to be configured independently, from the command-line, registry, etc.
|
||||
|
||||
#ifndef __RFB_CONFIGURATION_H__
|
||||
#define __RFB_CONFIGURATION_H__
|
||||
|
||||
namespace rfb {
|
||||
class VoidParameter;
|
||||
|
||||
// -=- Configuration
|
||||
// Class used to access parameters.
|
||||
|
||||
class Configuration {
|
||||
public:
|
||||
// - Set named parameter to value
|
||||
static bool setParam(const char* param, const char* value, bool immutable=false);
|
||||
|
||||
// - Set parameter to value (separated by "=")
|
||||
static bool setParam(const char* config, bool immutable=false);
|
||||
|
||||
// - Set named parameter to value, with name truncated at len
|
||||
static bool setParam(const char* name, int len,
|
||||
const char* val, bool immutable);
|
||||
|
||||
// - Get named parameter
|
||||
static VoidParameter* getParam(const char* param);
|
||||
|
||||
static void listParams(int width=79, int nameWidth=10);
|
||||
|
||||
static VoidParameter* head;
|
||||
};
|
||||
|
||||
// -=- VoidParameter
|
||||
// Configuration parameter base-class.
|
||||
|
||||
class VoidParameter {
|
||||
public:
|
||||
VoidParameter(const char* name_, const char* desc_);
|
||||
virtual ~VoidParameter();
|
||||
const char* getName() const;
|
||||
const char* getDescription() const;
|
||||
|
||||
virtual bool setParam(const char* value) = 0;
|
||||
virtual bool setParam();
|
||||
virtual char* getDefaultStr() const = 0;
|
||||
virtual char* getValueStr() const = 0;
|
||||
virtual bool isBool() const;
|
||||
|
||||
virtual void setImmutable();
|
||||
|
||||
VoidParameter* _next;
|
||||
protected:
|
||||
bool immutable;
|
||||
const char* name;
|
||||
const char* description;
|
||||
};
|
||||
|
||||
class AliasParameter : public VoidParameter {
|
||||
public:
|
||||
AliasParameter(const char* name_, const char* desc_,VoidParameter* param_);
|
||||
virtual bool setParam(const char* value);
|
||||
virtual bool setParam();
|
||||
virtual char* getDefaultStr() const;
|
||||
virtual char* getValueStr() const;
|
||||
virtual bool isBool() const;
|
||||
private:
|
||||
VoidParameter* param;
|
||||
};
|
||||
|
||||
class BoolParameter : public VoidParameter {
|
||||
public:
|
||||
BoolParameter(const char* name_, const char* desc_, bool v);
|
||||
virtual bool setParam(const char* value);
|
||||
virtual bool setParam();
|
||||
virtual void setParam(bool b);
|
||||
virtual char* getDefaultStr() const;
|
||||
virtual char* getValueStr() const;
|
||||
virtual bool isBool() const;
|
||||
operator bool() const;
|
||||
protected:
|
||||
bool value;
|
||||
bool def_value;
|
||||
};
|
||||
|
||||
class IntParameter : public VoidParameter {
|
||||
public:
|
||||
IntParameter(const char* name_, const char* desc_, int v);
|
||||
virtual bool setParam(const char* value);
|
||||
virtual bool setParam(int v);
|
||||
virtual char* getDefaultStr() const;
|
||||
virtual char* getValueStr() const;
|
||||
operator int() const;
|
||||
protected:
|
||||
int value;
|
||||
int def_value;
|
||||
};
|
||||
|
||||
class StringParameter : public VoidParameter {
|
||||
public:
|
||||
// StringParameter contains a null-terminated string, which CANNOT
|
||||
// be Null, and so neither can the default value!
|
||||
StringParameter(const char* name_, const char* desc_, const char* v);
|
||||
virtual ~StringParameter();
|
||||
virtual bool setParam(const char* value);
|
||||
virtual char* getDefaultStr() const;
|
||||
virtual char* getValueStr() const;
|
||||
|
||||
// getData() returns a copy of the data - it must be delete[]d by the
|
||||
// caller.
|
||||
char* getData() const { return getValueStr(); }
|
||||
protected:
|
||||
char* value;
|
||||
const char* def_value;
|
||||
};
|
||||
|
||||
class BinaryParameter : public VoidParameter {
|
||||
public:
|
||||
BinaryParameter(const char* name_, const char* desc_, const void* v, int l);
|
||||
virtual ~BinaryParameter();
|
||||
virtual bool setParam(const char* value);
|
||||
virtual void setParam(const void* v, int l);
|
||||
virtual char* getDefaultStr() const;
|
||||
virtual char* getValueStr() const;
|
||||
|
||||
void getData(void** data, int* length) const;
|
||||
|
||||
protected:
|
||||
char* value;
|
||||
int length;
|
||||
char* def_value;
|
||||
int def_length;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif // __RFB_CONFIGURATION_H__
|
104
rfb/ConnParams.cxx
Normal file
104
rfb/ConnParams.cxx
Normal file
|
@ -0,0 +1,104 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#include <rdr/InStream.h>
|
||||
#include <rdr/OutStream.h>
|
||||
#include <rfb/Exception.h>
|
||||
#include <rfb/encodings.h>
|
||||
#include <rfb/Encoder.h>
|
||||
#include <rfb/ConnParams.h>
|
||||
#include <rfb/util.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
ConnParams::ConnParams()
|
||||
: majorVersion(0), minorVersion(0), width(0), height(0), useCopyRect(false),
|
||||
supportsLocalCursor(false), supportsDesktopResize(false),
|
||||
name_(0), nEncodings_(0), encodings_(0),
|
||||
currentEncoding_(encodingRaw), verStrPos(0)
|
||||
{
|
||||
setName("");
|
||||
}
|
||||
|
||||
ConnParams::~ConnParams()
|
||||
{
|
||||
delete [] name_;
|
||||
delete [] encodings_;
|
||||
}
|
||||
|
||||
bool ConnParams::readVersion(rdr::InStream* is, bool* done)
|
||||
{
|
||||
if (verStrPos >= 12) return false;
|
||||
while (is->checkNoWait(1) && verStrPos < 12) {
|
||||
verStr[verStrPos++] = is->readU8();
|
||||
}
|
||||
|
||||
if (verStrPos < 12) {
|
||||
*done = false;
|
||||
return true;
|
||||
}
|
||||
*done = true;
|
||||
verStr[12] = 0;
|
||||
return (sscanf(verStr, "RFB %03d.%03d\n", &majorVersion,&minorVersion) == 2);
|
||||
}
|
||||
|
||||
void ConnParams::writeVersion(rdr::OutStream* os)
|
||||
{
|
||||
char str[13];
|
||||
sprintf(str, "RFB %03d.%03d\n", majorVersion, minorVersion);
|
||||
os->writeBytes(str, 12);
|
||||
os->flush();
|
||||
}
|
||||
|
||||
void ConnParams::setPF(const PixelFormat& pf)
|
||||
{
|
||||
pf_ = pf;
|
||||
|
||||
if (pf.bpp != 8 && pf.bpp != 16 && pf.bpp != 32)
|
||||
throw Exception("setPF: not 8, 16 or 32 bpp?");
|
||||
}
|
||||
|
||||
void ConnParams::setName(const char* name)
|
||||
{
|
||||
delete [] name_;
|
||||
name_ = strDup(name);
|
||||
}
|
||||
|
||||
void ConnParams::setEncodings(int nEncodings, const rdr::U32* encodings)
|
||||
{
|
||||
if (nEncodings > nEncodings_) {
|
||||
delete [] encodings_;
|
||||
encodings_ = new rdr::U32[nEncodings];
|
||||
}
|
||||
nEncodings_ = nEncodings;
|
||||
useCopyRect = false;
|
||||
supportsLocalCursor = false;
|
||||
currentEncoding_ = encodingRaw;
|
||||
|
||||
for (int i = nEncodings-1; i >= 0; i--) {
|
||||
encodings_[i] = encodings[i];
|
||||
|
||||
if (encodings[i] == encodingCopyRect)
|
||||
useCopyRect = true;
|
||||
else if (encodings[i] == pseudoEncodingCursor)
|
||||
supportsLocalCursor = true;
|
||||
else if (encodings[i] == pseudoEncodingDesktopSize)
|
||||
supportsDesktopResize = true;
|
||||
else if (encodings[i] <= encodingMax && Encoder::supported(encodings[i]))
|
||||
currentEncoding_ = encodings[i];
|
||||
}
|
||||
}
|
86
rfb/ConnParams.h
Normal file
86
rfb/ConnParams.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
//
|
||||
// ConnParams - structure containing the connection parameters.
|
||||
//
|
||||
|
||||
#ifndef __RFB_CONNPARAMS_H__
|
||||
#define __RFB_CONNPARAMS_H__
|
||||
|
||||
#include <rdr/types.h>
|
||||
#include <rfb/PixelFormat.h>
|
||||
|
||||
namespace rdr { class InStream; }
|
||||
|
||||
namespace rfb {
|
||||
|
||||
class ConnParams {
|
||||
public:
|
||||
ConnParams();
|
||||
~ConnParams();
|
||||
|
||||
bool readVersion(rdr::InStream* is, bool* done);
|
||||
void writeVersion(rdr::OutStream* os);
|
||||
|
||||
int majorVersion;
|
||||
int minorVersion;
|
||||
|
||||
void setVersion(int major, int minor) {
|
||||
majorVersion = major; minorVersion = minor;
|
||||
}
|
||||
bool isVersion(int major, int minor) {
|
||||
return majorVersion == major && minorVersion == minor;
|
||||
}
|
||||
bool beforeVersion(int major, int minor) {
|
||||
return (majorVersion < major ||
|
||||
(majorVersion == major && minorVersion < minor));
|
||||
}
|
||||
bool afterVersion(int major, int minor) {
|
||||
return !beforeVersion(major,minor+1);
|
||||
}
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
const PixelFormat& pf() { return pf_; }
|
||||
void setPF(const PixelFormat& pf);
|
||||
|
||||
const char* name() { return name_; }
|
||||
void setName(const char* name);
|
||||
|
||||
rdr::U32 currentEncoding() { return currentEncoding_; }
|
||||
int nEncodings() { return nEncodings_; }
|
||||
const rdr::U32* encodings() { return encodings_; }
|
||||
void setEncodings(int nEncodings, const rdr::U32* encodings);
|
||||
bool useCopyRect;
|
||||
|
||||
bool supportsLocalCursor;
|
||||
bool supportsDesktopResize;
|
||||
|
||||
private:
|
||||
|
||||
PixelFormat pf_;
|
||||
char* name_;
|
||||
int nEncodings_;
|
||||
rdr::U32* encodings_;
|
||||
int currentEncoding_;
|
||||
char verStr[13];
|
||||
int verStrPos;
|
||||
};
|
||||
}
|
||||
#endif
|
178
rfb/Cursor.cxx
Normal file
178
rfb/Cursor.cxx
Normal file
|
@ -0,0 +1,178 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <rfb/Cursor.h>
|
||||
#include <rfb/LogWriter.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
static LogWriter vlog("Cursor");
|
||||
|
||||
void Cursor::setSize(int w, int h) {
|
||||
int oldMaskLen = maskLen();
|
||||
ManagedPixelBuffer::setSize(w, h);
|
||||
if (maskLen() > oldMaskLen) {
|
||||
delete [] mask.buf;
|
||||
mask.buf = new rdr::U8[maskLen()];
|
||||
}
|
||||
}
|
||||
|
||||
void Cursor::drawOutline(const Pixel& c)
|
||||
{
|
||||
Cursor outlined;
|
||||
|
||||
// Create a mirror of the existing cursor
|
||||
outlined.setPF(getPF());
|
||||
outlined.setSize(width(), height());
|
||||
outlined.hotspot = hotspot;
|
||||
|
||||
// Clear the mirror's background to the outline colour
|
||||
outlined.fillRect(getRect(), c);
|
||||
|
||||
// Blit the existing cursor, using its mask
|
||||
outlined.maskRect(getRect(), data, mask.buf);
|
||||
|
||||
// Now just adjust the mask to add the outline. The outline pixels
|
||||
// will already be the right colour. :)
|
||||
int maskBytesPerRow = (width() + 7) / 8;
|
||||
for (int y = 0; y < height(); y++) {
|
||||
for (int byte=0; byte<maskBytesPerRow; byte++) {
|
||||
rdr::U8 m8 = mask.buf[y*maskBytesPerRow + byte];
|
||||
|
||||
// Handle above & below outline
|
||||
if (y > 0) m8 |= mask.buf[(y-1)*maskBytesPerRow + byte];
|
||||
if (y < height()-1) m8 |= mask.buf[(y+1)*maskBytesPerRow + byte];
|
||||
|
||||
// Left outline
|
||||
m8 |= mask.buf[y*maskBytesPerRow + byte] << 1;
|
||||
if (byte < maskBytesPerRow-1)
|
||||
m8 |= (mask.buf[y*maskBytesPerRow + byte + 1] >> 7) & 1;
|
||||
|
||||
// Right outline
|
||||
m8 |= mask.buf[y*maskBytesPerRow + byte] >> 1;
|
||||
if (byte > 0)
|
||||
m8 |= (mask.buf[y*maskBytesPerRow + byte - 1] << 7) & 128;
|
||||
|
||||
outlined.mask.buf[y*maskBytesPerRow + byte] = m8;
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the existing cursor & mask with the new one
|
||||
delete [] data;
|
||||
delete [] mask.buf;
|
||||
data = outlined.data; outlined.data = 0;
|
||||
mask.buf = outlined.mask.buf; outlined.mask.buf = 0;
|
||||
}
|
||||
|
||||
rdr::U8* Cursor::getBitmap(Pixel* pix0, Pixel* pix1)
|
||||
{
|
||||
bool gotPix0 = false;
|
||||
bool gotPix1 = false;
|
||||
rdr::U8Array source(maskLen());
|
||||
memset(source.buf, 0, maskLen());
|
||||
|
||||
int maskBytesPerRow = (width() + 7) / 8;
|
||||
for (int y = 0; y < height(); y++) {
|
||||
for (int x = 0; x < width(); x++) {
|
||||
int byte = y * maskBytesPerRow + x / 8;
|
||||
int bit = 7 - x % 8;
|
||||
if (mask.buf[byte] & (1 << bit)) {
|
||||
Pixel pix=0;
|
||||
switch (getPF().bpp) {
|
||||
case 8: pix = ((rdr::U8*) data)[y * width() + x]; break;
|
||||
case 16: pix = ((rdr::U16*)data)[y * width() + x]; break;
|
||||
case 32: pix = ((rdr::U32*)data)[y * width() + x]; break;
|
||||
}
|
||||
if (!gotPix0 || pix == *pix0) {
|
||||
gotPix0 = true;
|
||||
*pix0 = pix;
|
||||
} else if (!gotPix1 || pix == *pix1) {
|
||||
gotPix1 = true;
|
||||
*pix1 = pix;
|
||||
source.buf[byte] |= (1 << bit);
|
||||
} else {
|
||||
// not a bitmap
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return source.takeBuf();
|
||||
}
|
||||
|
||||
// crop() determines the "busy" rectangle for the cursor - the minimum bounding
|
||||
// rectangle containing actual pixels. This isn't the most efficient algorithm
|
||||
// but it's short. For sanity, we make sure that the busy rectangle always
|
||||
// includes the hotspot (the hotspot is unsigned on the wire so otherwise it
|
||||
// would cause problems if it was above or left of the actual pixels)
|
||||
|
||||
void Cursor::crop()
|
||||
{
|
||||
Rect busy = getRect().intersect(Rect(hotspot.x, hotspot.y,
|
||||
hotspot.x+1, hotspot.y+1));
|
||||
int maskBytesPerRow = (width() + 7) / 8;
|
||||
int x, y;
|
||||
for (y = 0; y < height(); y++) {
|
||||
for (x = 0; x < width(); x++) {
|
||||
int byte = y * maskBytesPerRow + x / 8;
|
||||
int bit = 7 - x % 8;
|
||||
if (mask.buf[byte] & (1 << bit)) {
|
||||
if (x < busy.tl.x) busy.tl.x = x;
|
||||
if (x+1 > busy.br.x) busy.br.x = x+1;
|
||||
if (y < busy.tl.y) busy.tl.y = y;
|
||||
if (y+1 > busy.br.y) busy.br.y = y+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (width() == busy.width() && height() == busy.height()) return;
|
||||
|
||||
vlog.debug("cropping %dx%d to %dx%d", width(), height(),
|
||||
busy.width(), busy.height());
|
||||
|
||||
// Copy the pixel data
|
||||
int newDataLen = busy.area() * (getPF().bpp/8);
|
||||
rdr::U8* newData = new rdr::U8[newDataLen];
|
||||
getImage(newData, busy);
|
||||
|
||||
// Copy the mask
|
||||
int newMaskBytesPerRow = (busy.width()+7)/8;
|
||||
int newMaskLen = newMaskBytesPerRow * busy.height();
|
||||
rdr::U8* newMask = new rdr::U8[newMaskLen];
|
||||
memset(newMask, 0, newMaskLen);
|
||||
for (y = 0; y < busy.height(); y++) {
|
||||
int newByte, newBit;
|
||||
for (x = 0; x < busy.width(); x++) {
|
||||
int oldByte = (y+busy.tl.y) * maskBytesPerRow + (x+busy.tl.x) / 8;
|
||||
int oldBit = 7 - (x+busy.tl.x) % 8;
|
||||
newByte = y * newMaskBytesPerRow + x / 8;
|
||||
newBit = 7 - x % 8;
|
||||
if (mask.buf[oldByte] & (1 << oldBit))
|
||||
newMask[newByte] |= (1 << newBit);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the size and data to the new, cropped cursor.
|
||||
setSize(busy.width(), busy.height());
|
||||
hotspot = hotspot.subtract(busy.tl);
|
||||
delete [] data;
|
||||
delete [] mask.buf;
|
||||
datasize = newDataLen;
|
||||
data = newData;
|
||||
mask.buf = newMask;
|
||||
}
|
56
rfb/Cursor.h
Normal file
56
rfb/Cursor.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
//
|
||||
// Cursor - structure containing information describing
|
||||
// the current cursor shape
|
||||
//
|
||||
|
||||
#ifndef __RFB_CURSOR_H__
|
||||
#define __RFB_CURSOR_H__
|
||||
|
||||
#include <rfb/PixelBuffer.h>
|
||||
|
||||
namespace rfb {
|
||||
|
||||
class Cursor : public ManagedPixelBuffer {
|
||||
public:
|
||||
Cursor() {}
|
||||
rdr::U8Array mask;
|
||||
Point hotspot;
|
||||
|
||||
int maskLen() { return (width() + 7) / 8 * height(); }
|
||||
|
||||
// setSize() resizes the cursor. The contents of the data and mask are
|
||||
// undefined after this call.
|
||||
virtual void setSize(int w, int h);
|
||||
|
||||
// drawOutline() adds an outline to the cursor in the given colour.
|
||||
void drawOutline(const Pixel& c);
|
||||
|
||||
// getBitmap() tests whether the cursor is monochrome, and if so returns a
|
||||
// bitmap together with background and foreground colours. The size and
|
||||
// layout of the bitmap are the same as the mask.
|
||||
rdr::U8* getBitmap(Pixel* pix0, Pixel* pix1);
|
||||
|
||||
// crop() crops the cursor down to the smallest possible size, based on the
|
||||
// mask.
|
||||
void crop();
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
68
rfb/Decoder.cxx
Normal file
68
rfb/Decoder.cxx
Normal file
|
@ -0,0 +1,68 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <rfb/Exception.h>
|
||||
#include <rfb/Decoder.h>
|
||||
#include <rfb/RawDecoder.h>
|
||||
#include <rfb/RREDecoder.h>
|
||||
#include <rfb/HextileDecoder.h>
|
||||
#include <rfb/ZRLEDecoder.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
Decoder::~Decoder()
|
||||
{
|
||||
}
|
||||
|
||||
DecoderCreateFnType Decoder::createFns[encodingMax+1] = { 0 };
|
||||
|
||||
bool Decoder::supported(unsigned int encoding)
|
||||
{
|
||||
return encoding <= encodingMax && createFns[encoding];
|
||||
}
|
||||
|
||||
Decoder* Decoder::createDecoder(unsigned int encoding, CMsgReader* reader)
|
||||
{
|
||||
if (encoding <= encodingMax && createFns[encoding])
|
||||
return (*createFns[encoding])(reader);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Decoder::registerDecoder(unsigned int encoding,
|
||||
DecoderCreateFnType createFn)
|
||||
{
|
||||
if (encoding > encodingMax)
|
||||
throw Exception("Decoder::registerDecoder: encoding out of range");
|
||||
|
||||
if (createFns[encoding])
|
||||
fprintf(stderr,"Replacing existing decoder for encoding %s (%d)\n",
|
||||
encodingName(encoding), encoding);
|
||||
createFns[encoding] = createFn;
|
||||
}
|
||||
|
||||
int DecoderInit::count = 0;
|
||||
|
||||
DecoderInit::DecoderInit()
|
||||
{
|
||||
if (count++ != 0) return;
|
||||
|
||||
Decoder::registerDecoder(encodingRaw, RawDecoder::create);
|
||||
Decoder::registerDecoder(encodingRRE, RREDecoder::create);
|
||||
Decoder::registerDecoder(encodingHextile, HextileDecoder::create);
|
||||
Decoder::registerDecoder(encodingZRLE, ZRLEDecoder::create);
|
||||
}
|
52
rfb/Decoder.h
Normal file
52
rfb/Decoder.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef __RFB_DECODER_H__
|
||||
#define __RFB_DECODER_H__
|
||||
|
||||
#include <rfb/Rect.h>
|
||||
#include <rfb/encodings.h>
|
||||
|
||||
namespace rfb {
|
||||
class CMsgReader;
|
||||
class CMsgHandler;
|
||||
class Decoder;
|
||||
typedef Decoder* (*DecoderCreateFnType)(CMsgReader*);
|
||||
|
||||
class Decoder {
|
||||
public:
|
||||
virtual ~Decoder();
|
||||
virtual void readRect(const Rect& r, CMsgHandler* handler)=0;
|
||||
|
||||
static bool supported(unsigned int encoding);
|
||||
static Decoder* createDecoder(unsigned int encoding, CMsgReader* reader);
|
||||
static void registerDecoder(unsigned int encoding,
|
||||
DecoderCreateFnType createFn);
|
||||
private:
|
||||
static DecoderCreateFnType createFns[encodingMax+1];
|
||||
};
|
||||
|
||||
class DecoderInit {
|
||||
static int count;
|
||||
public:
|
||||
DecoderInit();
|
||||
};
|
||||
|
||||
static DecoderInit decoderInitObj;
|
||||
}
|
||||
|
||||
#endif
|
75
rfb/Encoder.cxx
Normal file
75
rfb/Encoder.cxx
Normal file
|
@ -0,0 +1,75 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <rfb/Exception.h>
|
||||
#include <rfb/Encoder.h>
|
||||
#include <rfb/RawEncoder.h>
|
||||
#include <rfb/RREEncoder.h>
|
||||
#include <rfb/HextileEncoder.h>
|
||||
#include <rfb/ZRLEEncoder.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
Encoder::~Encoder()
|
||||
{
|
||||
}
|
||||
|
||||
EncoderCreateFnType Encoder::createFns[encodingMax+1] = { 0 };
|
||||
|
||||
bool Encoder::supported(unsigned int encoding)
|
||||
{
|
||||
return encoding <= encodingMax && createFns[encoding];
|
||||
}
|
||||
|
||||
Encoder* Encoder::createEncoder(unsigned int encoding, SMsgWriter* writer)
|
||||
{
|
||||
if (encoding <= encodingMax && createFns[encoding])
|
||||
return (*createFns[encoding])(writer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Encoder::registerEncoder(unsigned int encoding,
|
||||
EncoderCreateFnType createFn)
|
||||
{
|
||||
if (encoding > encodingMax)
|
||||
throw Exception("Encoder::registerEncoder: encoding out of range");
|
||||
|
||||
if (createFns[encoding])
|
||||
fprintf(stderr,"Replacing existing encoder for encoding %s (%d)\n",
|
||||
encodingName(encoding), encoding);
|
||||
createFns[encoding] = createFn;
|
||||
}
|
||||
|
||||
void Encoder::unregisterEncoder(unsigned int encoding)
|
||||
{
|
||||
if (encoding > encodingMax)
|
||||
throw Exception("Encoder::unregisterEncoder: encoding out of range");
|
||||
createFns[encoding] = 0;
|
||||
}
|
||||
|
||||
int EncoderInit::count = 0;
|
||||
|
||||
EncoderInit::EncoderInit()
|
||||
{
|
||||
if (count++ != 0) return;
|
||||
|
||||
Encoder::registerEncoder(encodingRaw, RawEncoder::create);
|
||||
Encoder::registerEncoder(encodingRRE, RREEncoder::create);
|
||||
Encoder::registerEncoder(encodingHextile, HextileEncoder::create);
|
||||
Encoder::registerEncoder(encodingZRLE, ZRLEEncoder::create);
|
||||
}
|
57
rfb/Encoder.h
Normal file
57
rfb/Encoder.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef __RFB_ENCODER_H__
|
||||
#define __RFB_ENCODER_H__
|
||||
|
||||
#include <rfb/Rect.h>
|
||||
#include <rfb/encodings.h>
|
||||
|
||||
namespace rfb {
|
||||
class SMsgWriter;
|
||||
class Encoder;
|
||||
class ImageGetter;
|
||||
typedef Encoder* (*EncoderCreateFnType)(SMsgWriter*);
|
||||
|
||||
class Encoder {
|
||||
public:
|
||||
virtual ~Encoder();
|
||||
|
||||
// writeRect() tries to write the given rectangle. If it is unable to
|
||||
// write the whole rectangle it returns false and sets actual to the actual
|
||||
// rectangle which was updated.
|
||||
virtual bool writeRect(const Rect& r, ImageGetter* ig, Rect* actual)=0;
|
||||
|
||||
static bool supported(unsigned int encoding);
|
||||
static Encoder* createEncoder(unsigned int encoding, SMsgWriter* writer);
|
||||
static void registerEncoder(unsigned int encoding,
|
||||
EncoderCreateFnType createFn);
|
||||
static void unregisterEncoder(unsigned int encoding);
|
||||
private:
|
||||
static EncoderCreateFnType createFns[encodingMax+1];
|
||||
};
|
||||
|
||||
class EncoderInit {
|
||||
static int count;
|
||||
public:
|
||||
EncoderInit();
|
||||
};
|
||||
|
||||
static EncoderInit encoderInitObj;
|
||||
}
|
||||
|
||||
#endif
|
37
rfb/Exception.h
Normal file
37
rfb/Exception.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef __RFB_EXCEPTION_H__
|
||||
#define __RFB_EXCEPTION_H__
|
||||
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
namespace rfb {
|
||||
struct Exception : public rdr::Exception {
|
||||
Exception(const char* s=0, const char* e="rfb::Exception")
|
||||
: rdr::Exception(s,e) {}
|
||||
};
|
||||
struct AuthFailureException : public Exception {
|
||||
AuthFailureException(const char* s="Authentication failure")
|
||||
: Exception(s,"rfb::AuthFailureException") {}
|
||||
};
|
||||
struct ConnFailedException : public Exception {
|
||||
ConnFailedException(const char* s="Connection failed")
|
||||
: Exception(s,"rfb::ConnFailedException") {}
|
||||
};
|
||||
}
|
||||
#endif
|
386
rfb/HTTPServer.cxx
Normal file
386
rfb/HTTPServer.cxx
Normal file
|
@ -0,0 +1,386 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <rfb/HTTPServer.h>
|
||||
#include <rfb/LogWriter.h>
|
||||
#include <rfb/util.h>
|
||||
#include <rdr/MemOutStream.h>
|
||||
#include <time.h>
|
||||
|
||||
// *** Shouldn't really link against this - only for ClientWaitTimeMillis
|
||||
// and IdleTimeout
|
||||
#include <rfb/ServerCore.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
|
||||
using namespace rfb;
|
||||
using namespace rdr;
|
||||
|
||||
static LogWriter vlog("HTTPServer");
|
||||
|
||||
|
||||
//
|
||||
// -=- LineReader
|
||||
// Helper class which is repeatedly called until a line has been read
|
||||
// (lines end in \n or \r\n).
|
||||
// Returns true when line complete, and resets internal state so that
|
||||
// next read() call will start reading a new line.
|
||||
// Only one buffer is kept - process line before reading next line!
|
||||
//
|
||||
|
||||
class LineReader : public CharArray {
|
||||
public:
|
||||
LineReader(InStream& is_, int l)
|
||||
: CharArray(l), is(is_), pos(0), len(l), bufferOverrun(false) {}
|
||||
|
||||
// Returns true if line complete, false otherwise
|
||||
bool read() {
|
||||
while (is.checkNoWait(1)) {
|
||||
char c = is.readU8();
|
||||
|
||||
if (c == '\n') {
|
||||
if (pos && (buf[pos-1] == '\r'))
|
||||
pos--;
|
||||
bufferOverrun = false;
|
||||
buf[pos++] = 0;
|
||||
pos = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pos == (len-1)) {
|
||||
bufferOverrun = true;
|
||||
buf[pos] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
buf[pos++] = c;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool didBufferOverrun() const {return bufferOverrun;}
|
||||
protected:
|
||||
InStream& is;
|
||||
int pos, len;
|
||||
bool bufferOverrun;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// -=- HTTPServer::Session
|
||||
// Manages the internal state for an HTTP session.
|
||||
// processHTTP returns true when request has completed,
|
||||
// indicating that socket & session data can be deleted.
|
||||
//
|
||||
|
||||
class rfb::HTTPServer::Session {
|
||||
public:
|
||||
Session(network::Socket& s, rfb::HTTPServer& srv)
|
||||
: contentType(0), line(s.inStream(), 256), sock(s),
|
||||
server(srv), state(ReadRequestLine), lastActive(time(0)) {
|
||||
}
|
||||
~Session() {
|
||||
}
|
||||
|
||||
void writeResponse(int result, const char* text);
|
||||
bool writeResponse(int code);
|
||||
|
||||
bool processHTTP();
|
||||
|
||||
network::Socket* getSock() const {return &sock;}
|
||||
|
||||
int checkIdleTimeout();
|
||||
protected:
|
||||
CharArray uri;
|
||||
const char* contentType;
|
||||
LineReader line;
|
||||
network::Socket& sock;
|
||||
rfb::HTTPServer& server;
|
||||
enum {ReadRequestLine, ReadHeaders, WriteResponse} state;
|
||||
enum {GetRequest, HeadRequest} request;
|
||||
time_t lastActive;
|
||||
};
|
||||
|
||||
|
||||
// - Internal helper routines
|
||||
|
||||
void
|
||||
copyStream(InStream& is, OutStream& os) {
|
||||
try {
|
||||
while (1) {
|
||||
os.writeU8(is.readU8());
|
||||
}
|
||||
} catch (rdr::EndOfStream) {
|
||||
}
|
||||
}
|
||||
|
||||
void writeLine(OutStream& os, const char* text) {
|
||||
os.writeBytes(text, strlen(text));
|
||||
os.writeBytes("\r\n", 2);
|
||||
}
|
||||
|
||||
|
||||
// - Write an HTTP-compliant response to the client
|
||||
|
||||
void
|
||||
HTTPServer::Session::writeResponse(int result, const char* text) {
|
||||
char buffer[1024];
|
||||
if (strlen(text) > 512)
|
||||
throw new rdr::Exception("Internal error - HTTP response text too big");
|
||||
sprintf(buffer, "%s %d %s", "HTTP/1.1", result, text);
|
||||
OutStream& os=sock.outStream();
|
||||
writeLine(os, buffer);
|
||||
writeLine(os, "Server: RealVNC/4.0");
|
||||
writeLine(os, "Connection: close");
|
||||
os.writeBytes("Content-Type: ", 14);
|
||||
if (result == 200) {
|
||||
if (!contentType)
|
||||
contentType = guessContentType(uri.buf, "text/html");
|
||||
os.writeBytes(contentType, strlen(contentType));
|
||||
} else {
|
||||
os.writeBytes("text/html", 9);
|
||||
}
|
||||
os.writeBytes("\r\n", 2);
|
||||
writeLine(os, "");
|
||||
if (result != 200) {
|
||||
writeLine(os, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">");
|
||||
writeLine(os, "<HTML><HEAD>");
|
||||
sprintf(buffer, "<TITLE>%d %s</TITLE>", result, text);
|
||||
writeLine(os, buffer);
|
||||
writeLine(os, "</HEAD><BODY><H1>");
|
||||
writeLine(os, text);
|
||||
writeLine(os, "</H1></BODY></HTML>");
|
||||
sock.outStream().flush();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
HTTPServer::Session::writeResponse(int code) {
|
||||
switch (code) {
|
||||
case 200: writeResponse(code, "OK"); break;
|
||||
case 400: writeResponse(code, "Bad Request"); break;
|
||||
case 404: writeResponse(code, "Not Found"); break;
|
||||
case 501: writeResponse(code, "Not Implemented"); break;
|
||||
default: writeResponse(500, "Unknown Error"); break;
|
||||
};
|
||||
|
||||
// This return code is passed straight out of processHTTP().
|
||||
// true indicates that the request has been completely processed.
|
||||
return true;
|
||||
}
|
||||
|
||||
// - Main HTTP request processing routine
|
||||
|
||||
bool
|
||||
HTTPServer::Session::processHTTP() {
|
||||
lastActive = time(0);
|
||||
|
||||
while (sock.inStream().checkNoWait(1)) {
|
||||
|
||||
switch (state) {
|
||||
|
||||
// Reading the Request-Line
|
||||
case ReadRequestLine:
|
||||
|
||||
// Either read a line, or run out of incoming data
|
||||
if (!line.read())
|
||||
return false;
|
||||
|
||||
// We have read a line! Skip it if it's blank
|
||||
if (strlen(line.buf) == 0)
|
||||
continue;
|
||||
|
||||
// The line contains a request to process.
|
||||
{
|
||||
char method[16], path[128], version[16];
|
||||
int matched = sscanf(line.buf, "%15s%127s%15s",
|
||||
method, path, version);
|
||||
if (matched != 3)
|
||||
return writeResponse(400);
|
||||
|
||||
// Store the required "method"
|
||||
if (strcmp(method, "GET") == 0)
|
||||
request = GetRequest;
|
||||
else if (strcmp(method, "HEAD") == 0)
|
||||
request = HeadRequest;
|
||||
else
|
||||
return writeResponse(501);
|
||||
|
||||
// Store the URI to the "document"
|
||||
uri.buf = strDup(path);
|
||||
}
|
||||
|
||||
// Move on to reading the request headers
|
||||
state = ReadHeaders;
|
||||
break;
|
||||
|
||||
// Reading the request headers
|
||||
case ReadHeaders:
|
||||
|
||||
// Try to read a line
|
||||
if (!line.read())
|
||||
return false;
|
||||
|
||||
// Skip headers until we hit a blank line
|
||||
if (strlen(line.buf) != 0)
|
||||
continue;
|
||||
|
||||
// Headers ended - write the response!
|
||||
{
|
||||
CharArray address(sock.getPeerAddress());
|
||||
vlog.info("getting %s for %s", uri.buf, address.buf);
|
||||
InStream* data = server.getFile(uri.buf, &contentType);
|
||||
if (!data)
|
||||
return writeResponse(404);
|
||||
|
||||
try {
|
||||
writeResponse(200);
|
||||
if (request == GetRequest)
|
||||
copyStream(*data, sock.outStream());
|
||||
sock.outStream().flush();
|
||||
} catch (rdr::Exception& e) {
|
||||
vlog.error("error writing HTTP document:%s", e.str());
|
||||
}
|
||||
delete data;
|
||||
}
|
||||
|
||||
// The operation is complete!
|
||||
return true;
|
||||
|
||||
default:
|
||||
throw rdr::Exception("invalid HTTPSession state!");
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// Indicate that we're still processing the HTTP request.
|
||||
return false;
|
||||
}
|
||||
|
||||
int HTTPServer::Session::checkIdleTimeout() {
|
||||
time_t now = time(0);
|
||||
int timeout = (lastActive + rfb::Server::idleTimeout) - now;
|
||||
if (timeout > 0)
|
||||
return timeout * 1000;
|
||||
sock.shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -=- Constructor / destructor
|
||||
|
||||
HTTPServer::HTTPServer() {
|
||||
}
|
||||
|
||||
HTTPServer::~HTTPServer() {
|
||||
std::list<Session*>::iterator i;
|
||||
for (i=sessions.begin(); i!=sessions.end(); i++) {
|
||||
delete (*i)->getSock();
|
||||
delete *i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -=- SocketServer interface implementation
|
||||
|
||||
void
|
||||
HTTPServer::addClient(network::Socket* sock) {
|
||||
Session* s = new Session(*sock, *this);
|
||||
if (!s) {
|
||||
sock->shutdown();
|
||||
} else {
|
||||
sock->inStream().setTimeout(rfb::Server::clientWaitTimeMillis);
|
||||
sock->outStream().setTimeout(rfb::Server::clientWaitTimeMillis);
|
||||
sessions.push_front(s);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
HTTPServer::processSocketEvent(network::Socket* sock) {
|
||||
std::list<Session*>::iterator i;
|
||||
for (i=sessions.begin(); i!=sessions.end(); i++) {
|
||||
if ((*i)->getSock() == sock) {
|
||||
try {
|
||||
if ((*i)->processHTTP()) {
|
||||
vlog.info("completed HTTP request");
|
||||
delete *i;
|
||||
sessions.erase(i);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
} catch (rdr::Exception& e) {
|
||||
vlog.error("untrapped: %s", e.str());
|
||||
delete *i;
|
||||
sessions.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete sock;
|
||||
return false;
|
||||
}
|
||||
|
||||
void HTTPServer::getSockets(std::list<network::Socket*>* sockets)
|
||||
{
|
||||
sockets->clear();
|
||||
std::list<Session*>::iterator ci;
|
||||
for (ci = sessions.begin(); ci != sessions.end(); ci++) {
|
||||
sockets->push_back((*ci)->getSock());
|
||||
}
|
||||
}
|
||||
|
||||
int HTTPServer::checkTimeouts() {
|
||||
std::list<Session*>::iterator ci;
|
||||
int timeout = 0;
|
||||
for (ci = sessions.begin(); ci != sessions.end(); ci++) {
|
||||
soonestTimeout(&timeout, (*ci)->checkIdleTimeout());
|
||||
}
|
||||
return timeout;
|
||||
}
|
||||
|
||||
|
||||
// -=- Default getFile implementation
|
||||
|
||||
InStream*
|
||||
HTTPServer::getFile(const char* name, const char** contentType) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char*
|
||||
HTTPServer::guessContentType(const char* name, const char* defType) {
|
||||
CharArray file, ext;
|
||||
if (!strSplit(name, '.', &file.buf, &ext.buf))
|
||||
return defType;
|
||||
if (strcasecmp(ext.buf, "html") == 0 ||
|
||||
strcasecmp(ext.buf, "htm") == 0) {
|
||||
return "text/html";
|
||||
} else if (strcasecmp(ext.buf, "txt") == 0) {
|
||||
return "text/plain";
|
||||
} else if (strcasecmp(ext.buf, "gif") == 0) {
|
||||
return "image/gif";
|
||||
} else if (strcasecmp(ext.buf, "jpg") == 0) {
|
||||
return "image/jpeg";
|
||||
} else if (strcasecmp(ext.buf, "jar") == 0) {
|
||||
return "application/java-archive";
|
||||
} else if (strcasecmp(ext.buf, "exe") == 0) {
|
||||
return "application/octet-stream";
|
||||
}
|
||||
return defType;
|
||||
}
|
112
rfb/HTTPServer.h
Normal file
112
rfb/HTTPServer.h
Normal file
|
@ -0,0 +1,112 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
// -=- HTTPServer.h
|
||||
|
||||
// Single-threaded HTTP server implementation.
|
||||
// All I/O is handled by the processSocketEvent routine,
|
||||
// which is called by the main-loop of the VNC server whenever
|
||||
// there is an event on an HTTP socket.
|
||||
|
||||
#ifndef __RFB_HTTP_SERVER_H__
|
||||
#define __RFB_HTTP_SERVER_H__
|
||||
|
||||
#include <list>
|
||||
|
||||
#include <rdr/MemInStream.h>
|
||||
#include <rfb/UpdateTracker.h>
|
||||
#include <rfb/Configuration.h>
|
||||
#include <network/Socket.h>
|
||||
|
||||
namespace rfb {
|
||||
|
||||
class HTTPServer : public network::SocketServer {
|
||||
public:
|
||||
// -=- Constructors
|
||||
|
||||
// - HTTPServer(files)
|
||||
// Create an HTTP server which will use the getFile method
|
||||
// to satisfy HTTP GET requests.
|
||||
HTTPServer();
|
||||
|
||||
virtual ~HTTPServer();
|
||||
|
||||
// -=- Client management
|
||||
|
||||
// - Run a client connection on the supplied socket
|
||||
// This causes the server to perform HTTP protocol on the
|
||||
// supplied socket.
|
||||
// The socket will be closed if protocol initialisation
|
||||
// fails.
|
||||
virtual void addClient(network::Socket* sock);
|
||||
|
||||
// -=- Event processing methods
|
||||
|
||||
// - Process an input event on a particular Socket
|
||||
// The platform-specific side of the server implementation calls
|
||||
// this method whenever data arrives on one of the active
|
||||
// network sockets.
|
||||
// The method returns true if the Socket is still in use by the
|
||||
// server, or false if it is no longer required and should be
|
||||
// deleted.
|
||||
// NB: If false is returned then the Socket is deleted and must
|
||||
// not be accessed again!
|
||||
|
||||
virtual bool processSocketEvent(network::Socket* sock);
|
||||
|
||||
// - Check for socket timeouts
|
||||
virtual int checkTimeouts();
|
||||
|
||||
// getSockets() gets a list of sockets. This can be used to generate an
|
||||
// fd_set for calling select().
|
||||
|
||||
virtual void getSockets(std::list<network::Socket*>* sockets);
|
||||
|
||||
|
||||
// -=- File interface
|
||||
|
||||
// - getFile is passed the path portion of a URL and returns an
|
||||
// InStream containing the data to return. If the requested
|
||||
// file is available then the contentType should be set to the
|
||||
// type of the file, or left untouched if the file type is to
|
||||
// be determined automatically by HTTPServer.
|
||||
// If the file is not available then null is returned.
|
||||
// Overridden getFile functions should call the default version
|
||||
// if they do not recognise a path name.
|
||||
// NB: The caller assumes ownership of the returned InStream.
|
||||
// NB: The contentType is statically allocated by the getFile impl.
|
||||
// NB: contentType is *guaranteed* to be valid when getFile is called.
|
||||
|
||||
virtual rdr::InStream* getFile(const char* name, const char** contentType);
|
||||
|
||||
// - guessContentType is passed the name of a file and returns the
|
||||
// name of an HTTP content type, based on the file's extension. If
|
||||
// the extension isn't recognised then defType is returned. This can
|
||||
// be used from getFile to easily default to the supplied contentType,
|
||||
// or by passing zero in to determine whether a type is recognised or not.
|
||||
|
||||
static const char* guessContentType(const char* name, const char* defType);
|
||||
|
||||
protected:
|
||||
class Session;
|
||||
std::list<Session*> sessions;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
59
rfb/HextileDecoder.cxx
Normal file
59
rfb/HextileDecoder.cxx
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#include <rfb/CMsgReader.h>
|
||||
#include <rfb/CMsgHandler.h>
|
||||
#include <rfb/HextileDecoder.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
#define EXTRA_ARGS CMsgHandler* handler
|
||||
#define FILL_RECT(r, p) handler->fillRect(r, p)
|
||||
#define IMAGE_RECT(r, p) handler->imageRect(r, p)
|
||||
#define BPP 8
|
||||
#include <rfb/hextileDecode.h>
|
||||
#undef BPP
|
||||
#define BPP 16
|
||||
#include <rfb/hextileDecode.h>
|
||||
#undef BPP
|
||||
#define BPP 32
|
||||
#include <rfb/hextileDecode.h>
|
||||
#undef BPP
|
||||
|
||||
Decoder* HextileDecoder::create(CMsgReader* reader)
|
||||
{
|
||||
return new HextileDecoder(reader);
|
||||
}
|
||||
|
||||
HextileDecoder::HextileDecoder(CMsgReader* reader_) : reader(reader_)
|
||||
{
|
||||
}
|
||||
|
||||
HextileDecoder::~HextileDecoder()
|
||||
{
|
||||
}
|
||||
|
||||
void HextileDecoder::readRect(const Rect& r, CMsgHandler* handler)
|
||||
{
|
||||
rdr::InStream* is = reader->getInStream();
|
||||
rdr::U8* buf = reader->getImageBuf(16 * 16 * 4);
|
||||
switch (reader->bpp()) {
|
||||
case 8: hextileDecode8 (r, is, (rdr::U8*) buf, handler); break;
|
||||
case 16: hextileDecode16(r, is, (rdr::U16*)buf, handler); break;
|
||||
case 32: hextileDecode32(r, is, (rdr::U32*)buf, handler); break;
|
||||
}
|
||||
}
|
35
rfb/HextileDecoder.h
Normal file
35
rfb/HextileDecoder.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef __RFB_HEXTILEDECODER_H__
|
||||
#define __RFB_HEXTILEDECODER_H__
|
||||
|
||||
#include <rfb/Decoder.h>
|
||||
|
||||
namespace rfb {
|
||||
|
||||
class HextileDecoder : public Decoder {
|
||||
public:
|
||||
static Decoder* create(CMsgReader* reader);
|
||||
virtual void readRect(const Rect& r, CMsgHandler* handler);
|
||||
virtual ~HextileDecoder();
|
||||
private:
|
||||
HextileDecoder(CMsgReader* reader);
|
||||
CMsgReader* reader;
|
||||
};
|
||||
}
|
||||
#endif
|
61
rfb/HextileEncoder.cxx
Normal file
61
rfb/HextileEncoder.cxx
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#include <rfb/ImageGetter.h>
|
||||
#include <rfb/encodings.h>
|
||||
#include <rfb/SMsgWriter.h>
|
||||
#include <rfb/HextileEncoder.h>
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
#define EXTRA_ARGS ImageGetter* ig
|
||||
#define GET_IMAGE_INTO_BUF(r,buf) ig->getImage(buf, r);
|
||||
#define BPP 8
|
||||
#include <rfb/hextileEncode.h>
|
||||
#undef BPP
|
||||
#define BPP 16
|
||||
#include <rfb/hextileEncode.h>
|
||||
#undef BPP
|
||||
#define BPP 32
|
||||
#include <rfb/hextileEncode.h>
|
||||
#undef BPP
|
||||
|
||||
Encoder* HextileEncoder::create(SMsgWriter* writer)
|
||||
{
|
||||
return new HextileEncoder(writer);
|
||||
}
|
||||
|
||||
HextileEncoder::HextileEncoder(SMsgWriter* writer_) : writer(writer_)
|
||||
{
|
||||
}
|
||||
|
||||
HextileEncoder::~HextileEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
bool HextileEncoder::writeRect(const Rect& r, ImageGetter* ig, Rect* actual)
|
||||
{
|
||||
writer->startRect(r, encodingHextile);
|
||||
rdr::OutStream* os = writer->getOutStream();
|
||||
switch (writer->bpp()) {
|
||||
case 8: hextileEncode8(r, os, ig); break;
|
||||
case 16: hextileEncode16(r, os, ig); break;
|
||||
case 32: hextileEncode32(r, os, ig); break;
|
||||
}
|
||||
writer->endRect();
|
||||
return true;
|
||||
}
|
35
rfb/HextileEncoder.h
Normal file
35
rfb/HextileEncoder.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef __RFB_HEXTILEENCODER_H__
|
||||
#define __RFB_HEXTILEENCODER_H__
|
||||
|
||||
#include <rfb/Encoder.h>
|
||||
|
||||
namespace rfb {
|
||||
|
||||
class HextileEncoder : public Encoder {
|
||||
public:
|
||||
static Encoder* create(SMsgWriter* writer);
|
||||
virtual bool writeRect(const Rect& r, ImageGetter* ig, Rect* actual);
|
||||
virtual ~HextileEncoder();
|
||||
private:
|
||||
HextileEncoder(SMsgWriter* writer);
|
||||
SMsgWriter* writer;
|
||||
};
|
||||
}
|
||||
#endif
|
53
rfb/Hostname.h
Normal file
53
rfb/Hostname.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RFB_HOSTNAME_H__
|
||||
#define __RFB_HOSTNAME_H__
|
||||
|
||||
#include <rfb/util.h>
|
||||
|
||||
namespace rfb {
|
||||
|
||||
void getHostAndPort(const char* hi, char** host, int* port, int basePort=5900) {
|
||||
CharArray portBuf;
|
||||
CharArray hostBuf;
|
||||
if (hi[0] == '[') {
|
||||
if (!strSplit(&hi[1], ']', &hostBuf.buf, &portBuf.buf))
|
||||
throw rdr::Exception("unmatched [ in host");
|
||||
} else {
|
||||
portBuf.buf = strDup(hi);
|
||||
}
|
||||
if (strSplit(portBuf.buf, ':', hostBuf.buf ? 0 : &hostBuf.buf, &portBuf.buf)) {
|
||||
if (portBuf.buf[0] == ':') {
|
||||
*port = atoi(&portBuf.buf[1]);
|
||||
} else {
|
||||
*port = atoi(portBuf.buf);
|
||||
if (*port < 100) *port += basePort;
|
||||
}
|
||||
} else {
|
||||
*port = basePort;
|
||||
}
|
||||
if (strlen(hostBuf.buf) == 0)
|
||||
*host = strDup("localhost");
|
||||
else
|
||||
*host = hostBuf.takeBuf();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // __RFB_HOSTNAME_H__
|
30
rfb/ImageGetter.h
Normal file
30
rfb/ImageGetter.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef __RFB_IMAGEGETTER_H__
|
||||
#define __RFB_IMAGEGETTER_H__
|
||||
|
||||
#include <rfb/Rect.h>
|
||||
|
||||
namespace rfb {
|
||||
class ImageGetter {
|
||||
public:
|
||||
virtual void getImage(void* imageBuf,
|
||||
const Rect& r, int stride=0) = 0;
|
||||
};
|
||||
}
|
||||
#endif
|
137
rfb/LogWriter.cxx
Normal file
137
rfb/LogWriter.cxx
Normal file
|
@ -0,0 +1,137 @@
|
|||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
// -=- LogWriter.cxx - client-side logging interface
|
||||
|
||||
#include <string.h>
|
||||
#ifdef WIN32
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
#include <rfb/LogWriter.h>
|
||||
#include <rfb/Configuration.h>
|
||||
#include <rfb/util.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
rfb::LogParameter rfb::logParams;
|
||||
|
||||
using namespace rfb;
|
||||
|
||||
|
||||
LogWriter::LogWriter(const char* name) : m_name(name), m_level(0), m_log(0), m_next(log_writers) {
|
||||
log_writers = this;
|
||||
}
|
||||
|
||||
LogWriter::~LogWriter() {
|
||||
// *** Should remove this logger here!
|
||||
}
|
||||
|
||||
void LogWriter::setLog(Logger *logger) {
|
||||
m_log = logger;
|
||||
}
|
||||
|
||||
void LogWriter::setLevel(int level) {
|
||||
m_level = level;
|
||||
}
|
||||
|
||||
void
|
||||
LogWriter::listLogWriters(int width) {
|
||||
// *** make this respect width...
|
||||
LogWriter* current = log_writers;
|
||||
printf(" ");
|
||||
while (current) {
|
||||
printf("%s", current->m_name);
|
||||
current = current->m_next;
|
||||
if (current) printf(", ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
LogWriter* LogWriter::log_writers;
|
||||
|
||||
LogWriter*
|
||||
LogWriter::getLogWriter(const char* name) {
|
||||
LogWriter* current = log_writers;
|
||||
while (current) {
|
||||
if (strcasecmp(name, current->m_name) == 0) return current;
|
||||
current = current->m_next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool LogWriter::setLogParams(const char* params) {
|
||||
CharArray logwriterName, loggerName, logLevel;
|
||||
if (!strSplit(params, ':', &logwriterName.buf, &loggerName.buf) ||
|
||||
!strSplit(loggerName.buf, ':', &loggerName.buf, &logLevel.buf)) {
|
||||
fprintf(stderr,"failed to parse log params:%s\n",params);
|
||||
return false;
|
||||
}
|
||||
int level = atoi(logLevel.buf);
|
||||
Logger* logger = 0;
|
||||
if (strcmp("", loggerName.buf) != 0) {
|
||||
logger = Logger::getLogger(loggerName.buf);
|
||||
if (!logger) fprintf(stderr,"no logger found! %s\n",loggerName.buf);
|
||||
}
|
||||
if (strcmp("*", logwriterName.buf) == 0) {
|
||||
LogWriter* current = log_writers;
|
||||
while (current) {
|
||||
current->setLog(logger);
|
||||
current->setLevel(level);
|
||||
current = current->m_next;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
LogWriter* logwriter = getLogWriter(logwriterName.buf);
|
||||
if (!logwriter) {
|
||||
fprintf(stderr,"no logwriter found! %s\n",logwriterName.buf);
|
||||
} else {
|
||||
logwriter->setLog(logger);
|
||||
logwriter->setLevel(level);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
LogParameter::LogParameter()
|
||||
: StringParameter("Log",
|
||||
"Specifies which log output should be directed to "
|
||||
"which target logger, and the level of output to log. "
|
||||
"Format is <log>:<target>:<level>[, ...].",
|
||||
"") {
|
||||
}
|
||||
|
||||
bool LogParameter::setParam(const char* v) {
|
||||
if (immutable) return true;
|
||||
LogWriter::setLogParams("*::0");
|
||||
StringParameter::setParam(v);
|
||||
CharArray logParam;
|
||||
CharArray params(getData());
|
||||
while (params.buf) {
|
||||
strSplit(params.buf, ',', &logParam.buf, ¶ms.buf);
|
||||
if (strlen(logParam.buf) && !LogWriter::setLogParams(logParam.buf))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void LogParameter::setDefault(const char* d) {
|
||||
def_value = d;
|
||||
setParam(def_value);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue