Browse Source

2003-09-11 Mark McLoughlin <mark@skynet.ie>

* rdr/Exception.h, rdr/FdInStream.cxx, rdr/FdInStream.h,
          rdr/FdOutStream.cxx, rdr/FdOutStream.h, rdr/FixedMemOutStream.h,
          rdr/InStream.cxx, rdr/InStream.h, rdr/MemInStream.h,
          rdr/MemOutStream.h, rdr/NullOutStream.cxx, rdr/NullOutStream.h,
          rdr/OutStream.h, rdr/ZlibInStream.cxx, rdr/ZlibInStream.h,
          rdr/ZlibOutStream.cxx, rdr/ZlibOutStream.h, rdr/types.h,
          zrle.cxx, zrleDecode.h, zrleEncode.h: remove original
        C++ ZRLE implementation. Its been ported to C.

        * NEWS: copy the existing ChangeLog to here and make
        this a more detailed ChangeLog.
pull/1/head
markmc 19 years ago
parent
commit
9edf7e56bb
  1. 160
      ChangeLog
  2. 178
      NEWS
  3. 71
      rdr/Exception.h
  4. 251
      rdr/FdInStream.cxx
  5. 72
      rdr/FdInStream.h
  6. 113
      rdr/FdOutStream.cxx
  7. 53
      rdr/FdOutStream.h
  8. 52
      rdr/FixedMemOutStream.h
  9. 35
      rdr/InStream.cxx
  10. 143
      rdr/InStream.h
  11. 47
      rdr/MemInStream.h
  12. 82
      rdr/MemOutStream.h
  13. 60
      rdr/NullOutStream.cxx
  14. 42
      rdr/NullOutStream.h
  15. 152
      rdr/OutStream.h
  16. 121
      rdr/ZlibInStream.cxx
  17. 59
      rdr/ZlibInStream.h
  18. 144
      rdr/ZlibOutStream.cxx
  19. 57
      rdr/ZlibOutStream.h
  20. 33
      rdr/types.h
  21. 179
      zrle.cxx
  22. 241
      zrleDecode.h
  23. 310
      zrleEncode.h

160
ChangeLog

