removed experimental vnc
This commit is contained in:
parent
7f6eca9eb4
commit
79a1815206
|
@ -21,7 +21,3 @@ if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "IRIX")
|
||||||
endif()
|
endif()
|
||||||
add_subdirectory(plugin)
|
add_subdirectory(plugin)
|
||||||
add_subdirectory(micro)
|
add_subdirectory(micro)
|
||||||
|
|
||||||
if (VNC_SUPPORT)
|
|
||||||
add_subdirectory(vnc)
|
|
||||||
endif()
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
# synergy -- mouse and keyboard sharing utility
|
|
||||||
# Copyright (C) 2012 Nick Bolton
|
|
||||||
#
|
|
||||||
# This package is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# found in the file COPYING that should have accompanied this file.
|
|
||||||
#
|
|
||||||
# This package 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
if (WIN32)
|
|
||||||
add_subdirectory(common)
|
|
||||||
add_subdirectory(win)
|
|
||||||
elseif (UNIX)
|
|
||||||
#add_subdirectory(unix)
|
|
||||||
endif()
|
|
||||||
|
|
|
@ -1,340 +0,0 @@
|
||||||
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.
|
|
|
@ -1,20 +0,0 @@
|
||||||
# synergy -- mouse and keyboard sharing utility
|
|
||||||
# Copyright (C) 2012 Nick Bolton
|
|
||||||
#
|
|
||||||
# This package is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# found in the file COPYING that should have accompanied this file.
|
|
||||||
#
|
|
||||||
# This package 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
add_subdirectory(rfb)
|
|
||||||
add_subdirectory(network)
|
|
||||||
add_subdirectory(rdr)
|
|
||||||
add_subdirectory(Xregion)
|
|
||||||
add_subdirectory(zlib)
|
|
|
@ -1,4 +0,0 @@
|
||||||
|
|
||||||
SUBDIRS = @ZLIB_DIR@ rdr network Xregion rfb
|
|
||||||
|
|
||||||
# followed by boilerplate.mk
|
|
|
@ -1,36 +0,0 @@
|
||||||
# synergy -- mouse and keyboard sharing utility
|
|
||||||
# Copyright (C) 2012 Nick Bolton
|
|
||||||
#
|
|
||||||
# This package is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# found in the file COPYING that should have accompanied this file.
|
|
||||||
#
|
|
||||||
# This package 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
set(inc
|
|
||||||
region.h
|
|
||||||
|
|
||||||
Xregion.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(src
|
|
||||||
Region.c
|
|
||||||
)
|
|
||||||
|
|
||||||
if (WIN32)
|
|
||||||
list(APPEND src ${inc})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(inc
|
|
||||||
..
|
|
||||||
../../win
|
|
||||||
)
|
|
||||||
|
|
||||||
include_directories(${inc})
|
|
||||||
add_library(vnc_Xregion STATIC ${src})
|
|
|
@ -1,15 +0,0 @@
|
||||||
|
|
||||||
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
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,220 +0,0 @@
|
||||||
/* $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_ */
|
|
|
@ -1,190 +0,0 @@
|
||||||
/* $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
|
|
|
@ -1,35 +0,0 @@
|
||||||
|
|
||||||
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 $<
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,99 +0,0 @@
|
||||||
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)
|
|
||||||
|
|
||||||
if test "$SOLARIS" = yes; then
|
|
||||||
dnl Solaris 2.5 lacks vsnprintf, so use our own version & support 2.5
|
|
||||||
VSNPRINTF_DEFINE=
|
|
||||||
else
|
|
||||||
AC_CHECK_FUNC(vsnprintf,VSNPRINTF_DEFINE='-DHAVE_VSNPRINTF',VSNPRINTF_DEFINE=)
|
|
||||||
fi
|
|
||||||
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 \
|
|
||||||
)
|
|
|
@ -1,76 +0,0 @@
|
||||||
#
|
|
||||||
# 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
|
|
|
@ -1,13 +0,0 @@
|
||||||
<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>
|
|
Binary file not shown.
Before Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
|
@ -1,35 +0,0 @@
|
||||||
# synergy -- mouse and keyboard sharing utility
|
|
||||||
# Copyright (C) 2012 Nick Bolton
|
|
||||||
#
|
|
||||||
# This package is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# found in the file COPYING that should have accompanied this file.
|
|
||||||
#
|
|
||||||
# This package 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
set(inc
|
|
||||||
Socket.h
|
|
||||||
TcpSocket.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(src
|
|
||||||
${inc}
|
|
||||||
TcpSocket.cxx
|
|
||||||
)
|
|
||||||
|
|
||||||
if (WIN32)
|
|
||||||
list(APPEND src ${inc})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(inc
|
|
||||||
..
|
|
||||||
)
|
|
||||||
|
|
||||||
include_directories(${inc})
|
|
||||||
add_library(vnc_network STATIC ${src})
|
|
|
@ -1,17 +0,0 @@
|
||||||
|
|
||||||
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
|
|
|
@ -1,147 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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 <limits.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)),
|
|
||||||
ownStreams(true), isShutdown_(false),
|
|
||||||
queryConnection(false) {}
|
|
||||||
virtual ~Socket() {
|
|
||||||
if (ownStreams) {
|
|
||||||
delete instream;
|
|
||||||
delete outstream;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rdr::FdInStream &inStream() {return *instream;}
|
|
||||||
rdr::FdOutStream &outStream() {return *outstream;}
|
|
||||||
int getFd() {return outstream->getFd();}
|
|
||||||
|
|
||||||
// if shutdown() is overridden then the override MUST call on to here
|
|
||||||
virtual void shutdown() {isShutdown_ = true;}
|
|
||||||
bool isShutdown() const {return isShutdown_;}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
// Was there a "?" in the ConnectionFilter used to accept this Socket?
|
|
||||||
void setRequiresQuery() {queryConnection = true;}
|
|
||||||
bool requiresQuery() const {return queryConnection;}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Socket() : instream(0), outstream(0), ownStreams(false),
|
|
||||||
isShutdown_(false), queryConnection(false) {}
|
|
||||||
Socket(rdr::FdInStream* i, rdr::FdOutStream* o, bool own)
|
|
||||||
: instream(i), outstream(o), ownStreams(own),
|
|
||||||
isShutdown_(false), queryConnection(false) {}
|
|
||||||
rdr::FdInStream* instream;
|
|
||||||
rdr::FdOutStream* outstream;
|
|
||||||
bool ownStreams;
|
|
||||||
bool isShutdown_;
|
|
||||||
bool queryConnection;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConnectionFilter {
|
|
||||||
public:
|
|
||||||
virtual bool verifyConnection(Socket* s) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
// setFilter() applies the specified filter to all new connections
|
|
||||||
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() {}
|
|
||||||
|
|
||||||
// addSocket() tells the server to serve the Socket. The caller
|
|
||||||
// retains ownership of the Socket - the only way for the server
|
|
||||||
// to discard a Socket is by calling shutdown() on it.
|
|
||||||
// outgoing is set to true if the socket was created by connecting out
|
|
||||||
// to another host, or false if the socket was created by accept()ing
|
|
||||||
// an incoming connection.
|
|
||||||
virtual void addSocket(network::Socket* sock, bool outgoing=false) = 0;
|
|
||||||
|
|
||||||
// removeSocket() tells the server to stop serving the Socket. The
|
|
||||||
// caller retains ownership of the Socket - the server must NOT
|
|
||||||
// delete the Socket! This call is used mainly to cause per-Socket
|
|
||||||
// resources to be freed.
|
|
||||||
virtual void removeSocket(network::Socket* sock) = 0;
|
|
||||||
|
|
||||||
// processSocketEvent() tells the server there is a Socket read event.
|
|
||||||
// The implementation can indicate that the Socket is no longer active
|
|
||||||
// by calling shutdown() on it. The caller will then call removeSocket()
|
|
||||||
// soon after processSocketEvent returns, to allow any pre-Socket
|
|
||||||
// resources to be tidied up.
|
|
||||||
virtual void 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;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __NETWORK_SOCKET_H__
|
|
|
@ -1,467 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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");
|
|
||||||
|
|
||||||
|
|
||||||
// -=- Socket initialisation
|
|
||||||
static bool socketsInitialised = false;
|
|
||||||
static void initSockets() {
|
|
||||||
if (socketsInitialised)
|
|
||||||
return;
|
|
||||||
#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
|
|
||||||
socketsInitialised = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -=- 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
|
|
||||||
initSockets();
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable Nagle's algorithm, to reduce latency
|
|
||||||
enableNagles(sock, false);
|
|
||||||
|
|
||||||
// Create the input and output streams
|
|
||||||
instream = new FdInStream(sock);
|
|
||||||
outstream = new FdOutStream(sock);
|
|
||||||
ownStreams = 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()
|
|
||||||
{
|
|
||||||
Socket::shutdown();
|
|
||||||
::shutdown(getFd(), 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TcpSocket::enableNagles(int sock, bool enable) {
|
|
||||||
int one = enable ? 0 : 1;
|
|
||||||
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
|
|
||||||
(char *)&one, sizeof(one)) < 0) {
|
|
||||||
int e = errorNumber;
|
|
||||||
vlog.error("unable to setsockopt TCP_NODELAY: %d", e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
initSockets();
|
|
||||||
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(fd, 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, to reduce latency
|
|
||||||
TcpSocket::enableNagles(new_sock, false);
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
s->setRequiresQuery();
|
|
||||||
return true;
|
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,99 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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 bool enableNagles(int sock, bool enable);
|
|
||||||
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__
|
|
|
@ -1,58 +0,0 @@
|
||||||
# synergy -- mouse and keyboard sharing utility
|
|
||||||
# Copyright (C) 2012 Nick Bolton
|
|
||||||
#
|
|
||||||
# This package is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# found in the file COPYING that should have accompanied this file.
|
|
||||||
#
|
|
||||||
# This package 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
set(inc
|
|
||||||
Exception.h
|
|
||||||
FdInStream.h
|
|
||||||
FdOutStream.h
|
|
||||||
FixedMemOutStream.h
|
|
||||||
HexInStream.h
|
|
||||||
HexOutStream.h
|
|
||||||
InStream.h
|
|
||||||
MemInStream.h
|
|
||||||
MemOutStream.h
|
|
||||||
OutStream.h
|
|
||||||
RandomStream.h
|
|
||||||
SubstitutingInStream.h
|
|
||||||
types.h
|
|
||||||
ZlibInStream.h
|
|
||||||
ZlibOutStream.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(src
|
|
||||||
Exception.cxx
|
|
||||||
FdInStream.cxx
|
|
||||||
FdOutStream.cxx
|
|
||||||
HexInStream.cxx
|
|
||||||
HexOutStream.cxx
|
|
||||||
InStream.cxx
|
|
||||||
RandomStream.cxx
|
|
||||||
ZlibInStream.cxx
|
|
||||||
ZlibOutStream.cxx
|
|
||||||
)
|
|
||||||
|
|
||||||
if (WIN32)
|
|
||||||
list(APPEND src ${inc})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(inc
|
|
||||||
..
|
|
||||||
../zlib
|
|
||||||
)
|
|
||||||
|
|
||||||
include_directories(${inc})
|
|
||||||
add_library(vnc_rdr STATIC ${src})
|
|
||||||
target_link_libraries(vnc_rdr
|
|
||||||
vnc_zlib)
|
|
|
@ -1,73 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
||||||
#include <tchar.h>
|
|
||||||
#include <windows.h>
|
|
||||||
//#include <winsock2.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace rdr;
|
|
||||||
|
|
||||||
SystemException::SystemException(const char* s, int err_)
|
|
||||||
: Exception(s), 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
|
|
||||||
char* currStr = str_+strlen(str_);
|
|
||||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
0, err, 0, currStr, len-1-strlen(str_), 0);
|
|
||||||
#endif
|
|
||||||
int l = strlen(str_);
|
|
||||||
if ((l >= 2) && (str_[l-2] == '\r') && (str_[l-1] == '\n'))
|
|
||||||
str_[l-2] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
strncat(str_, strerror(err), len-1-strlen(str_));
|
|
||||||
#endif
|
|
||||||
strncat(str_, " (", len-1-strlen(str_));
|
|
||||||
char buf[20];
|
|
||||||
#ifdef WIN32
|
|
||||||
if (err < 0)
|
|
||||||
sprintf(buf, "%x", err);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
sprintf(buf,"%d",err);
|
|
||||||
strncat(str_, buf, len-1-strlen(str_));
|
|
||||||
strncat(str_, ")", len-1-strlen(str_));
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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];
|
|
||||||
Exception(const char* s=0) {
|
|
||||||
str_[0] = 0;
|
|
||||||
if (s)
|
|
||||||
strncat(str_, s, len-1);
|
|
||||||
else
|
|
||||||
strcat(str_, "Exception");
|
|
||||||
}
|
|
||||||
virtual const char* str() const { return str_; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SystemException : public Exception {
|
|
||||||
int err;
|
|
||||||
SystemException(const char* s, int err_);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TimedOut : public Exception {
|
|
||||||
TimedOut(const char* s="Timed out") : Exception(s) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EndOfStream : public Exception {
|
|
||||||
EndOfStream(const char* s="End of stream") : Exception(s) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FrameException : public Exception {
|
|
||||||
FrameException(const char* s="Frame exception") : Exception(s) {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,283 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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>
|
|
||||||
|
|
||||||
#pragma warning(disable: 4244)
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,174 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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;
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,52 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,117 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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;
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,110 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,35 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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;
|
|
||||||
}
|
|
|
@ -1,153 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,19 +0,0 @@
|
||||||
|
|
||||||
SRCS = Exception.cxx FdInStream.cxx FdOutStream.cxx InStream.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
|
|
|
@ -1,63 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,83 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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 clearAndZero() { memset(start, 0, ptr-start); clear(); }
|
|
||||||
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
|
|
|
@ -1,152 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,130 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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()
|
|
||||||
#ifndef RFB_HAVE_WINCRYPT
|
|
||||||
#pragma message(" NOTE: Not building WinCrypt-based RandomStream")
|
|
||||||
#endif
|
|
||||||
#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 RFB_HAVE_WINCRYPT
|
|
||||||
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
|
|
||||||
#ifndef WIN32
|
|
||||||
fp = fopen("/dev/urandom", "r");
|
|
||||||
if (!fp)
|
|
||||||
fp = fopen("/dev/random", "r");
|
|
||||||
if (!fp) {
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
#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 RFB_HAVE_WINCRYPT
|
|
||||||
if (provider)
|
|
||||||
CryptReleaseContext(provider, 0);
|
|
||||||
#endif
|
|
||||||
#ifndef WIN32
|
|
||||||
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 RFB_HAVE_WINCRYPT
|
|
||||||
if (provider) {
|
|
||||||
if (!CryptGenRandom(provider, length, (U8*)end))
|
|
||||||
throw rdr::SystemException("unable to CryptGenRandom", GetLastError());
|
|
||||||
end += length;
|
|
||||||
} else {
|
|
||||||
#else
|
|
||||||
#ifndef WIN32
|
|
||||||
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;
|
|
||||||
} else {
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
||||||
#include <windows.h>
|
|
||||||
#include <wincrypt.h>
|
|
||||||
#ifdef WINCRYPT32API
|
|
||||||
#define RFB_HAVE_WINCRYPT
|
|
||||||
#endif
|
|
||||||
#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 RFB_HAVE_WINCRYPT
|
|
||||||
HCRYPTPROV provider;
|
|
||||||
#endif
|
|
||||||
#ifndef WIN32
|
|
||||||
FILE* fp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end of namespace rdr
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,102 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,125 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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;
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,140 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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;
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,66 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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;
|
|
||||||
};
|
|
||||||
|
|
||||||
class U32Array {
|
|
||||||
public:
|
|
||||||
U32Array() : buf(0) {}
|
|
||||||
U32Array(U32* a) : buf(a) {} // note: assumes ownership
|
|
||||||
U32Array(int len) : buf(new U32[len]) {}
|
|
||||||
~U32Array() { delete [] buf; }
|
|
||||||
U32* takeBuf() { U32* tmp = buf; buf = 0; return tmp; }
|
|
||||||
U32* buf;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end of namespace rdr
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,86 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,91 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
||||||
|
|
|
@ -1,276 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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::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");
|
|
||||||
if (security->processMsg(this)) {
|
|
||||||
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();
|
|
||||||
return;
|
|
||||||
case secResultFailed:
|
|
||||||
vlog.debug("auth failed");
|
|
||||||
break;
|
|
||||||
case secResultTooMany:
|
|
||||||
vlog.debug("auth failed - too many tries");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw Exception("Unknown security result from server");
|
|
||||||
}
|
|
||||||
CharArray reason;
|
|
||||||
if (cp.beforeVersion(3,8))
|
|
||||||
reason.buf = strDup("Authentication failure");
|
|
||||||
else
|
|
||||||
reason.buf = is->readString();
|
|
||||||
state_ = RFBSTATE_INVALID;
|
|
||||||
throw AuthFailureException(reason.buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CConnection::processInitMsg()
|
|
||||||
{
|
|
||||||
vlog.debug("reading server initialisation");
|
|
||||||
reader_->readServerInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
|
@ -1,183 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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();
|
|
||||||
|
|
||||||
// Methods to initialise the connection
|
|
||||||
|
|
||||||
// setServerName() is used to provide a unique(ish) name for the server to
|
|
||||||
// which we are connected. This might be the result of getPeerEndpoint on
|
|
||||||
// a TcpSocket, for example, or a host specified by DNS name & port.
|
|
||||||
// The serverName is used when verifying the Identity of a host (see RA2).
|
|
||||||
void setServerName(const char* name_) { serverName.replaceBuf(strDup(name_)); }
|
|
||||||
|
|
||||||
// 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; }
|
|
||||||
|
|
||||||
// Access method used by SSecurity implementations that can verify servers'
|
|
||||||
// Identities, to determine the unique(ish) name of the server.
|
|
||||||
const char* getServerName() const { return 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
|
|
|
@ -1,162 +0,0 @@
|
||||||
# synergy -- mouse and keyboard sharing utility
|
|
||||||
# Copyright (C) 2012 Nick Bolton
|
|
||||||
#
|
|
||||||
# This package is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# found in the file COPYING that should have accompanied this file.
|
|
||||||
#
|
|
||||||
# This package 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
set(inc
|
|
||||||
Blacklist.h
|
|
||||||
CConnection.h
|
|
||||||
CMsgHandler.h
|
|
||||||
CMsgReader.h
|
|
||||||
CMsgReaderV3.h
|
|
||||||
CMsgWriter.h
|
|
||||||
CMsgWriterV3.h
|
|
||||||
ColourCube.h
|
|
||||||
ColourMap.h
|
|
||||||
ComparingUpdateTracker.h
|
|
||||||
Configuration.h
|
|
||||||
ConnParams.h
|
|
||||||
CSecurity.h
|
|
||||||
CSecurityNone.h
|
|
||||||
CSecurityVncAuth.h
|
|
||||||
Cursor.h
|
|
||||||
d3des.h
|
|
||||||
Decoder.h
|
|
||||||
Encoder.h
|
|
||||||
encodings.h
|
|
||||||
Exception.h
|
|
||||||
hextileConstants.h
|
|
||||||
hextileDecode.h
|
|
||||||
HextileDecoder.h
|
|
||||||
hextileEncode.h
|
|
||||||
HextileEncoder.h
|
|
||||||
Hostname.h
|
|
||||||
HTTPServer.h
|
|
||||||
ImageGetter.h
|
|
||||||
InputHandler.h
|
|
||||||
KeyRemapper.h
|
|
||||||
keysymdef.h
|
|
||||||
Logger.h
|
|
||||||
Logger_file.h
|
|
||||||
Logger_stdio.h
|
|
||||||
LogWriter.h
|
|
||||||
msgTypes.h
|
|
||||||
Password.h
|
|
||||||
Pixel.h
|
|
||||||
PixelBuffer.h
|
|
||||||
PixelFormat.h
|
|
||||||
RawDecoder.h
|
|
||||||
RawEncoder.h
|
|
||||||
Rect.h
|
|
||||||
Region.h
|
|
||||||
rreDecode.h
|
|
||||||
RREDecoder.h
|
|
||||||
rreEncode.h
|
|
||||||
RREEncoder.h
|
|
||||||
SConnection.h
|
|
||||||
SDesktop.h
|
|
||||||
secTypes.h
|
|
||||||
ServerCore.h
|
|
||||||
SMsgHandler.h
|
|
||||||
SMsgReader.h
|
|
||||||
SMsgReaderV3.h
|
|
||||||
SMsgWriter.h
|
|
||||||
SMsgWriterV3.h
|
|
||||||
SSecurity.h
|
|
||||||
SSecurityFactoryStandard.h
|
|
||||||
SSecurityNone.h
|
|
||||||
SSecurityVncAuth.h
|
|
||||||
Threading.h
|
|
||||||
Timer.h
|
|
||||||
TransImageGetter.h
|
|
||||||
transInitTempl.h
|
|
||||||
transTempl.h
|
|
||||||
TrueColourMap.h
|
|
||||||
UpdateTracker.h
|
|
||||||
UserPasswdGetter.h
|
|
||||||
util.h
|
|
||||||
VNCSConnectionST.h
|
|
||||||
VNCServer.h
|
|
||||||
VNCServerST.h
|
|
||||||
zrleDecode.h
|
|
||||||
ZRLEDecoder.h
|
|
||||||
zrleEncode.h
|
|
||||||
ZRLEEncoder.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(src
|
|
||||||
d3des.c
|
|
||||||
Blacklist.cxx
|
|
||||||
CConnection.cxx
|
|
||||||
CMsgHandler.cxx
|
|
||||||
CMsgReader.cxx
|
|
||||||
CMsgReaderV3.cxx
|
|
||||||
CMsgWriter.cxx
|
|
||||||
CMsgWriterV3.cxx
|
|
||||||
ComparingUpdateTracker.cxx
|
|
||||||
Configuration.cxx
|
|
||||||
ConnParams.cxx
|
|
||||||
CSecurityVncAuth.cxx
|
|
||||||
Cursor.cxx
|
|
||||||
Decoder.cxx
|
|
||||||
Encoder.cxx
|
|
||||||
encodings.cxx
|
|
||||||
HextileDecoder.cxx
|
|
||||||
HextileEncoder.cxx
|
|
||||||
HTTPServer.cxx
|
|
||||||
KeyRemapper.cxx
|
|
||||||
Logger.cxx
|
|
||||||
Logger_file.cxx
|
|
||||||
Logger_stdio.cxx
|
|
||||||
LogWriter.cxx
|
|
||||||
Password.cxx
|
|
||||||
PixelBuffer.cxx
|
|
||||||
PixelFormat.cxx
|
|
||||||
RawDecoder.cxx
|
|
||||||
RawEncoder.cxx
|
|
||||||
Region.cxx
|
|
||||||
RREDecoder.cxx
|
|
||||||
RREEncoder.cxx
|
|
||||||
SConnection.cxx
|
|
||||||
secTypes.cxx
|
|
||||||
ServerCore.cxx
|
|
||||||
SMsgHandler.cxx
|
|
||||||
SMsgReader.cxx
|
|
||||||
SMsgReaderV3.cxx
|
|
||||||
SMsgWriter.cxx
|
|
||||||
SMsgWriterV3.cxx
|
|
||||||
SSecurityFactoryStandard.cxx
|
|
||||||
SSecurityVncAuth.cxx
|
|
||||||
Timer.cxx
|
|
||||||
TransImageGetter.cxx
|
|
||||||
UpdateTracker.cxx
|
|
||||||
util.cxx
|
|
||||||
VNCSConnectionST.cxx
|
|
||||||
VNCServerST.cxx
|
|
||||||
ZRLEDecoder.cxx
|
|
||||||
ZRLEEncoder.cxx
|
|
||||||
)
|
|
||||||
|
|
||||||
if (WIN32)
|
|
||||||
list(APPEND src ${inc})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(inc
|
|
||||||
..
|
|
||||||
../../win
|
|
||||||
)
|
|
||||||
|
|
||||||
include_directories(${inc})
|
|
||||||
add_library(vnc_rfb STATIC ${src})
|
|
||||||
target_link_libraries(vnc_rfb
|
|
||||||
vnc_Xregion)
|
|
|
@ -1,99 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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(int w, int h, const Point& hotspot, 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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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();
|
|
||||||
|
|
||||||
// The following methods are called as corresponding messages are read. A
|
|
||||||
// derived class should override these methods as desired. Note that for
|
|
||||||
// the setDesktopSize(), setPixelFormat() and setName() methods, a derived
|
|
||||||
// class should call on to CMsgHandler's methods to set the members of cp
|
|
||||||
// appropriately.
|
|
||||||
|
|
||||||
virtual void setDesktopSize(int w, int h);
|
|
||||||
virtual void setCursor(int width, int height, const Point& hotspot,
|
|
||||||
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
|
|
|
@ -1,160 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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::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();
|
|
||||||
handler->setColourMapEntries(firstColour, nColours, rgbs.buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMsgReader::readBell()
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
handler->serverCutText(ca.buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMsgReader::readFramebufferUpdateStart()
|
|
||||||
{
|
|
||||||
handler->framebufferUpdateStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMsgReader::readFramebufferUpdateEnd()
|
|
||||||
{
|
|
||||||
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 (encoding > encodingMax)
|
|
||||||
throw Exception("Unknown rect encoding");
|
|
||||||
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(int width, int height, const Point& hotspot)
|
|
||||||
{
|
|
||||||
int data_len = width * height * (handler->cp.pf().bpp/8);
|
|
||||||
int mask_len = ((width+7)/8) * height;
|
|
||||||
rdr::U8Array data(data_len);
|
|
||||||
rdr::U8Array mask(mask_len);
|
|
||||||
|
|
||||||
is->readBytes(data.buf, data_len);
|
|
||||||
is->readBytes(mask.buf, mask_len);
|
|
||||||
|
|
||||||
handler->setCursor(width, height, hotspot, 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;
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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 readFramebufferUpdateStart();
|
|
||||||
virtual void readFramebufferUpdateEnd();
|
|
||||||
virtual void readRect(const Rect& r, unsigned int encoding);
|
|
||||||
|
|
||||||
virtual void readCopyRect(const Rect& r);
|
|
||||||
|
|
||||||
virtual void readSetCursor(int width, int height, const Point& hotspot);
|
|
||||||
|
|
||||||
CMsgReader(CMsgHandler* handler, rdr::InStream* is);
|
|
||||||
|
|
||||||
CMsgHandler* handler;
|
|
||||||
rdr::InStream* is;
|
|
||||||
Decoder* decoders[encodingMax+1];
|
|
||||||
rdr::U8* imageBuf;
|
|
||||||
int imageBufSize;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,95 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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>
|
|
||||||
#include <rfb/util.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);
|
|
||||||
CharArray name(is->readString());
|
|
||||||
handler->setName(name.buf);
|
|
||||||
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(w, h, Point(x,y));
|
|
||||||
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();
|
|
||||||
handler->framebufferUpdateStart();
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,126 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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::keyEvent(rdr::U32 key, bool down)
|
|
||||||
{
|
|
||||||
startMsg(msgTypeKeyEvent);
|
|
||||||
os->writeU8(down);
|
|
||||||
os->pad(2);
|
|
||||||
os->writeU32(key);
|
|
||||||
endMsg();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CMsgWriter::pointerEvent(const Point& pos, int buttonMask)
|
|
||||||
{
|
|
||||||
Point p(pos);
|
|
||||||
if (p.x < 0) p.x = 0;
|
|
||||||
if (p.y < 0) p.y = 0;
|
|
||||||
if (p.x >= cp->width) p.x = cp->width - 1;
|
|
||||||
if (p.y >= cp->height) p.y = cp->height - 1;
|
|
||||||
|
|
||||||
startMsg(msgTypePointerEvent);
|
|
||||||
os->writeU8(buttonMask);
|
|
||||||
os->writeU16(p.x);
|
|
||||||
os->writeU16(p.y);
|
|
||||||
endMsg();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CMsgWriter::clientCutText(const char* str, int len)
|
|
||||||
{
|
|
||||||
startMsg(msgTypeClientCutText);
|
|
||||||
os->pad(3);
|
|
||||||
os->writeU32(len);
|
|
||||||
os->writeBytes(str, len);
|
|
||||||
endMsg();
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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 <rfb/InputHandler.h>
|
|
||||||
|
|
||||||
namespace rdr { class OutStream; }
|
|
||||||
|
|
||||||
namespace rfb {
|
|
||||||
|
|
||||||
class PixelFormat;
|
|
||||||
class ConnParams;
|
|
||||||
struct Rect;
|
|
||||||
|
|
||||||
class CMsgWriter : public InputHandler {
|
|
||||||
public:
|
|
||||||
virtual ~CMsgWriter();
|
|
||||||
|
|
||||||
// CMsgWriter abstract interface methods
|
|
||||||
virtual void writeClientInit(bool shared)=0;
|
|
||||||
virtual void startMsg(int type)=0;
|
|
||||||
virtual void endMsg()=0;
|
|
||||||
|
|
||||||
// CMsgWriter implemented methods
|
|
||||||
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);
|
|
||||||
|
|
||||||
// InputHandler implementation
|
|
||||||
virtual void keyEvent(rdr::U32 key, bool down);
|
|
||||||
virtual void pointerEvent(const Point& pos, int buttonMask);
|
|
||||||
virtual void clientCutText(const char* str, int len);
|
|
||||||
|
|
||||||
ConnParams* getConnParams() { return cp; }
|
|
||||||
rdr::OutStream* getOutStream() { return os; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
CMsgWriter(ConnParams* cp, rdr::OutStream* os);
|
|
||||||
|
|
||||||
ConnParams* cp;
|
|
||||||
rdr::OutStream* os;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,49 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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();
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,52 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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. It
|
|
||||||
// should return false when it needs more data, or true when the security
|
|
||||||
// handshaking is over and we are now waiting for the SecurityResult message
|
|
||||||
// from the server. In the event of failure a suitable exception should be
|
|
||||||
// thrown.
|
|
||||||
//
|
|
||||||
// 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)=0;
|
|
||||||
virtual void destroy() { delete this; }
|
|
||||||
virtual int getType() const = 0;
|
|
||||||
virtual const char* description() const = 0;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,36 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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) { return true; }
|
|
||||||
virtual int getType() const {return secTypeNone;}
|
|
||||||
virtual const char* description() const {return "No Encryption";}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,74 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
||||||
//
|
|
||||||
// XXX not thread-safe, because d3des isn't - do we need to worry about this?
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <rfb/CConnection.h>
|
|
||||||
#include <rfb/UserPasswdGetter.h>
|
|
||||||
#include <rfb/Password.h>
|
|
||||||
#include <rfb/CSecurityVncAuth.h>
|
|
||||||
#include <rfb/util.h>
|
|
||||||
extern "C" {
|
|
||||||
#include <rfb/d3des.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
using namespace rfb;
|
|
||||||
|
|
||||||
static const int vncAuthChallengeSize = 16;
|
|
||||||
|
|
||||||
|
|
||||||
CSecurityVncAuth::CSecurityVncAuth(UserPasswdGetter* upg_)
|
|
||||||
: upg(upg_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CSecurityVncAuth::~CSecurityVncAuth()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSecurityVncAuth::processMsg(CConnection* cc)
|
|
||||||
{
|
|
||||||
rdr::InStream* is = cc->getInStream();
|
|
||||||
rdr::OutStream* os = cc->getOutStream();
|
|
||||||
|
|
||||||
// Read the challenge & obtain the user's password
|
|
||||||
rdr::U8 challenge[vncAuthChallengeSize];
|
|
||||||
is->readBytes(challenge, vncAuthChallengeSize);
|
|
||||||
PlainPasswd passwd(strDup("test"));
|
|
||||||
//upg->getUserPasswd(0, &passwd.buf);
|
|
||||||
|
|
||||||
// Calculate the correct response
|
|
||||||
rdr::U8 key[8];
|
|
||||||
int pwdLen = strlen(passwd.buf);
|
|
||||||
for (int i=0; i<8; i++)
|
|
||||||
key[i] = i<pwdLen ? passwd.buf[i] : 0;
|
|
||||||
deskey(key, EN0);
|
|
||||||
for (int j = 0; j < vncAuthChallengeSize; j += 8)
|
|
||||||
des(challenge+j, challenge+j);
|
|
||||||
|
|
||||||
// Return the response to the server
|
|
||||||
os->writeBytes(challenge, vncAuthChallengeSize);
|
|
||||||
os->flush();
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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>
|
|
||||||
|
|
||||||
namespace rfb {
|
|
||||||
|
|
||||||
class UserPasswdGetter;
|
|
||||||
|
|
||||||
class CSecurityVncAuth : public CSecurity {
|
|
||||||
public:
|
|
||||||
CSecurityVncAuth(UserPasswdGetter* pg);
|
|
||||||
virtual ~CSecurityVncAuth();
|
|
||||||
virtual bool processMsg(CConnection* cc);
|
|
||||||
virtual int getType() const {return secTypeVncAuth;};
|
|
||||||
virtual const char* description() const {return "No Encryption";}
|
|
||||||
private:
|
|
||||||
UserPasswdGetter* upg;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,96 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,36 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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_) {}
|
|
||||||
virtual ~Colour() {}
|
|
||||||
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 ~ColourMap() {}
|
|
||||||
virtual void lookup(int index, int* r, int* g, int* b)=0;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,137 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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)
|
|
||||||
: fb(buffer), oldFb(fb->getPF(), 0, 0), firstCompare(true)
|
|
||||||
{
|
|
||||||
changed.assign_union(fb->getRect());
|
|
||||||
}
|
|
||||||
|
|
||||||
ComparingUpdateTracker::~ComparingUpdateTracker()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#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(), __rfbmin(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, __rfbmin(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 = __rfbmin(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 = __rfbmin(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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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();
|
|
||||||
private:
|
|
||||||
void compareRect(const Rect& r, Region* newchanged);
|
|
||||||
PixelBuffer* fb;
|
|
||||||
ManagedPixelBuffer oldFb;
|
|
||||||
bool firstCompare;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,446 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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>
|
|
||||||
#include <rfb/Threading.h>
|
|
||||||
|
|
||||||
#ifdef __RFB_THREADING_IMPL
|
|
||||||
// On platforms that support Threading, we use Locks to make getData safe
|
|
||||||
#define LOCK_CONFIG Lock l(*configLock())
|
|
||||||
rfb::Mutex* configLock_ = 0;
|
|
||||||
static rfb::Mutex* configLock() {
|
|
||||||
if (!configLock_)
|
|
||||||
configLock_ = new rfb::Mutex;
|
|
||||||
return configLock_;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define LOCK_CONFIG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <rdr/HexOutStream.h>
|
|
||||||
#include <rdr/HexInStream.h>
|
|
||||||
|
|
||||||
using namespace rfb;
|
|
||||||
|
|
||||||
static LogWriter vlog("Config");
|
|
||||||
|
|
||||||
|
|
||||||
// -=- The Global Configuration object
|
|
||||||
Configuration* Configuration::global_ = 0;
|
|
||||||
Configuration* Configuration::global() {
|
|
||||||
if (!global_)
|
|
||||||
global_ = new Configuration("Global");
|
|
||||||
return global_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -=- Configuration implementation
|
|
||||||
|
|
||||||
Configuration::Configuration(const char* name_, Configuration* attachToGroup)
|
|
||||||
: name(strDup(name_)), head(0), _next(0) {
|
|
||||||
if (attachToGroup) {
|
|
||||||
_next = attachToGroup->_next;
|
|
||||||
attachToGroup->_next = this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Configuration& Configuration::operator=(const Configuration& src) {
|
|
||||||
VoidParameter* current = head;
|
|
||||||
while (current) {
|
|
||||||
VoidParameter* srcParam = ((Configuration&)src).get(current->getName());
|
|
||||||
if (srcParam) {
|
|
||||||
current->immutable = false;
|
|
||||||
CharArray value(srcParam->getValueStr());
|
|
||||||
vlog.debug("operator=(%s, %s)", current->getName(), value.buf);
|
|
||||||
current->setParam(value.buf);
|
|
||||||
}
|
|
||||||
current = current->_next;
|
|
||||||
}
|
|
||||||
if (_next)
|
|
||||||
*_next=src;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Configuration::set(const char* n, const char* v, bool immutable) {
|
|
||||||
return set(n, strlen(n), v, immutable);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Configuration::set(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 _next ? _next->set(name, len, val, immutable) : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Configuration::set(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 set(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 _next ? _next->set(config, immutable) : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
VoidParameter* Configuration::get(const char* param)
|
|
||||||
{
|
|
||||||
VoidParameter* current = head;
|
|
||||||
while (current) {
|
|
||||||
if (strcasecmp(current->getName(), param) == 0)
|
|
||||||
return current;
|
|
||||||
current = current->_next;
|
|
||||||
}
|
|
||||||
return _next ? _next->get(param) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Configuration::list(int width, int nameWidth) {
|
|
||||||
VoidParameter* current = head;
|
|
||||||
|
|
||||||
fprintf(stderr, "%s Parameters:\n", name.buf);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_next)
|
|
||||||
_next->list(width, nameWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -=- VoidParameter
|
|
||||||
|
|
||||||
VoidParameter::VoidParameter(const char* name_, const char* desc_, Configuration* conf)
|
|
||||||
: immutable(false), name(name_), description(desc_) {
|
|
||||||
if (!conf)
|
|
||||||
conf = Configuration::global();
|
|
||||||
_next = conf->head;
|
|
||||||
conf->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_, Configuration* conf)
|
|
||||||
: VoidParameter(name_, desc_, conf), 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, Configuration* conf)
|
|
||||||
: VoidParameter(name_, desc_, conf), 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 {
|
|
||||||
return strDup(def_value ? "1" : "0");
|
|
||||||
}
|
|
||||||
|
|
||||||
char* BoolParameter::getValueStr() const {
|
|
||||||
return strDup(value ? "1" : "0");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoolParameter::isBool() const {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
BoolParameter::operator bool() const {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -=- IntParameter
|
|
||||||
|
|
||||||
IntParameter::IntParameter(const char* name_, const char* desc_, int v,
|
|
||||||
int minValue_, int maxValue_, Configuration* conf)
|
|
||||||
: VoidParameter(name_, desc_, conf), value(v), def_value(v),
|
|
||||||
minValue(minValue_), maxValue(maxValue_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
IntParameter::setParam(const char* v) {
|
|
||||||
if (immutable) return true;
|
|
||||||
vlog.debug("set %s(Int) to %s", getName(), v);
|
|
||||||
int i = atoi(v);
|
|
||||||
if (i < minValue || i > maxValue)
|
|
||||||
return false;
|
|
||||||
value = i;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
IntParameter::setParam(int v) {
|
|
||||||
if (immutable) return true;
|
|
||||||
vlog.debug("set %s(Int) to %d", getName(), v);
|
|
||||||
if (v < minValue || v > maxValue)
|
|
||||||
return false;
|
|
||||||
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, Configuration* conf)
|
|
||||||
: VoidParameter(name_, desc_, conf), 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) {
|
|
||||||
LOCK_CONFIG;
|
|
||||||
if (immutable) return true;
|
|
||||||
if (!v)
|
|
||||||
throw rfb::Exception("setParam(<null>) not allowed");
|
|
||||||
vlog.debug("set %s(String) to %s", getName(), v);
|
|
||||||
CharArray oldValue(value);
|
|
||||||
value = strDup(v);
|
|
||||||
return value != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* StringParameter::getDefaultStr() const {
|
|
||||||
return strDup(def_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* StringParameter::getValueStr() const {
|
|
||||||
LOCK_CONFIG;
|
|
||||||
return strDup(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -=- BinaryParameter
|
|
||||||
|
|
||||||
BinaryParameter::BinaryParameter(const char* name_, const char* desc_, const void* v, int l, Configuration* conf)
|
|
||||||
: VoidParameter(name_, desc_, conf), 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) {
|
|
||||||
LOCK_CONFIG;
|
|
||||||
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) {
|
|
||||||
LOCK_CONFIG;
|
|
||||||
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 {
|
|
||||||
LOCK_CONFIG;
|
|
||||||
return rdr::HexOutStream::binToHexStr(value, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BinaryParameter::getData(void** data_, int* length_) const {
|
|
||||||
LOCK_CONFIG;
|
|
||||||
if (length_) *length_ = length;
|
|
||||||
if (data_) {
|
|
||||||
*data_ = new char[length];
|
|
||||||
memcpy(*data_, value, length);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,260 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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.
|
|
||||||
//
|
|
||||||
// If no Configuration is specified when creating a Parameter, then the
|
|
||||||
// global Configuration will be assumed.
|
|
||||||
//
|
|
||||||
// Configurations can be "chained" into groups. Each group has a root
|
|
||||||
// Configuration, a pointer to which should be passed to the constructors
|
|
||||||
// of the other group members. set() and get() operations called on the
|
|
||||||
// root will iterate through all of the group's members.
|
|
||||||
//
|
|
||||||
// NB: On platforms that support Threading, locking is performed to protect
|
|
||||||
// complex parameter types from concurrent access (e.g. strings).
|
|
||||||
// NB: NO LOCKING is performed when linking Configurations to groups
|
|
||||||
// or when adding Parameters to Configurations.
|
|
||||||
|
|
||||||
#ifndef __RFB_CONFIGURATION_H__
|
|
||||||
#define __RFB_CONFIGURATION_H__
|
|
||||||
|
|
||||||
#include <rfb/util.h>
|
|
||||||
|
|
||||||
namespace rfb {
|
|
||||||
class VoidParameter;
|
|
||||||
struct ParameterIterator;
|
|
||||||
|
|
||||||
// -=- Configuration
|
|
||||||
// Class used to access parameters.
|
|
||||||
|
|
||||||
class Configuration {
|
|
||||||
public:
|
|
||||||
// - Create a new Configuration object
|
|
||||||
Configuration(const char* name, Configuration* attachToGroup=0);
|
|
||||||
|
|
||||||
// - Return the buffer containing the Configuration's name
|
|
||||||
const char* getName() const { return name.buf; }
|
|
||||||
|
|
||||||
// - Assignment operator. For every Parameter in this Configuration's
|
|
||||||
// group, get()s the corresponding source parameter and copies its
|
|
||||||
// content.
|
|
||||||
Configuration& operator=(const Configuration& src);
|
|
||||||
|
|
||||||
// - Set named parameter to value
|
|
||||||
bool set(const char* param, const char* value, bool immutable=false);
|
|
||||||
|
|
||||||
// - Set parameter to value (separated by "=")
|
|
||||||
bool set(const char* config, bool immutable=false);
|
|
||||||
|
|
||||||
// - Set named parameter to value, with name truncated at len
|
|
||||||
bool set(const char* name, int len,
|
|
||||||
const char* val, bool immutable);
|
|
||||||
|
|
||||||
// - Get named parameter
|
|
||||||
VoidParameter* get(const char* param);
|
|
||||||
|
|
||||||
// - List the parameters of this Configuration group
|
|
||||||
void list(int width=79, int nameWidth=10);
|
|
||||||
|
|
||||||
// - readFromFile
|
|
||||||
// Read configuration parameters from the specified file.
|
|
||||||
void readFromFile(const char* filename);
|
|
||||||
|
|
||||||
// - writeConfigToFile
|
|
||||||
// Write a new configuration parameters file, then mv it
|
|
||||||
// over the old file.
|
|
||||||
void writeToFile(const char* filename);
|
|
||||||
|
|
||||||
|
|
||||||
// - Get the Global Configuration object
|
|
||||||
// NB: This call does NOT lock the Configuration system.
|
|
||||||
// ALWAYS ensure that if you have ANY global Parameters,
|
|
||||||
// then they are defined as global objects, to ensure that
|
|
||||||
// global() is called when only the main thread is running.
|
|
||||||
static Configuration* global();
|
|
||||||
|
|
||||||
// - Container for process-wide Global parameters
|
|
||||||
static bool setParam(const char* param, const char* value, bool immutable=false) {
|
|
||||||
return global()->set(param, value, immutable);
|
|
||||||
}
|
|
||||||
static bool setParam(const char* config, bool immutable=false) {
|
|
||||||
return global()->set(config, immutable);
|
|
||||||
}
|
|
||||||
static bool setParam(const char* name, int len,
|
|
||||||
const char* val, bool immutable) {
|
|
||||||
return global()->set(name, len, val, immutable);
|
|
||||||
}
|
|
||||||
static VoidParameter* getParam(const char* param) { return global()->get(param); }
|
|
||||||
static void listParams(int width=79, int nameWidth=10) { global()->list(width, nameWidth); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
friend class VoidParameter;
|
|
||||||
friend struct ParameterIterator;
|
|
||||||
|
|
||||||
// Name for this Configuration
|
|
||||||
CharArray name;
|
|
||||||
|
|
||||||
// - Pointer to first Parameter in this group
|
|
||||||
VoidParameter* head;
|
|
||||||
|
|
||||||
// Pointer to next Configuration in this group
|
|
||||||
Configuration* _next;
|
|
||||||
|
|
||||||
// The process-wide, Global Configuration object
|
|
||||||
static Configuration* global_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// -=- VoidParameter
|
|
||||||
// Configuration parameter base-class.
|
|
||||||
|
|
||||||
class VoidParameter {
|
|
||||||
public:
|
|
||||||
VoidParameter(const char* name_, const char* desc_, Configuration* conf=0);
|
|
||||||
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();
|
|
||||||
protected:
|
|
||||||
friend class Configuration;
|
|
||||||
friend struct ParameterIterator;
|
|
||||||
|
|
||||||
VoidParameter* _next;
|
|
||||||
bool immutable;
|
|
||||||
const char* name;
|
|
||||||
const char* description;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AliasParameter : public VoidParameter {
|
|
||||||
public:
|
|
||||||
AliasParameter(const char* name_, const char* desc_,VoidParameter* param_, Configuration* conf=0);
|
|
||||||
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, Configuration* conf=0);
|
|
||||||
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,
|
|
||||||
int minValue=INT_MIN, int maxValue=INT_MAX, Configuration* conf=0);
|
|
||||||
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;
|
|
||||||
int minValue, maxValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
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, Configuration* conf=0);
|
|
||||||
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, Configuration* conf=0);
|
|
||||||
virtual ~BinaryParameter();
|
|
||||||
virtual bool setParam(const char* value);
|
|
||||||
virtual void setParam(const void* v, int l);
|
|
||||||
virtual char* getDefaultStr() const;
|
|
||||||
virtual char* getValueStr() const;
|
|
||||||
|
|
||||||
// getData() will return length zero if there is no data
|
|
||||||
// NB: data may be set to zero, OR set to a zero-length buffer
|
|
||||||
void getData(void** data, int* length) const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
char* value;
|
|
||||||
int length;
|
|
||||||
char* def_value;
|
|
||||||
int def_length;
|
|
||||||
};
|
|
||||||
|
|
||||||
// -=- ParameterIterator
|
|
||||||
// Iterates over all the Parameters in a Configuration group. The
|
|
||||||
// current Parameter is accessed via param, the current Configuration
|
|
||||||
// via config. The next() method moves on to the next Parameter.
|
|
||||||
|
|
||||||
struct ParameterIterator {
|
|
||||||
ParameterIterator(Configuration* c) : config(c), param(c ? c->head : 0) {}
|
|
||||||
void next() {
|
|
||||||
param = param->_next;
|
|
||||||
while (!param) {
|
|
||||||
config = config->_next;
|
|
||||||
if (!config) break;
|
|
||||||
param = config->head;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Configuration* config;
|
|
||||||
VoidParameter* param;
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // __RFB_CONFIGURATION_H__
|
|
|
@ -1,105 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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(true),
|
|
||||||
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;
|
|
||||||
supportsDesktopResize = 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];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,179 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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;
|
|
||||||
*pix0 = *pix1 = 0;
|
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,68 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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);
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,75 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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);
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,37 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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 {
|
|
||||||
typedef rdr::Exception Exception;
|
|
||||||
struct AuthFailureException : public Exception {
|
|
||||||
AuthFailureException(const char* s="Authentication failure")
|
|
||||||
: Exception(s) {}
|
|
||||||
};
|
|
||||||
struct AuthCancelledException : public rfb::Exception {
|
|
||||||
AuthCancelledException(const char* s="Authentication cancelled")
|
|
||||||
: Exception(s) {}
|
|
||||||
};
|
|
||||||
struct ConnFailedException : public Exception {
|
|
||||||
ConnFailedException(const char* s="Connection failed") : Exception(s) {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,412 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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>
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#define strcasecmp _stricmp
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#pragma warning(disable: 4244)
|
|
||||||
|
|
||||||
using namespace rfb;
|
|
||||||
using namespace rdr;
|
|
||||||
|
|
||||||
static LogWriter vlog("HTTPServer");
|
|
||||||
|
|
||||||
const int clientWaitTimeMillis = 20000;
|
|
||||||
const int idleTimeoutSecs = 5 * 60;
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// -=- 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), contentLength(-1), lastModified(-1),
|
|
||||||
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;
|
|
||||||
int contentLength;
|
|
||||||
time_t lastModified;
|
|
||||||
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");
|
|
||||||
time_t now = time(0);
|
|
||||||
struct tm* tm = gmtime(&now);
|
|
||||||
strftime(buffer, 1024, "Date: %a, %d %b %Y %H:%M:%S GMT", tm);
|
|
||||||
writeLine(os, buffer);
|
|
||||||
if (lastModified == (time_t)-1 || lastModified == 0)
|
|
||||||
lastModified = now;
|
|
||||||
tm = gmtime(&lastModified);
|
|
||||||
strftime(buffer, 1024, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT", tm);
|
|
||||||
writeLine(os, buffer);
|
|
||||||
if (contentLength != -1) {
|
|
||||||
sprintf(buffer,"Content-Length: %d",contentLength);
|
|
||||||
writeLine(os, buffer);
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
contentLength = -1;
|
|
||||||
lastModified = -1;
|
|
||||||
InStream* data = server.getFile(uri.buf, &contentType, &contentLength,
|
|
||||||
&lastModified);
|
|
||||||
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 + idleTimeoutSecs) - now;
|
|
||||||
if (timeout > 0)
|
|
||||||
return secsToMillis(timeout);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -=- SocketServer interface implementation
|
|
||||||
|
|
||||||
void
|
|
||||||
HTTPServer::addSocket(network::Socket* sock, bool) {
|
|
||||||
Session* s = new Session(*sock, *this);
|
|
||||||
if (!s) {
|
|
||||||
sock->shutdown();
|
|
||||||
} else {
|
|
||||||
sock->inStream().setTimeout(clientWaitTimeMillis);
|
|
||||||
sock->outStream().setTimeout(clientWaitTimeMillis);
|
|
||||||
sessions.push_front(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
HTTPServer::removeSocket(network::Socket* sock) {
|
|
||||||
std::list<Session*>::iterator i;
|
|
||||||
for (i=sessions.begin(); i!=sessions.end(); i++) {
|
|
||||||
if ((*i)->getSock() == sock) {
|
|
||||||
delete *i;
|
|
||||||
sessions.erase(i);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
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");
|
|
||||||
sock->shutdown();
|
|
||||||
}
|
|
||||||
} catch (rdr::Exception& e) {
|
|
||||||
vlog.error("untrapped: %s", e.str());
|
|
||||||
sock->shutdown();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw rdr::Exception("invalid Socket in HTTPServer");
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
|
||||||
int* contentLength, time_t* lastModified)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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>
|
|
||||||
#include <time.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();
|
|
||||||
|
|
||||||
// SocketServer interface
|
|
||||||
|
|
||||||
// addSocket()
|
|
||||||
// This causes the server to perform HTTP protocol on the
|
|
||||||
// supplied socket.
|
|
||||||
virtual void addSocket(network::Socket* sock, bool outgoing=false);
|
|
||||||
|
|
||||||
// removeSocket()
|
|
||||||
// Could clean up socket-specific resources here.
|
|
||||||
virtual void removeSocket(network::Socket* sock);
|
|
||||||
|
|
||||||
// processSocketEvent()
|
|
||||||
// The platform-specific side of the server implementation calls
|
|
||||||
// this method whenever data arrives on one of the active
|
|
||||||
// network sockets.
|
|
||||||
virtual void 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,
|
|
||||||
int* contentLength, time_t* lastModified);
|
|
||||||
|
|
||||||
// - 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
|
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,61 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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;
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,55 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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 <stdlib.h>
|
|
||||||
#include <rdr/Exception.h>
|
|
||||||
#include <rfb/util.h>
|
|
||||||
|
|
||||||
namespace rfb {
|
|
||||||
|
|
||||||
static 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__
|
|
|
@ -1,30 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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
|
|
|
@ -1,40 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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.
|
|
||||||
*/
|
|
||||||
//
|
|
||||||
// InputHandler - abstract interface for accepting keyboard &
|
|
||||||
// pointer input and clipboard data.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef __RFB_INPUTHANDLER_H__
|
|
||||||
#define __RFB_INPUTHANDLER_H__
|
|
||||||
|
|
||||||
#include <rdr/types.h>
|
|
||||||
#include <rfb/Rect.h>
|
|
||||||
|
|
||||||
namespace rfb {
|
|
||||||
|
|
||||||
class InputHandler {
|
|
||||||
public:
|
|
||||||
virtual ~InputHandler() {}
|
|
||||||
virtual void keyEvent(rdr::U32 key, bool down) {}
|
|
||||||
virtual void pointerEvent(const Point& pos, int buttonMask) {}
|
|
||||||
virtual void clientCutText(const char* str, int len) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,84 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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/KeyRemapper.h>
|
|
||||||
#include <rfb/Configuration.h>
|
|
||||||
#include <rfb/LogWriter.h>
|
|
||||||
|
|
||||||
using namespace rfb;
|
|
||||||
|
|
||||||
static LogWriter vlog("KeyRemapper");
|
|
||||||
|
|
||||||
KeyRemapper KeyRemapper::defInstance;
|
|
||||||
|
|
||||||
#ifdef __RFB_THREADING_IMPL
|
|
||||||
static Mutex mappingLock;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void KeyRemapper::setMapping(const char* m) {
|
|
||||||
#ifdef __RFB_THREADING_IMPL
|
|
||||||
Lock l(mappingLock);
|
|
||||||
#endif
|
|
||||||
mapping.clear();
|
|
||||||
while (m[0]) {
|
|
||||||
int from, to;
|
|
||||||
char bidi;
|
|
||||||
const char* nextComma = strchr(m, ',');
|
|
||||||
if (!nextComma)
|
|
||||||
nextComma = m + strlen(m);
|
|
||||||
if (sscanf(m, "0x%x%c>0x%x", &from,
|
|
||||||
&bidi, &to) == 3) {
|
|
||||||
if (bidi != '-' && bidi != '<')
|
|
||||||
vlog.error("warning: unknown operation %c>, assuming ->", bidi);
|
|
||||||
mapping[from] = to;
|
|
||||||
if (bidi == '<')
|
|
||||||
mapping[to] = from;
|
|
||||||
} else {
|
|
||||||
vlog.error("warning: bad mapping %.*s", nextComma-m, m);
|
|
||||||
}
|
|
||||||
m = nextComma;
|
|
||||||
if (nextComma[0])
|
|
||||||
m++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rdr::U32 KeyRemapper::remapKey(rdr::U32 key) const {
|
|
||||||
#ifdef __RFB_THREADING_IMPL
|
|
||||||
Lock l(mappingLock);
|
|
||||||
#endif
|
|
||||||
std::map<rdr::U32,rdr::U32>::const_iterator i = mapping.find(key);
|
|
||||||
if (i != mapping.end())
|
|
||||||
return i->second;
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class KeyMapParameter : public StringParameter {
|
|
||||||
public:
|
|
||||||
KeyMapParameter()
|
|
||||||
: StringParameter("RemapKeys", "Comma-separated list of incoming keysyms to remap. Mappings are expressed as two hex values, prefixed by 0x, and separated by ->", "") {
|
|
||||||
setParam(value);
|
|
||||||
}
|
|
||||||
bool setParam(const char* v) {
|
|
||||||
KeyRemapper::defInstance.setMapping(v);
|
|
||||||
return StringParameter::setParam(v);
|
|
||||||
}
|
|
||||||
} defaultParam;
|
|
||||||
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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_KEYREMAPPER_H__
|
|
||||||
#define __RFB_KEYREMAPPER_H__
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <rdr/types.h>
|
|
||||||
|
|
||||||
namespace rfb {
|
|
||||||
|
|
||||||
class KeyRemapper {
|
|
||||||
public:
|
|
||||||
KeyRemapper(const char* m="") { setMapping(m); }
|
|
||||||
void setMapping(const char* m);
|
|
||||||
rdr::U32 remapKey(rdr::U32 key) const;
|
|
||||||
static KeyRemapper defInstance;
|
|
||||||
private:
|
|
||||||
std::map<rdr::U32,rdr::U32> mapping;
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // __RFB_KEYREMAPPER_H__
|
|
|
@ -1,137 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* This is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This software is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this software; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
||||||
* USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// -=- LogWriter.cxx - client-side logging interface
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#ifdef WIN32
|
|
||||||
#define strcasecmp _stricmp
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <rfb/LogWriter.h>
|
|
||||||
#include <rfb/Configuration.h>
|
|
||||||
#include <rfb/util.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
rfb::LogParameter rfb::logParams;
|
|
||||||
|
|
||||||
using namespace rfb;
|
|
||||||
|
|
||||||
|
|
||||||
LogWriter::LogWriter(const char* name) : m_name(name), m_level(0), m_log(0), m_next(log_writers) {
|
|
||||||
log_writers = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogWriter::~LogWriter() {
|
|
||||||
// *** Should remove this logger here!
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogWriter::setLog(Logger *logger) {
|
|
||||||
m_log = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogWriter::setLevel(int level) {
|
|
||||||
m_level = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LogWriter::listLogWriters(int width) {
|
|
||||||
// *** make this respect width...
|
|
||||||
LogWriter* current = log_writers;
|
|
||||||
fprintf(stderr, " ");
|
|
||||||
while (current) {
|
|
||||||
fprintf(stderr, "%s", current->m_name);
|
|
||||||
current = current->m_next;
|
|
||||||
if (current) fprintf(stderr, ", ");
|
|
||||||
}
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
LogWriter* LogWriter::log_writers;
|
|
||||||
|
|
||||||
LogWriter*
|
|
||||||
LogWriter::getLogWriter(const char* name) {
|
|
||||||
LogWriter* current = log_writers;
|
|
||||||
while (current) {
|
|
||||||
if (strcasecmp(name, current->m_name) == 0) return current;
|
|
||||||
current = current->m_next;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LogWriter::setLogParams(const char* params) {
|
|
||||||
CharArray logwriterName, loggerName, logLevel;
|
|
||||||
if (!strSplit(params, ':', &logwriterName.buf, &loggerName.buf) ||
|
|
||||||
!strSplit(loggerName.buf, ':', &loggerName.buf, &logLevel.buf)) {
|
|
||||||
fprintf(stderr,"failed to parse log params:%s\n",params);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int level = atoi(logLevel.buf);
|
|
||||||
Logger* logger = 0;
|
|
||||||
if (strcmp("", loggerName.buf) != 0) {
|
|
||||||
logger = Logger::getLogger(loggerName.buf);
|
|
||||||
if (!logger) fprintf(stderr,"no logger found! %s\n",loggerName.buf);
|
|
||||||
}
|
|
||||||
if (strcmp("*", logwriterName.buf) == 0) {
|
|
||||||
LogWriter* current = log_writers;
|
|
||||||
while (current) {
|
|
||||||
current->setLog(logger);
|
|
||||||
current->setLevel(level);
|
|
||||||
current = current->m_next;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
LogWriter* logwriter = getLogWriter(logwriterName.buf);
|
|
||||||
if (!logwriter) {
|
|
||||||
fprintf(stderr,"no logwriter found! %s\n",logwriterName.buf);
|
|
||||||
} else {
|
|
||||||
logwriter->setLog(logger);
|
|
||||||
logwriter->setLevel(level);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LogParameter::LogParameter()
|
|
||||||
: StringParameter("Log",
|
|
||||||
"Specifies which log output should be directed to "
|
|
||||||
"which target logger, and the level of output to log. "
|
|
||||||
"Format is <log>:<target>:<level>[, ...].",
|
|
||||||
"") {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LogParameter::setParam(const char* v) {
|
|
||||||
if (immutable) return true;
|
|
||||||
LogWriter::setLogParams("*::0");
|
|
||||||
StringParameter::setParam(v);
|
|
||||||
CharArray logParam;
|
|
||||||
CharArray params(getData());
|
|
||||||
while (params.buf) {
|
|
||||||
strSplit(params.buf, ',', &logParam.buf, ¶ms.buf);
|
|
||||||
if (strlen(logParam.buf) && !LogWriter::setLogParams(logParam.buf))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogParameter::setDefault(const char* d) {
|
|
||||||
def_value = d;
|
|
||||||
setParam(def_value);
|
|
||||||
}
|
|
|
@ -1,106 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* This is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This software is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this software; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
||||||
* USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// -=- LogWriter.h - The Log writer class.
|
|
||||||
|
|
||||||
#ifndef __RFB_LOG_WRITER_H__
|
|
||||||
#define __RFB_LOG_WRITER_H__
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <rfb/Logger.h>
|
|
||||||
#include <rfb/Configuration.h>
|
|
||||||
|
|
||||||
// Each log writer instance has a unique textual name,
|
|
||||||
// and is attached to a particular Log instance and
|
|
||||||
// is assigned a particular log level.
|
|
||||||
|
|
||||||
#define DEF_LOGFUNCTION(name, level) \
|
|
||||||
inline void name(const char* fmt, ...) { \
|
|
||||||
if (m_log && (level <= m_level)) { \
|
|
||||||
va_list ap; va_start(ap, fmt); \
|
|
||||||
m_log->write(level, m_name, fmt, ap);\
|
|
||||||
va_end(ap); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace rfb {
|
|
||||||
|
|
||||||
class LogWriter;
|
|
||||||
|
|
||||||
class LogWriter {
|
|
||||||
public:
|
|
||||||
LogWriter(const char* name);
|
|
||||||
~LogWriter();
|
|
||||||
|
|
||||||
const char *getName() {return m_name;}
|
|
||||||
|
|
||||||
void setLog(Logger *logger);
|
|
||||||
void setLevel(int level);
|
|
||||||
|
|
||||||
inline void write(int level, const char* format, ...) {
|
|
||||||
if (m_log && (level <= m_level)) {
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, format);
|
|
||||||
m_log->write(level, m_name, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DEF_LOGFUNCTION(error, 0)
|
|
||||||
DEF_LOGFUNCTION(status, 10)
|
|
||||||
DEF_LOGFUNCTION(info, 30)
|
|
||||||
DEF_LOGFUNCTION(debug, 100)
|
|
||||||
|
|
||||||
// -=- DIAGNOSTIC & HELPER ROUTINES
|
|
||||||
|
|
||||||
static void listLogWriters(int width=79);
|
|
||||||
|
|
||||||
// -=- CLASS FIELDS & FUNCTIONS
|
|
||||||
|
|
||||||
static LogWriter* log_writers;
|
|
||||||
|
|
||||||
static LogWriter* getLogWriter(const char* name);
|
|
||||||
|
|
||||||
static bool setLogParams(const char* params);
|
|
||||||
|
|
||||||
private:
|
|
||||||
const char* m_name;
|
|
||||||
int m_level;
|
|
||||||
Logger* m_log;
|
|
||||||
LogWriter* m_next;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LogParameter : public StringParameter {
|
|
||||||
public:
|
|
||||||
LogParameter();
|
|
||||||
virtual bool setParam(const char* v);
|
|
||||||
|
|
||||||
// Call this to set a suitable default value.
|
|
||||||
// Can't use the normal default mechanism for
|
|
||||||
// this because there is no guarantee on C++
|
|
||||||
// constructor ordering - some LogWriters may
|
|
||||||
// not exist when LogParameter gets constructed.
|
|
||||||
// NB: The default value must exist for the
|
|
||||||
// lifetime of the process!
|
|
||||||
void setDefault(const char* v);
|
|
||||||
};
|
|
||||||
extern LogParameter logParams;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // __RFB_LOG_WRITER_H__
|
|
|
@ -1,118 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// -=- Logger.cxx - support for the Logger and LogWriter classes
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#ifdef WIN32
|
|
||||||
#define strcasecmp _stricmp
|
|
||||||
#define vsnprintf _vsnprintf
|
|
||||||
#define HAVE_VSNPRINTF
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <rfb/Logger.h>
|
|
||||||
#include <rfb/LogWriter.h>
|
|
||||||
#include <rfb/util.h>
|
|
||||||
#include <rfb/Threading.h>
|
|
||||||
|
|
||||||
using namespace rfb;
|
|
||||||
|
|
||||||
#ifndef HAVE_VSNPRINTF
|
|
||||||
#ifdef __RFB_THREADING_IMPL
|
|
||||||
static Mutex fpLock;
|
|
||||||
#endif
|
|
||||||
static FILE* fp = 0;
|
|
||||||
int vsnprintf(char *str, size_t n, const char *format, va_list ap)
|
|
||||||
{
|
|
||||||
str[0] = 0;
|
|
||||||
if (!fp) {
|
|
||||||
// Safely create a FILE* for /dev/null if there isn't already one
|
|
||||||
#ifdef __RFB_THREADING_IMPL
|
|
||||||
Lock l(fpLock);
|
|
||||||
#endif
|
|
||||||
if (!fp)
|
|
||||||
fp = fopen("/dev/null","w");
|
|
||||||
if (!fp) return 0;
|
|
||||||
}
|
|
||||||
int len = vfprintf(fp, format, ap);
|
|
||||||
if (len <= 0) return 0;
|
|
||||||
|
|
||||||
CharArray s(len+1);
|
|
||||||
vsprintf(s.buf, format, ap);
|
|
||||||
|
|
||||||
int written = __rfbmin(len, (int)n-1);
|
|
||||||
memcpy(str, s.buf, written);
|
|
||||||
str[written] = 0;
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
Logger* Logger::loggers = 0;
|
|
||||||
|
|
||||||
Logger::Logger(const char* name) : registered(false), m_name(name), m_next(0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::~Logger() {
|
|
||||||
// *** Should remove this logger here!
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::write(int level, const char *logname, const char* format,
|
|
||||||
va_list ap)
|
|
||||||
{
|
|
||||||
// - Format the supplied data, and pass it to the
|
|
||||||
// actual log_message function
|
|
||||||
// The log level is included as a hint for loggers capable of representing
|
|
||||||
// different log levels in some way.
|
|
||||||
char buf1[4096];
|
|
||||||
vsnprintf(buf1, sizeof(buf1)-1, format, ap);
|
|
||||||
buf1[sizeof(buf1)-1] = 0;
|
|
||||||
write(level, logname, buf1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Logger::registerLogger() {
|
|
||||||
if (!registered) {
|
|
||||||
registered = true;
|
|
||||||
m_next = loggers;
|
|
||||||
loggers=this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger*
|
|
||||||
Logger::getLogger(const char* name) {
|
|
||||||
Logger* current = loggers;
|
|
||||||
while (current) {
|
|
||||||
if (strcasecmp(name, current->m_name) == 0) return current;
|
|
||||||
current = current->m_next;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Logger::listLoggers() {
|
|
||||||
Logger* current = loggers;
|
|
||||||
while (current) {
|
|
||||||
printf(" %s\n", current->m_name);
|
|
||||||
current = current->m_next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// -=- Logger.h - The Logger class.
|
|
||||||
|
|
||||||
#ifndef __RFB_LOGGER_H__
|
|
||||||
#define __RFB_LOGGER_H__
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
// Each log writer instance has a unique textual name,
|
|
||||||
// and is attached to a particular Logger instance and
|
|
||||||
// is assigned a particular log level.
|
|
||||||
|
|
||||||
namespace rfb {
|
|
||||||
|
|
||||||
class Logger {
|
|
||||||
public:
|
|
||||||
|
|
||||||
// -=- Create / Destroy a logger
|
|
||||||
|
|
||||||
Logger(const char* name);
|
|
||||||
virtual ~Logger();
|
|
||||||
|
|
||||||
// -=- Get the name of a logger
|
|
||||||
|
|
||||||
const char *getName() {return m_name;}
|
|
||||||
|
|
||||||
// -=- Write data to a log
|
|
||||||
|
|
||||||
virtual void write(int level, const char *logname, const char *text) = 0;
|
|
||||||
void write(int level, const char *logname, const char* format, va_list ap);
|
|
||||||
|
|
||||||
// -=- Register a logger
|
|
||||||
|
|
||||||
void registerLogger();
|
|
||||||
|
|
||||||
// -=- CLASS FIELDS & FUNCTIONS
|
|
||||||
|
|
||||||
static Logger* loggers;
|
|
||||||
|
|
||||||
static Logger* getLogger(const char* name);
|
|
||||||
|
|
||||||
static void listLoggers();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool registered;
|
|
||||||
const char *m_name;
|
|
||||||
Logger *m_next;
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // __RFB_LOGGER_H__
|
|
|
@ -1,127 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// -=- Logger_file.cxx - Logger instance for a file
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <rfb/util.h>
|
|
||||||
#include <rfb/Logger_file.h>
|
|
||||||
#include <rfb/Threading.h>
|
|
||||||
|
|
||||||
using namespace rfb;
|
|
||||||
|
|
||||||
|
|
||||||
// If threading is available then protect the write() operation
|
|
||||||
// from concurrent accesses
|
|
||||||
#ifdef __RFB_THREADING_IMPL
|
|
||||||
static Mutex logLock;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
Logger_File::Logger_File(const char* loggerName)
|
|
||||||
: Logger(loggerName), indent(13), width(79), m_filename(0), m_file(0),
|
|
||||||
m_lastLogTime(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger_File::~Logger_File()
|
|
||||||
{
|
|
||||||
closeFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger_File::write(int level, const char *logname, const char *message)
|
|
||||||
{
|
|
||||||
#ifdef __RFB_THREADING_IMPL
|
|
||||||
Lock l(logLock);
|
|
||||||
#endif
|
|
||||||
if (!m_file) {
|
|
||||||
if (!m_filename) return;
|
|
||||||
CharArray bakFilename(strlen(m_filename) + 1 + 4);
|
|
||||||
sprintf(bakFilename.buf, "%s.bak", m_filename);
|
|
||||||
remove(bakFilename.buf);
|
|
||||||
rename(m_filename, bakFilename.buf);
|
|
||||||
m_file = fopen(m_filename, "w+");
|
|
||||||
if (!m_file) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef _WIN32_WCE
|
|
||||||
time_t current = time(0);
|
|
||||||
if (current != m_lastLogTime) {
|
|
||||||
m_lastLogTime = current;
|
|
||||||
fprintf(m_file, "\n%s", ctime(&m_lastLogTime));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fprintf(m_file," %s:", logname);
|
|
||||||
int column = strlen(logname) + 2;
|
|
||||||
if (column < indent) {
|
|
||||||
fprintf(m_file,"%*s",indent-column,"");
|
|
||||||
column = indent;
|
|
||||||
}
|
|
||||||
while (true) {
|
|
||||||
const char* s = strchr(message, ' ');
|
|
||||||
int wordLen;
|
|
||||||
if (s) wordLen = s-message;
|
|
||||||
else wordLen = strlen(message);
|
|
||||||
|
|
||||||
if (column + wordLen + 1 > width) {
|
|
||||||
fprintf(m_file,"\n%*s",indent,"");
|
|
||||||
column = indent;
|
|
||||||
}
|
|
||||||
fprintf(m_file," %.*s",wordLen,message);
|
|
||||||
column += wordLen + 1;
|
|
||||||
message += wordLen + 1;
|
|
||||||
if (!s) break;
|
|
||||||
}
|
|
||||||
fprintf(m_file,"\n");
|
|
||||||
fflush(m_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger_File::setFilename(const char* filename)
|
|
||||||
{
|
|
||||||
closeFile();
|
|
||||||
m_filename = strDup(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger_File::setFile(FILE* file)
|
|
||||||
{
|
|
||||||
closeFile();
|
|
||||||
m_file = file;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger_File::closeFile()
|
|
||||||
{
|
|
||||||
if (m_filename) {
|
|
||||||
if (m_file) {
|
|
||||||
fclose(m_file);
|
|
||||||
m_file = 0;
|
|
||||||
}
|
|
||||||
strFree(m_filename);
|
|
||||||
m_filename = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Logger_File logger("file");
|
|
||||||
|
|
||||||
bool rfb::initFileLogger(const char* filename) {
|
|
||||||
logger.setFilename(filename);
|
|
||||||
logger.registerLogger();
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// -=- Logger_file - log to a file
|
|
||||||
|
|
||||||
#ifndef __RFB_LOGGER_FILE_H__
|
|
||||||
#define __RFB_LOGGER_FILE_H__
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <rfb/Logger.h>
|
|
||||||
|
|
||||||
namespace rfb {
|
|
||||||
|
|
||||||
class Logger_File : public Logger {
|
|
||||||
public:
|
|
||||||
Logger_File(const char* loggerName);
|
|
||||||
~Logger_File();
|
|
||||||
|
|
||||||
virtual void write(int level, const char *logname, const char *message);
|
|
||||||
void setFilename(const char* filename);
|
|
||||||
void setFile(FILE* file);
|
|
||||||
|
|
||||||
int indent;
|
|
||||||
int width;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void closeFile();
|
|
||||||
char* m_filename;
|
|
||||||
FILE* m_file;
|
|
||||||
time_t m_lastLogTime;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool initFileLogger(const char* filename);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,32 +0,0 @@
|
||||||
/* Copyright (C) 2002-2005 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// -=- Logger_stdio.cxx - Logger instances for stderr and stdout
|
|
||||||
|
|
||||||
#include <rfb/Logger_stdio.h>
|
|
||||||
|
|
||||||
using namespace rfb;
|
|
||||||
|
|
||||||
static Logger_StdIO logStdErr("stderr", stderr);
|
|
||||||
static Logger_StdIO logStdOut("stdout", stdout);
|
|
||||||
|
|
||||||
bool rfb::initStdIOLoggers() {
|
|
||||||
logStdErr.registerLogger();
|
|
||||||
logStdOut.registerLogger();
|
|
||||||
return true;
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue