git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2 3789f03b-4d11-0410-bbf8-ca57d06f2519tags/v0.0.90
@@ -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. |
@@ -0,0 +1,5 @@ | |||
SUBDIRS = @ZLIB_DIR@ rdr network Xregion rfb tx x0vncserver vncviewer \ | |||
vncconfig vncpasswd | |||
# followed by boilerplate.mk |
@@ -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/ |
@@ -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). |
@@ -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/ |
@@ -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/ |
@@ -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 |
@@ -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 |
@@ -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_ */ |
@@ -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 |
@@ -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 $< |
@@ -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 \ | |||
) |
@@ -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 |
@@ -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_)) |
@@ -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> |
@@ -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 |
@@ -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 | |||
@@ -0,0 +1,7 @@ | |||
MessageId=0x1 | |||
Severity=Success | |||
SymbolicName=VNC4LogMessage | |||
Language=English | |||
%1: %2 | |||
@@ -0,0 +1,2 @@ | |||
LANGUAGE 0x9,0x1 | |||
1 11 MSG00001.bin |
@@ -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 |
@@ -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__ |
@@ -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; | |||
} |
@@ -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__ |
@@ -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' |
@@ -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 |
@@ -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_)); | |||
} |
@@ -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 |
@@ -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; | |||
} |
@@ -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 |
@@ -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; | |||
} |
@@ -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 |
@@ -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 |
@@ -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; | |||
} |
@@ -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 |
@@ -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; | |||
} | |||
@@ -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 |
@@ -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; | |||
} |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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; | |||
} |
@@ -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 |
@@ -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 |
@@ -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; | |||
} |
@@ -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 |
@@ -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 |
@@ -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; | |||
} |
@@ -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 |
@@ -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; | |||
} |
@@ -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 |
@@ -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' |
@@ -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 |
@@ -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 |
@@ -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); | |||
} | |||
} |
@@ -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 | |||
@@ -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"); | |||
} |
@@ -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 |
@@ -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) | |||
{ | |||
} | |||
@@ -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 |
@@ -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; | |||
} |
@@ -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 |
@@ -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(); | |||
} |
@@ -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 |
@@ -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_; | |||
} |
@@ -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 |
@@ -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(); | |||
} |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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; | |||
} |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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); | |||
} | |||
} |
@@ -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 |
@@ -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); | |||
} | |||
} |
@@ -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__ |
@@ -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]; | |||
} | |||
} |
@@ -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 |
@@ -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; | |||
} |
@@ -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 |
@@ -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); | |||
} |
@@ -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 |
@@ -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); | |||
} |
@@ -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 |
@@ -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 |
@@ -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; | |||
} |
@@ -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 | |||
@@ -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; | |||
} | |||
} |
@@ -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 |
@@ -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; | |||
} |
@@ -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 |
@@ -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__ |
@@ -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 |