@ -1,147 +1,13 @@
Mark sent me patches to no longer need C++ for ZRLE encoding!
added --disable-cxx Option for configure
x11vnc changes from Karl Runge:
- Changed all those whimpy printf(...)'s into manly fprintf(stdxxx,...)'s.
- Added -q switch (quiet) to suppress printing all the debug-looking output.
- Added -bg switch to fork into background after everything is set up.
(checks for LIBVNCSERVER_HAVE_FORK and LIBVNCSERVER_HAVE_SETSID)
- Print this string out to stdout: 'PORT=XXXX' (usually XXXX = 5900).
Combining with -bg, easy to write a ssh/rsh wrapper with something like:
port=`ssh $host "x11vnc -bg .."` then run vncviewer based on $port output.
(tunneling the vnc traffic thru ssh a bit more messy, but doable)
- Quite a bit of code to be more careful when doing 8bpp indexed color, e.g.
not assuming NCOLORS is 256, handling 8bit TrueColor and Direct Color, etc
(I did all this probably in April, not quite clear in my mind now, but
I did test it out a fair amount on my old Sparcstation 20 wrt a user's
questions).
introduce rfbErr for Errors (Erik)
make rfbLog overridable (suggested by Erik)
don't reutrn on EINTR in WriteExact()/ReadExact() (suggested by Erik)
use AX_PREFIX_CONFIG_H to prefix constants in config.h to avoid
name clashes (also suggested by Erik)
transformed Bool, KeySym, Pixel to rfbBool, rfbKeySym, rfbPixel
(as suggested by Erik)
purged exit() calls (suggested by Erik)
fixed bug with maxRectsPerUpdate and Tight Encoding (these are incompatible)
checked sync with TightVNC 1.2.8:
viewonly/full passwords; if given a list, only the first is a full one
vncRandomBytes is a little more secure now
new weights for tight encoding
checked sync with RealVNC 3.3.7
introduced maxRectsPerUpdate
added first alpha version of LibVNCClient
added simple and simple15 example (really simple examples)
finally got around to fix configure in CVS
long standing http bug (.jar was sent twice) fixed by a friend of Karl named Mike
http options in cargs
when closing a client and no longer listening for new ones, don't crash
fixed a bug with ClientConnectionGone
endianness is checked at configure time
fixed a bug that prevented the first client from being closed
fixed that annoying "libvncserver-config --link" bug
make rfbReverseByte public (for rdp2vnc)
fixed compilation on OS X, IRIX, Solaris
install target for headers is now ${prefix}/include/rfb ("#include <rfb/rfb.h>")
renamed "sraRegion.h" to "rfbregion.h"
CARD{8,16,32} are more standard uint{8,16,32}_t now
fixed LinuxVNC colour handling
fixed a bug with pthreads where the connection was not closed
moved vncterm to main package (LinuxVNC included)
portability fixes (IRIX, OSX, Solaris)
more portable way to determine endianness and types of a given size
through autoconf based methods
0.5
rpm packaging through autoconf
autoconf'ed the whole package (including optional support for zlib,
pthreads and libjpeg as well as zrle/c++)
moved appropriate files to contrib/ and examples/ respectively
fixed long standing cargs bug (Justin "Zippy" Dearing)
Even better x11vnc from Karl J. Runge! (supports different kbd layouts of
client/server)
Better x11vnc from Karl J. Runge!
fixed severe bug (Const Kaplinsky)
got patch from Const Kaplisnky with CursorPosUpdate encoding and some Docs
sync'ed with newest RealVNC (ZRLE encoding)
a HTTP request for tunnelling was added (to fool strict web proxies)
sync'ed with TightVNC 1.2.5
0.4
support for NewFB from Const Kaplinsky
memory leaks squashed (localtime pseudo leak is still there :-)
small improvements for OSXvnc (still not working correctly)
synced with TightVNC 1.2.3
solaris compile cleanups
many x11vnc improvements
added backchannel, an encoding which needs special clients to pass
arbitrary data to the client
changes from Tim Jansen regarding multi threading and client blocking
as well as C++ compliancy
x11vnc can be controlled by starting again with special options if compiling
with LOCAL_CONTROL defined
0.3
added x11vnc, a x0rfbserver clone
regard deferUpdateTime in processEvents, if usec<0
initialize deferUpdateTime (memory "leak"!)
changed command line handling (arguments are parsed and then removed)
added very simple example: zippy
added rfbDrawLine, rfbDrawPixel
0.2
inserted a deferUpdate mechanism (X11 independent).
removed deletion of requestedRegion
added rfbLoadConsoleFont
fixed font colour handling.
added rfbSelectBox
added rfbDrawCharWithClip to allow for clipping and a background colour.
fixed font colours
added rfbFillRect
added IO function to check password.
rfbNewClient now sets the socket in the fd_set (for the select() call)
when compiling the library with HAVE_PTHREADS and an application
which includes "rfb.h" without, the structures got mixed up.
So, the pthreads section is now always at the end, and also
you get a linker error for rfbInitServer when using two different
pthread setups.
fixed two deadlocks: when setting a cursor and when using CopyRect
fixed CopyRect when copying modified regions (they lost the modified
property)
WIN32 target compiles and works for example :-)
fixed CopyRect (was using the wrong order of rectangles...)
should also work with pthreads, because copyrects are
always sent immediately (so that two consecutive copy rects
cannot conflict).
changed rfbUndrawCursor(rfbClientPtr) to (rfbScreenInfoPtr), because
this makes more sense!
flag backgroundLoop in rfbScreenInfo (if having pthreads)
CopyRect & CopyRegion were implemented.
if you use a rfbDoCopyR* function, it copies the data in the
framebuffer. If you prefer to do that yourself, use rfbScheduleCopyR*
instead; this doesn't modify the frameBuffer.
added flag to optionally not send XCursor updates, but only RichCursor,
or if that is not possible, fall back to server side cursor.
This is useful if your cursor has many nice colours.
fixed java viewer on server side:
SendCursorUpdate would send data even before the client pixel format
was set, but the java applet doesn't like the server's format.
fixed two pthread issues:
rfbSendFramebuffer was sent by a ProcessClientMessage function
(unprotected by updateMutex).
cursor coordinates were set without protection by cursorMutex
source is now equivalent to TridiaVNC 1.2.1
pthreads now work (use iterators!)
cursors are supported (rfbSetCursor automatically undraws cursor)
support for 3 bytes/pixel (slow!)
server side colourmap support
fixed rfbCloseClient not to close the connection (pthreads!)
this is done lazily (and with proper signalling).
cleaned up mac.c (from original OSXvnc); now compiles (untested!)
compiles cleanly on Linux, IRIX, BSD, Apple (Darwin)
fixed prototypes
0.1
rewrote API to use pseudo-methods instead of required functions.
lots of clean up.
Example can show symbols now.
All encodings
HTTP
2003-09-11 Mark McLoughlin <mark@skynet.ie>
* rdr/Exception.h, rdr/FdInStream.cxx, rdr/FdInStream.h,
rdr/FdOutStream.cxx, rdr/FdOutStream.h, rdr/FixedMemOutStream.h,
rdr/InStream.cxx, rdr/InStream.h, rdr/MemInStream.h,
rdr/MemOutStream.h, rdr/NullOutStream.cxx, rdr/NullOutStream.h,
rdr/OutStream.h, rdr/ZlibInStream.cxx, rdr/ZlibInStream.h,
rdr/ZlibOutStream.cxx, rdr/ZlibOutStream.h, rdr/types.h,
zrle.cxx, zrleDecode.h, zrleEncode.h: remove original
C++ ZRLE implementation. Its been ported to C.
* NEWS: copy the existing ChangeLog to here and make
this a more detailed ChangeLog.

178
NEWS

@ -1,39 +1,147 @@
Question: Why the *&!"/(§ did you change so many things in the API?
Answer: It was necessary to make this library slightly less
painful to use with other libraries.
Mark sent me patches to no longer need C++ for ZRLE encoding!
added --disable-cxx Option for configure
x11vnc changes from Karl Runge:
- Changed all those whimpy printf(...)'s into manly fprintf(stdxxx,...)'s.
Anyway, most changes are just search-and-replace:
- Added -q switch (quiet) to suppress printing all the debug-looking output.
#include "rfb.h" -> #include <rfb/rfb.h>
CARD8 -> uint8_t
CARD16 -> uint16_t
CARD32 -> uint32_t
Pixel -> rfbPixel
KeySym -> rfbKeySym
Bool -> rfbBool
- Added -bg switch to fork into background after everything is set up.
(checks for LIBVNCSERVER_HAVE_FORK and LIBVNCSERVER_HAVE_SETSID)
also, rfbUsage doesn't exit any longer, but returns FALSE
- Print this string out to stdout: 'PORT=XXXX' (usually XXXX = 5900).
Combining with -bg, easy to write a ssh/rsh wrapper with something like:
port=`ssh $host "x11vnc -bg .."` then run vncviewer based on $port output.
(tunneling the vnc traffic thru ssh a bit more messy, but doable)
If you used some constants defined in rfbconfig.h, you now
have to prefix LIBVNCSERVER_ to the constants.
Upcoming 0.6 release!
lots of bugs fixed.
Version 5.0:
The library just got autoconf && automake support as well as a real install
target!
x11vnc was much improved thanks to Karl Runge!
CursorPosUpdate encoding supported thanks to Const Kaplinsky!
ZRLE encoding, if you have a c++ compiler!
HTTP now optionally handles HTTP proxy functions to connect to the same
server only.
Of course, a lot of bugs fixed since last release...
- Quite a bit of code to be more careful when doing 8bpp indexed color, e.g.
not assuming NCOLORS is 256, handling 8bit TrueColor and Direct Color, etc
(I did all this probably in April, not quite clear in my mind now, but
I did test it out a fair amount on my old Sparcstation 20 wrt a user's
questions).
introduce rfbErr for Errors (Erik)
make rfbLog overridable (suggested by Erik)
don't reutrn on EINTR in WriteExact()/ReadExact() (suggested by Erik)
use AX_PREFIX_CONFIG_H to prefix constants in config.h to avoid
name clashes (also suggested by Erik)
transformed Bool, KeySym, Pixel to rfbBool, rfbKeySym, rfbPixel
(as suggested by Erik)
purged exit() calls (suggested by Erik)
fixed bug with maxRectsPerUpdate and Tight Encoding (these are incompatible)
checked sync with TightVNC 1.2.8:
viewonly/full passwords; if given a list, only the first is a full one
vncRandomBytes is a little more secure now
new weights for tight encoding
checked sync with RealVNC 3.3.7
introduced maxRectsPerUpdate
added first alpha version of LibVNCClient
added simple and simple15 example (really simple examples)
finally got around to fix configure in CVS
long standing http bug (.jar was sent twice) fixed by a friend of Karl named Mike
http options in cargs
when closing a client and no longer listening for new ones, don't crash
fixed a bug with ClientConnectionGone
endianness is checked at configure time
fixed a bug that prevented the first client from being closed
fixed that annoying "libvncserver-config --link" bug
make rfbReverseByte public (for rdp2vnc)
fixed compilation on OS X, IRIX, Solaris
install target for headers is now ${prefix}/include/rfb ("#include <rfb/rfb.h>")
renamed "sraRegion.h" to "rfbregion.h"
CARD{8,16,32} are more standard uint{8,16,32}_t now
fixed LinuxVNC colour handling
fixed a bug with pthreads where the connection was not closed
moved vncterm to main package (LinuxVNC included)
portability fixes (IRIX, OSX, Solaris)
more portable way to determine endianness and types of a given size
through autoconf based methods
0.5
rpm packaging through autoconf
autoconf'ed the whole package (including optional support for zlib,
pthreads and libjpeg as well as zrle/c++)
moved appropriate files to contrib/ and examples/ respectively
fixed long standing cargs bug (Justin "Zippy" Dearing)
Even better x11vnc from Karl J. Runge! (supports different kbd layouts of
client/server)
Better x11vnc from Karl J. Runge!
fixed severe bug (Const Kaplinsky)
got patch from Const Kaplisnky with CursorPosUpdate encoding and some Docs
sync'ed with newest RealVNC (ZRLE encoding)
a HTTP request for tunnelling was added (to fool strict web proxies)
sync'ed with TightVNC 1.2.5
0.4
support for NewFB from Const Kaplinsky
memory leaks squashed (localtime pseudo leak is still there :-)
small improvements for OSXvnc (still not working correctly)
synced with TightVNC 1.2.3
solaris compile cleanups
many x11vnc improvements
added backchannel, an encoding which needs special clients to pass
arbitrary data to the client
changes from Tim Jansen regarding multi threading and client blocking
as well as C++ compliancy
x11vnc can be controlled by starting again with special options if compiling
with LOCAL_CONTROL defined
0.3
added x11vnc, a x0rfbserver clone
regard deferUpdateTime in processEvents, if usec<0
initialize deferUpdateTime (memory "leak"!)
changed command line handling (arguments are parsed and then removed)
added very simple example: zippy
added rfbDrawLine, rfbDrawPixel
0.2
inserted a deferUpdate mechanism (X11 independent).
removed deletion of requestedRegion
added rfbLoadConsoleFont
fixed font colour handling.
added rfbSelectBox
added rfbDrawCharWithClip to allow for clipping and a background colour.
fixed font colours
added rfbFillRect
added IO function to check password.
rfbNewClient now sets the socket in the fd_set (for the select() call)
when compiling the library with HAVE_PTHREADS and an application
which includes "rfb.h" without, the structures got mixed up.
So, the pthreads section is now always at the end, and also
you get a linker error for rfbInitServer when using two different
pthread setups.
fixed two deadlocks: when setting a cursor and when using CopyRect
fixed CopyRect when copying modified regions (they lost the modified
property)
WIN32 target compiles and works for example :-)
fixed CopyRect (was using the wrong order of rectangles...)
should also work with pthreads, because copyrects are
always sent immediately (so that two consecutive copy rects
cannot conflict).
changed rfbUndrawCursor(rfbClientPtr) to (rfbScreenInfoPtr), because
this makes more sense!
flag backgroundLoop in rfbScreenInfo (if having pthreads)
CopyRect & CopyRegion were implemented.
if you use a rfbDoCopyR* function, it copies the data in the
framebuffer. If you prefer to do that yourself, use rfbScheduleCopyR*
instead; this doesn't modify the frameBuffer.
added flag to optionally not send XCursor updates, but only RichCursor,
or if that is not possible, fall back to server side cursor.
This is useful if your cursor has many nice colours.
fixed java viewer on server side:
SendCursorUpdate would send data even before the client pixel format
was set, but the java applet doesn't like the server's format.
fixed two pthread issues:
rfbSendFramebuffer was sent by a ProcessClientMessage function
(unprotected by updateMutex).
cursor coordinates were set without protection by cursorMutex
source is now equivalent to TridiaVNC 1.2.1
pthreads now work (use iterators!)
cursors are supported (rfbSetCursor automatically undraws cursor)
support for 3 bytes/pixel (slow!)
server side colourmap support
fixed rfbCloseClient not to close the connection (pthreads!)
this is done lazily (and with proper signalling).
cleaned up mac.c (from original OSXvnc); now compiles (untested!)
compiles cleanly on Linux, IRIX, BSD, Apple (Darwin)
fixed prototypes
0.1
rewrote API to use pseudo-methods instead of required functions.
lots of clean up.
Example can show symbols now.
All encodings
HTTP

71
rdr/Exception.h

@ -1,71 +0,0 @@
//
// Copyright (C) 2002 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, const char* e="rdr::Exception") {
str_[0] = 0;
strncat(str_, e, len-1);
if (s) {
strncat(str_, ": ", len-1-strlen(str_));
strncat(str_, s, len-1-strlen(str_));
}
}
virtual const char* str() const { return str_; }
};
struct SystemException : public Exception {
int err;
SystemException(const char* s, int err_) : err(err_) {
str_[0] = 0;
strncat(str_, "rdr::SystemException: ", len-1);
strncat(str_, s, len-1-strlen(str_));
strncat(str_, ": ", len-1-strlen(str_));
strncat(str_, strerror(err), len-1-strlen(str_));
strncat(str_, " (", len-1-strlen(str_));
char buf[20];
sprintf(buf,"%d",err);
strncat(str_, buf, len-1-strlen(str_));
strncat(str_, ")", len-1-strlen(str_));
}
};
struct TimedOut : public Exception {
TimedOut(const char* s=0) : Exception(s,"rdr::TimedOut") {}
};
struct EndOfStream : public Exception {
EndOfStream(const char* s=0) : Exception(s,"rdr::EndOfStream") {}
};
struct FrameException : public Exception {
FrameException(const char* s=0) : Exception(s,"rdr::FrameException") {}
};
}
#endif

251
rdr/FdInStream.cxx

@ -1,251 +0,0 @@
//
// Copyright (C) 2002 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 <errno.h>
#include <sys/types.h>
#ifdef _WIN32
#include <winsock.h>
#include <sys/timeb.h>
#define read(s,b,l) recv(s,(char*)b,l,0)
#undef errno
#define errno WSAGetLastError()
#else
#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>
extern "C" {
extern void rfbLog(const char *format, ...);
}
using namespace rdr;
enum { DEFAULT_BUF_SIZE = 8192,
MIN_BULK_SIZE = 1024 };
FdInStream::FdInStream(int fd_, int timeout_, int bufSize_)
: fd(fd_), timeout(timeout_), blockCallback(0), blockCallbackArg(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_, void (*blockCallback_)(void*),
void* blockCallbackArg_, int bufSize_)
: fd(fd_), timeout(0), blockCallback(blockCallback_),
blockCallbackArg(blockCallbackArg_),
timing(false), timeWaitedIn100us(5), timedKbits(0),
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
{
ptr = end = start = new U8[bufSize];
}
FdInStream::~FdInStream()
{
delete [] start;
}
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)
{
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);
end += n;
}
if (itemSize * nItems > end - ptr)
nItems = (end - ptr) / itemSize;
return nItems;
}
int FdInStream::checkReadable(int fd, int timeout)
{
while (true) {
fd_set rfds;
struct timeval tv;
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
int n = select(fd+1, &rfds, 0, 0, &tv);
if (n != -1 || errno != EINTR)
return n;
rfbLog("select returned EINTR\n");
}
}
#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 {
struct timeb tb;
ftime(&tb);
tv->tv_sec = tb.time;
tv->tv_usec = tb.millitm * 1000;
}
}
#endif
int FdInStream::readWithTimeoutOrCallback(void* buf, int len)
{
struct timeval before, after;
if (timing)
gettimeofday(&before, 0);
int n = checkReadable(fd, timeout);
if (n < 0) throw SystemException("select",errno);
if (n == 0) {
if (timeout) throw TimedOut();
if (blockCallback) (*blockCallback)(blockCallbackArg);
}
while (true) {
n = ::read(fd, buf, len);
if (n != -1 || errno != EINTR)
break;
rfbLog("read returned EINTR\n");
}
if (n < 0) throw SystemException("read",errno);
if (n == 0) throw EndOfStream();
if (timing) {
gettimeofday(&after, 0);
// rfbLog("%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) {
// rfbLog("new kbps infinite t %d k %d\n",
// newTimeWaited, newKbits);
// } else {
// rfbLog("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;
}

72
rdr/FdInStream.h

@ -1,72 +0,0 @@
//
// Copyright (C) 2002 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 FdInStream : public InStream {
public:
FdInStream(int fd, int timeout=0, int bufSize=0);
FdInStream(int fd, void (*blockCallback)(void*), void* blockCallbackArg=0,
int bufSize=0);
virtual ~FdInStream();
int getFd() { return fd; }
int pos();
void readBytes(void* data, int length);
int bytesInBuf() { return end - ptr; }
void startTiming();
void stopTiming();
unsigned int kbitsPerSecond();
unsigned int timeWaited() { return timeWaitedIn100us; }
protected:
int overrun(int itemSize, int nItems);
private:
int checkReadable(int fd, int timeout);
int readWithTimeoutOrCallback(void* buf, int len);
int fd;
int timeout;
void (*blockCallback)(void*);
void* blockCallbackArg;
bool timing;
unsigned int timeWaitedIn100us;
unsigned int timedKbits;
int bufSize;
int offset;
U8* start;
};
} // end of namespace rdr
#endif

113
rdr/FdOutStream.cxx

@ -1,113 +0,0 @@
//
// Copyright (C) 2002 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 <errno.h>
#include <sys/types.h>
#ifdef _WIN32
#include <winsock.h>
#define write(s,b,l) send(s,(const char*)b,l,0)
#undef errno
#define errno WSAGetLastError()
#else
#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 bufSize_)
: fd(fd_), 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::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 = write(fd, dataPtr, length);
if (n < 0) throw SystemException("write",errno);
length -= n;
dataPtr += n;
offset += n;
}
}
int FdOutStream::length()
{
return offset + ptr - start;
}
void FdOutStream::flush()
{
U8* sentUpTo = start;
while (sentUpTo < ptr) {
int n = write(fd, (const void*) sentUpTo, ptr - sentUpTo);
if (n < 0) throw SystemException("write",errno);
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;
}

53
rdr/FdOutStream.h

@ -1,53 +0,0 @@
//
// Copyright (C) 2002 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 bufSize=0);
virtual ~FdOutStream();
int getFd() { return fd; }
void flush();
int length();
void writeBytes(const void* data, int length);
private:
int overrun(int itemSize, int nItems);
int fd;
int bufSize;
int offset;
U8* start;
};
}
#endif

52
rdr/FixedMemOutStream.h

@ -1,52 +0,0 @@
//
// Copyright (C) 2002 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

35
rdr/InStream.cxx

@ -1,35 +0,0 @@
//
// Copyright (C) 2002 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;
}

143
rdr/InStream.h

@ -1,143 +0,0 @@
//
// Copyright (C) 2002 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).
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;
}
// 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).
virtual int overrun(int itemSize, int nItems) = 0;
protected:
InStream() {}
const U8* ptr;
const U8* end;
};
}
#endif

47
rdr/MemInStream.h

@ -1,47 +0,0 @@
//
// Copyright (C) 2002 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_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) {
ptr = start = (const U8*)data;
end = start + len;
}
int pos() { return ptr - start; }
void reposition(int pos) { ptr = start + pos; }
private:
int overrun(int itemSize, int nItems) { throw EndOfStream(); }
const U8* start;
};
}
#endif

82
rdr/MemOutStream.h

@ -1,82 +0,0 @@
//
// Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this software; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//
// A MemOutStream grows as needed when data is written to it.
//
#ifndef __RDR_MEMOUTSTREAM_H__
#define __RDR_MEMOUTSTREAM_H__
#include <rdr/OutStream.h>
namespace rdr {
class MemOutStream : public OutStream {
public:
MemOutStream(int len=1024) {
start = ptr = new U8[len];
end = start + len;
}
virtual ~MemOutStream() {
delete [] start;
}
void writeBytes(const void* data, int length) {
check(length);
memcpy(ptr, data, length);
ptr += length;
}
int length() { return ptr - start; }
void clear() { ptr = start; };
void reposition(int pos) { ptr = start + pos; }
// data() returns a pointer to the buffer.
const void* data() { return (const void*)start; }
private:
// overrun() either doubles the buffer or adds enough space for nItems of
// size itemSize bytes.
int overrun(int itemSize, int nItems) {
int len = ptr - start + itemSize * nItems;
if (len < (end - start) * 2)
len = (end - start) * 2;
U8* newStart = new U8[len];
memcpy(newStart, start, ptr - start);
ptr = newStart + (ptr - start);
delete [] start;
start = newStart;
end = newStart + len;
return nItems;
}
U8* start;
};
}
#endif

60
rdr/NullOutStream.cxx

@ -1,60 +0,0 @@
//
// Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this software; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
#include <rdr/NullOutStream.h>
#include <rdr/Exception.h>
using namespace rdr;
static const int bufferSize = 1024;
NullOutStream::NullOutStream()
: offset(0)
{
start = ptr = new U8[bufferSize];
end = start + bufferSize;
}
NullOutStream::~NullOutStream()
{
delete [] start;
}
int NullOutStream::length()
{
return offset + ptr - start;
}
void NullOutStream::writeBytes(const void* data, int length)
{
offset += length;
}
int NullOutStream::overrun(int itemSize, int nItems)
{
if (itemSize > bufferSize)
throw Exception("NullOutStream overrun: max itemSize exceeded");
offset += ptr - start;
ptr = start;
if (itemSize * nItems > end - ptr)
nItems = (end - ptr) / itemSize;
return nItems;
}

42
rdr/NullOutStream.h

@ -1,42 +0,0 @@
//
// Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this software; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
#ifndef __RDR_NULLOUTSTREAM_H__
#define __RDR_NULLOUTSTREAM_H__
#include <rdr/OutStream.h>
namespace rdr {
class NullOutStream : public OutStream {
public:
NullOutStream();
virtual ~NullOutStream();
int length();
void writeBytes(const void* data, int length);
private:
int overrun(int itemSize, int nItems);
int offset;
U8* start;
};
}
#endif

152
rdr/OutStream.h

@ -1,152 +0,0 @@
//
// Copyright (C) 2002 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]; }