Merge pull request #8 from kasmtech/stats

Stats
This commit is contained in:
Kasm 2020-10-05 15:35:18 -04:00 committed by GitHub
commit e7016550fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
105 changed files with 1175 additions and 3050 deletions

View File

@ -103,9 +103,9 @@ if(NOT DEFINED BUILD_WINVNC)
set(BUILD_WINVNC 1) set(BUILD_WINVNC 1)
endif() endif()
# Minimum version is Windows Vista/2008 (6.0) # Minimum version is Windows 7
if(WIN32) if(WIN32)
add_definitions(-D_WIN32_WINNT=0x0600) add_definitions(-D_WIN32_WINNT=0x0601)
endif() endif()
if(CMAKE_SIZEOF_VOID_P MATCHES 8) if(CMAKE_SIZEOF_VOID_P MATCHES 8)

View File

@ -26,11 +26,9 @@
Future Goals: Future Goals:
- Support uploads and downloads - Support uploads and downloads
- Json configuration file
- Pre-build Packages for all major Linux distributions - Pre-build Packages for all major Linux distributions
- CI pipelines to create releases - CI pipelines to create releases
@ -40,36 +38,39 @@ We are currently developing releasable packages for major operating sytems. The
This installer assumes you already have a desktop environment installed, but have never configured a VNC server. Use the install script found in this project under builder/install/install.sh, currently Ubuntu 18.04LTS is the only operating system with pre-compiled binaries. This installer assumes you already have a desktop environment installed, but have never configured a VNC server. Use the install script found in this project under builder/install/install.sh, currently Ubuntu 18.04LTS is the only operating system with pre-compiled binaries.
```sh ```sh
# use install script from builder/install/install.sh # install dependencies
sudo ./install.sh sudo apt-get -y install libjpeg-dev
# change owner of pre-installed cert to your user # install KasmVNC
wget https://github.com/kasmtech/KasmVNC/releases/download/v0.9.1-beta/KasmVNC_0.9.1-beta_Ubuntu_18.04.tar.gz | sudo tar xz --strip 1 -C /
# Generate an SSL Cert and change owner
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /usr/local/share/kasmvnc/certs/self.pem -out /usr/local/share/kasmvnc/certs/self.pem -subj "/C=US/ST=VA/L=None/O=None/OU=DoFu/CN=kasm/emailAddress=none@none.none"
sudo chown $USER /usr/local/share/kasmvnc/certs/self.pem sudo chown $USER /usr/local/share/kasmvnc/certs/self.pem
# create required files # start kasmvnc and set password for remote access
touch ~/.Xresources
# start kasmvnc to generate the required files and then kill it
# it will prompt to set the vnc password
vncserver :1 -interface 0.0.0.0 vncserver :1 -interface 0.0.0.0
# stop kasmvnc to make config changes
vncserver -kill :1 vncserver -kill :1
# overwrite the VNC password to nothing. KasmVNC uses HTTPS basic authentication
echo '' | vncpasswd -f > $HOME/.vnc/passwd
# modify vncstartup to launch your environment of choice, in this example LXDE # modify vncstartup to launch your environment of choice, in this example LXDE
echo '/usr/bin/lxsession -s LXDE &' >> ~/.vnc/xstartup echo '/usr/bin/lxsession -s LXDE &' >> ~/.vnc/xstartup
# The KasmVNC username is automatically set to your system username, you can mofify it if you wish
vi ~/.vnc/config
# launch KasmVNC # launch KasmVNC
vncserver $DISPLAY -depth 24 -geometry 1280x1050 -basicAuth kasm_user:password -websocketPort 8443 -cert /usr/local/share/kasmvnc/certs/self.pem -sslOnly -FrameRate=24 -interface 0.0.0.0 vncserver $DISPLAY -depth 24 -geometry 1280x1050 -websocketPort 8443 -cert /usr/local/share/kasmvnc/certs/self.pem -sslOnly -FrameRate=24 -interface 0.0.0.0
``` ```
Now navigate to your system at https://[ip-address]:8443/vnc.html
The options for vncserver in the example above: The options for vncserver in the example above:
| Argument | Description | | Argument | Description |
| -------- | ----------- | | -------- | ----------- |
| depth | Color depth, for jpeg/webp should be 24bit | | depth | Color depth, for jpeg/webp should be 24bit |
| geometry | Screensize, this will automatically be adjusted when the client connects. | | geometry | Screensize, this will automatically be adjusted when the client connects. |
| basicAuth | Username and password seperated by a semi-colon. |
| websocketPort | The port to use for the web socket. Use a high port to avoid having to run as root. | | websocketPort | The port to use for the web socket. Use a high port to avoid having to run as root. |
| cert | SSL cert to use for HTTPS | | cert | SSL cert to use for HTTPS |
| sslOnly | Disable HTTP | | sslOnly | Disable HTTP |

View File

@ -6,7 +6,7 @@ Docker CE
sudo docker build -t kasmvncbuilder:18.04 -f builder/dockerfile.build . sudo docker build -t kasmvncbuilder:18.04 -f builder/dockerfile.build .
# run the builder # run the builder
sudo docker run -v /tmp:/build kasmvncbuilder:18.04 sudo docker run -v /tmp:/build --rm kasmvncbuilder:18.04
# tar will be on /tmp of host # tar will be on /tmp of host
cp /tmp/kasmvnc*.tar.gz builder/ cp /tmp/kasmvnc*.tar.gz builder/

View File

@ -7,7 +7,7 @@
# Ubuntu applies a million patches, but here we use upstream to simplify matters # Ubuntu applies a million patches, but here we use upstream to simplify matters
cd /tmp cd /tmp
wget https://www.x.org/archive//individual/xserver/xorg-server-1.18.4.tar.bz2 wget https://www.x.org/archive/individual/xserver/xorg-server-1.19.6.tar.bz2
#git clone https://kasmweb@bitbucket.org/kasmtech/kasmvnc.git #git clone https://kasmweb@bitbucket.org/kasmtech/kasmvnc.git
#cd kasmvnc #cd kasmvnc
@ -23,10 +23,10 @@ sed -i -e '/find_package(FLTK/s@^@#@' \
cmake . cmake .
make -j5 make -j5
tar -C unix/xserver -xvf /tmp/xorg-server-1.18.4.tar.bz2 --strip-components=1 tar -C unix/xserver -xvf /tmp/xorg-server-1.19.6.tar.bz2 --strip-components=1
cd unix/xserver cd unix/xserver
patch -Np1 -i ../xserver118.patch patch -Np1 -i ../xserver119.patch
autoreconf -i autoreconf -i
# Configuring Xorg is long and has many distro-specific paths. # Configuring Xorg is long and has many distro-specific paths.
# The distro paths start after prefix and end with the font path, # The distro paths start after prefix and end with the font path,
@ -37,7 +37,8 @@ autoreconf -i
--with-xkb-output=/var/lib/xkb \ --with-xkb-output=/var/lib/xkb \
--with-xkb-bin-directory=/usr/bin \ --with-xkb-bin-directory=/usr/bin \
--with-default-font-path="/usr/share/fonts/X11/misc,/usr/share/fonts/X11/cyrillic,/usr/share/fonts/X11/100dpi/:unscaled,/usr/share/fonts/X11/75dpi/:unscaled,/usr/share/fonts/X11/Type1,/usr/share/fonts/X11/100dpi,/usr/share/fonts/X11/75dpi,built-ins" \ --with-default-font-path="/usr/share/fonts/X11/misc,/usr/share/fonts/X11/cyrillic,/usr/share/fonts/X11/100dpi/:unscaled,/usr/share/fonts/X11/75dpi/:unscaled,/usr/share/fonts/X11/Type1,/usr/share/fonts/X11/100dpi,/usr/share/fonts/X11/75dpi,built-ins" \
--with-pic --without-dtrace --disable-static --disable-dri \ --with-pic --without-dtrace --disable-dri \
--disable-static \
--disable-xinerama --disable-xvfb --disable-xnest --disable-xorg \ --disable-xinerama --disable-xvfb --disable-xnest --disable-xorg \
--disable-dmx --disable-xwin --disable-xephyr --disable-kdrive \ --disable-dmx --disable-xwin --disable-xephyr --disable-kdrive \
--disable-config-hal --disable-config-udev \ --disable-config-hal --disable-config-udev \

View File

@ -5,20 +5,22 @@ RUN sed -i 's$# deb-src$deb-src$' /etc/apt/sources.list
RUN apt-get update && \ RUN apt-get update && \
apt-get -y install sudo apt-get -y install sudo
RUN apt-get -y build-dep xorg-server libxfont-dev RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev
RUN apt-get -y install cmake git libjpeg-dev libgnutls28-dev vim wget tightvncserver RUN apt-get update && apt-get -y install cmake git libjpeg-dev libgnutls28-dev vim wget tightvncserver
RUN apt-get -y install libjpeg-dev libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev RUN apt-get update && apt-get -y install libjpeg-dev libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev
# Additions for webp # Additions for webp
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
RUN cd /tmp && tar -xzvf /tmp/libwebp-* RUN cd /tmp && tar -xzvf /tmp/libwebp-*
RUN cd /tmp/libwebp-1.0.2 && ./configure && make && make install RUN cd /tmp/libwebp-1.0.2 && \
./configure --enable-static --disable-shared && \
make && make install
# Fix for older required libs # Fix for older required libs
RUN cd /tmp && wget http://launchpadlibrarian.net/347526424/libxfont1-dev_1.5.2-4ubuntu2_amd64.deb && \ #RUN cd /tmp && wget http://launchpadlibrarian.net/347526424/libxfont1-dev_1.5.2-4ubuntu2_amd64.deb && \
wget http://launchpadlibrarian.net/347526425/libxfont1_1.5.2-4ubuntu2_amd64.deb && \ # wget http://launchpadlibrarian.net/347526425/libxfont1_1.5.2-4ubuntu2_amd64.deb && \
dpkg -i libxfont1_1.5.2-4ubuntu2_amd64.deb && \ # dpkg -i libxfont1_1.5.2-4ubuntu2_amd64.deb && \
dpkg -i libxfont1-dev_1.5.2-4ubuntu2_amd64.deb # dpkg -i libxfont1-dev_1.5.2-4ubuntu2_amd64.deb
RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo

View File

@ -1,79 +0,0 @@
set -e
OS_ID='unknown'
OS_VERSION_ID='unknown'
SUPPORTED='false'
if [[ $EUID -ne 0 ]]; then
echo "This script must ran with sudo"
exit 1
fi
function install_deps_ubuntu_18(){
# install deps and build tools
sudo apt-get update
sudo apt-get -y install libjpeg-dev libpng-dev libtiff-dev libgif-dev build-essential cmake libxfont-dev
wget http://launchpadlibrarian.net/347526424/libxfont1-dev_1.5.2-4ubuntu2_amd64.deb
wget http://launchpadlibrarian.net/347526425/libxfont1_1.5.2-4ubuntu2_amd64.deb
sudo dpkg -i libxfont1*.deb
rm /tmp/libxfont1*.deb
}
function build_webp(){
# build webp
wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
tar -xzvf /tmp/libwebp-*
cd /tmp/libwebp-1.0.2
./configure
make
sudo make install
cd /
rm -rf /tmp/libwebp*
sudo ldconfig
}
function install_kasmvnc(){
# install kasmvnc
wget -qO- https://github.com/kasmtech/KasmVNC/releases/download/v0.9.0-beta/KasmVNC_0.9.0-beta_Ubuntu_18.04.tar.gz | sudo tar xz --strip 1 -C /
#install cert
sudo mkdir /usr/local/share/kasmvnc/certs
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /usr/local/share/kasmvnc/certs/self.pem -out /usr/local/share/kasmvnc/certs/self.pem -subj "/C=US/ST=VA/L=None/O=None/OU=DoFu/CN=kasm/emailAddress=none@none.none"
}
cd /tmp
# Get the OS and version
if [ -f /etc/os-release ] ; then
OS_ID="$(awk -F= '/^ID=/{print $2}' /etc/os-release)"
OS_VERSION_ID="$(awk -F= '/^VERSION_ID/{print $2}' /etc/os-release)"
fi
if [ "${OS_ID}" == "ubuntu" ] && ( [ "${OS_VERSION_ID}" == '"16.04"' ] || [ "${OS_VERSION_ID}" == '"18.04"' ] || [ "${OS_VERSION_ID}" == '"20.04"' ]) ; then
if [ "${OS_VERSION_ID}" == '"18.04"' ] ; then
SUPPORTED='true'
install_deps_ubuntu_18
build_webp
install_kasmvnc
fi
fi
if [ "${OS_ID}" == "debian" ] && ( [ "${OS_VERSION_ID}" == '"9"' ] || [ "${OS_VERSION_ID}" == '"10"' ] ) ; then
#TODO: Add support for debian
echo 'Debian is currently not supported'
fi
if [ "${OS_ID}" == '"centos"' ] && ( [ "${OS_VERSION_ID}" == '"7"' ] || [ "${OS_VERSION_ID}" == '"8"' ] ) ; then
#TODO: Add support for Centos
echo 'CentOS is currently not supported'
fi
if [ "${SUPPORTED}" == "false" ] ; then
echo "Installation Not Supported for this Operating System. You must compile KasmVNC from source."
exit -1
fi
echo "Installation is complete"
echo "Follow the instructions to complete setup"

View File

@ -62,11 +62,11 @@ configure_file(release/maketarball.in release/maketarball)
set(TARBALL_DEPENDS vncpasswd vncconfig) set(TARBALL_DEPENDS vncpasswd vncconfig)
add_custom_target(tarball sh release/maketarball add_custom_target(tarball bash release/maketarball
DEPENDS ${TARBALL_DEPENDS} DEPENDS ${TARBALL_DEPENDS}
SOURCES release/maketarball) SOURCES release/maketarball)
add_custom_target(servertarball sh release/maketarball server add_custom_target(servertarball bash release/maketarball server
DEPENDS ${TARBALL_DEPENDS} DEPENDS ${TARBALL_DEPENDS}
SOURCES release/maketarball) SOURCES release/maketarball)

View File

@ -27,6 +27,9 @@ if(BUILD_STATIC)
# gettext is included in libc on many unix systems # gettext is included in libc on many unix systems
if(NOT LIBC_HAS_DGETTEXT) if(NOT LIBC_HAS_DGETTEXT)
set(GETTEXT_LIBRARIES "-Wl,-Bstatic -lintl -liconv -Wl,-Bdynamic") set(GETTEXT_LIBRARIES "-Wl,-Bstatic -lintl -liconv -Wl,-Bdynamic")
if(APPLE)
set(GETTEXT_LIBRARIES "${GETTEXT_LIBRARIES} -framework Carbon")
endif()
endif() endif()
if(GNUTLS_FOUND) if(GNUTLS_FOUND)
@ -44,7 +47,7 @@ if(BUILD_STATIC)
set(GNUTLS_LIBRARIES "${GNUTLS_LIBRARIES} -ltasn1") set(GNUTLS_LIBRARIES "${GNUTLS_LIBRARIES} -ltasn1")
endif() endif()
if(NETTLE_LIBRARY) if(NETTLE_LIBRARY)
set(GNUTLS_LIBRARIES "${GNUTLS_LIBRARIES} -lnettle -lhogweed -lgmp") set(GNUTLS_LIBRARIES "${GNUTLS_LIBRARIES} -lhogweed -lnettle -lgmp")
endif() endif()
if(GCRYPT_LIBRARY) if(GCRYPT_LIBRARY)
set(GNUTLS_LIBRARIES "${GNUTLS_LIBRARIES} -lgcrypt -lgpg-error") set(GNUTLS_LIBRARIES "${GNUTLS_LIBRARIES} -lgcrypt -lgpg-error")
@ -118,7 +121,7 @@ endif()
if(BUILD_STATIC_GCC) if(BUILD_STATIC_GCC)
# This ensures that we don't depend on libstdc++ or libgcc_s # This ensures that we don't depend on libstdc++ or libgcc_s
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nodefaultlibs") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nodefaultlibs")
set(STATIC_BASE_LIBRARIES "-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic") set(STATIC_BASE_LIBRARIES "")
if(ENABLE_ASAN AND NOT WIN32 AND NOT APPLE) if(ENABLE_ASAN AND NOT WIN32 AND NOT APPLE)
set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -Wl,-Bstatic -lasan -Wl,-Bdynamic -ldl -lm -lpthread") set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -Wl,-Bstatic -lasan -Wl,-Bdynamic -ldl -lm -lpthread")
endif() endif()
@ -136,7 +139,8 @@ if(BUILD_STATIC_GCC)
# these things again # these things again
set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -lmingw32 -lgcc_eh -lgcc -lmoldname -lmingwex -lmsvcrt") set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -lmingw32 -lgcc_eh -lgcc -lmoldname -lmingwex -lmsvcrt")
else() else()
set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -lgcc -lgcc_eh -lc") set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -lm -lgcc -lgcc_eh -lc")
endif() endif()
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} ${STATIC_BASE_LIBRARIES}") set(CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE} ${STATIC_BASE_LIBRARIES}")
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic ${STATIC_BASE_LIBRARIES}")
endif() endif()

View File

@ -38,11 +38,13 @@
#include <sys/un.h> #include <sys/un.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <wordexp.h>
#include "websocket.h" #include "websocket.h"
#include <network/TcpSocket.h> #include <network/TcpSocket.h>
#include <rfb/LogWriter.h> #include <rfb/LogWriter.h>
#include <rfb/Configuration.h> #include <rfb/Configuration.h>
#include <rfb/ServerCore.h>
#ifdef WIN32 #ifdef WIN32
#include <os/winerrno.h> #include <os/winerrno.h>
@ -151,8 +153,7 @@ TcpSocket::TcpSocket(const char *host, int port)
hints.ai_next = NULL; hints.ai_next = NULL;
if ((result = getaddrinfo(host, NULL, &hints, &ai)) != 0) { if ((result = getaddrinfo(host, NULL, &hints, &ai)) != 0) {
throw Exception("unable to resolve host by name: %s", throw GAIException("unable to resolve host by name", result);
gai_strerror(result));
} }
sock = -1; sock = -1;
@ -220,7 +221,7 @@ TcpSocket::TcpSocket(const char *host, int port)
if (err == 0) if (err == 0)
throw Exception("No useful address for host"); throw Exception("No useful address for host");
else else
throw SocketException("unable connect to socket", err); throw SocketException("unable to connect to socket", err);
} }
// Take proper ownership of the socket // Take proper ownership of the socket
@ -486,6 +487,13 @@ WebsocketListener::WebsocketListener(const struct sockaddr *listenaddr,
listen(internalSocket); listen(internalSocket);
settings.passwdfile = NULL;
wordexp_t wexp;
if (!wordexp(rfb::Server::kasmPasswordFile, &wexp, WRDE_NOCMD))
settings.passwdfile = strdup(wexp.we_wordv[0]);
wordfree(&wexp);
settings.basicauth = basicauth; settings.basicauth = basicauth;
settings.cert = cert; settings.cert = cert;
settings.key = ""; settings.key = "";
@ -603,8 +611,7 @@ void network::createTcpListeners(std::list<SocketListener*> *listeners,
snprintf (service, sizeof (service) - 1, "%d", port); snprintf (service, sizeof (service) - 1, "%d", port);
service[sizeof (service) - 1] = '\0'; service[sizeof (service) - 1] = '\0';
if ((result = getaddrinfo(addr, service, &hints, &ai)) != 0) if ((result = getaddrinfo(addr, service, &hints, &ai)) != 0)
throw rdr::Exception("unable to resolve listening address: %s", throw GAIException("unable to resolve listening address", result);
gai_strerror(result));
try { try {
createTcpListeners(listeners, ai); createTcpListeners(listeners, ai);
@ -612,6 +619,8 @@ void network::createTcpListeners(std::list<SocketListener*> *listeners,
freeaddrinfo(ai); freeaddrinfo(ai);
throw; throw;
} }
freeaddrinfo(ai);
} }
void network::createTcpListeners(std::list<SocketListener*> *listeners, void network::createTcpListeners(std::list<SocketListener*> *listeners,
@ -913,8 +922,7 @@ TcpFilter::Pattern TcpFilter::parsePattern(const char* p) {
} }
if ((result = getaddrinfo (p, NULL, &hints, &ai)) != 0) { if ((result = getaddrinfo (p, NULL, &hints, &ai)) != 0) {
throw Exception("unable to resolve host by name: %s", throw GAIException("unable to resolve host by name", result);
gai_strerror(result));
} }
memcpy (&pattern.address.u.sa, ai->ai_addr, ai->ai_addrlen); memcpy (&pattern.address.u.sa, ai->ai_addr, ai->ai_addrlen);

View File

@ -69,7 +69,7 @@ UnixSocket::UnixSocket(const char *path)
} }
if (result == -1) if (result == -1)
throw SocketException("unable connect to socket", err); throw SocketException("unable to connect to socket", err);
setFd(sock); setFd(sock);
} }

View File

@ -878,9 +878,11 @@ ws_ctx_t *do_handshake(int sock) {
usleep(10); usleep(10);
} }
if (strchr(settings.basicauth, ':')) { const char *colon;
if ((colon = strchr(settings.basicauth, ':'))) {
const char *hdr = strstr(handshake, "Authorization: Basic "); const char *hdr = strstr(handshake, "Authorization: Basic ");
if (!hdr) { if (!hdr) {
handler_emsg("BasicAuth required, but client didn't send any. 401 Unauth\n");
sprintf(response, "HTTP/1.1 401 Unauthorized\r\n" sprintf(response, "HTTP/1.1 401 Unauthorized\r\n"
"WWW-Authenticate: Basic realm=\"Websockify\"\r\n" "WWW-Authenticate: Basic realm=\"Websockify\"\r\n"
"\r\n"); "\r\n");
@ -892,6 +894,7 @@ ws_ctx_t *do_handshake(int sock) {
hdr += sizeof("Authorization: Basic ") - 1; hdr += sizeof("Authorization: Basic ") - 1;
const char *end = strchr(hdr, '\r'); const char *end = strchr(hdr, '\r');
if (!end || end - hdr > 256) { if (!end || end - hdr > 256) {
handler_emsg("Client sent invalid BasicAuth, dropping connection\n");
free_ws_ctx(ws_ctx); free_ws_ctx(ws_ctx);
return NULL; return NULL;
} }
@ -901,13 +904,55 @@ ws_ctx_t *do_handshake(int sock) {
tmp[len] = '\0'; tmp[len] = '\0';
len = ws_b64_pton(tmp, response, 256); len = ws_b64_pton(tmp, response, 256);
if (len <= 0 || strcmp(settings.basicauth, response)) { char authbuf[4096];
strncpy(authbuf, settings.basicauth, 4096);
authbuf[4095] = '\0';
// Do we need to read it from the file?
char *resppw = strchr(response, ':');
if (resppw && *resppw)
resppw++;
if (!colon[1] && settings.passwdfile) {
if (resppw && *resppw) {
char pwbuf[4096];
FILE *f = fopen(settings.passwdfile, "r");
if (f) {
handler_emsg("BasicAuth reading password from %s\n", settings.passwdfile);
const unsigned len = fread(pwbuf, 1, 4096, f);
fclose(f);
pwbuf[4095] = '\0';
if (len < 4096)
pwbuf[len] = '\0';
snprintf(authbuf, 4096, "%s%s", settings.basicauth, pwbuf);
authbuf[4095] = '\0';
const char *encrypted = crypt(resppw, "$5$kasm$");
*resppw = '\0';
snprintf(pwbuf, 4096, "%s%s", response, encrypted);
pwbuf[4095] = '\0';
strcpy(response, pwbuf);
} else {
fprintf(stderr, " websocket %d: Error: BasicAuth configured to read password from file %s, but the file doesn't exist\n",
wsthread_handler_id,
settings.passwdfile);
}
} else {
// Client tried an empty password, just fail them
response[0] = '\0';
}
}
if (len <= 0 || strcmp(authbuf, response)) {
handler_emsg("BasicAuth user/pw did not match\n");
sprintf(response, "HTTP/1.1 401 Forbidden\r\n" sprintf(response, "HTTP/1.1 401 Forbidden\r\n"
"\r\n"); "\r\n");
ws_send(ws_ctx, response, strlen(response)); ws_send(ws_ctx, response, strlen(response));
free_ws_ctx(ws_ctx); free_ws_ctx(ws_ctx);
return NULL; return NULL;
} }
handler_emsg("BasicAuth matched\n");
} }
//handler_msg("handshake: %s\n", handshake); //handler_msg("handshake: %s\n", handshake);

View File

@ -67,6 +67,7 @@ typedef struct {
const char *cert; const char *cert;
const char *key; const char *key;
const char *basicauth; const char *basicauth;
const char *passwdfile;
int ssl_only; int ssl_only;
const char *httpdir; const char *httpdir;
} settings_t; } settings_t;

View File

@ -31,6 +31,9 @@
#include <tchar.h> #include <tchar.h>
#include <winsock2.h> #include <winsock2.h>
#include <windows.h> #include <windows.h>
#include <ws2tcpip.h>
#else
#include <netdb.h>
#endif #endif
#include <string.h> #include <string.h>
@ -49,38 +52,46 @@ Exception::Exception(const char *format, ...) {
va_end(ap); va_end(ap);
} }
GAIException::GAIException(const char* s, int err)
: Exception("%s", s)
{
strncat(str_, ": ", len-1-strlen(str_));
#ifdef _WIN32
wchar_t *currStr = new wchar_t[len-strlen(str_)];
wcsncpy(currStr, gai_strerrorW(err), len-1-strlen(str_));
WideCharToMultiByte(CP_UTF8, 0, currStr, -1, str_+strlen(str_),
len-1-strlen(str_), 0, 0);
delete [] currStr;
#else
strncat(str_, gai_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_));
}
SystemException::SystemException(const char* s, int err_) SystemException::SystemException(const char* s, int err_)
: Exception("%s", s), err(err_) : Exception("%s", s), err(err_)
{ {
strncat(str_, ": ", len-1-strlen(str_)); strncat(str_, ": ", len-1-strlen(str_));
#ifdef _WIN32 #ifdef _WIN32
// Windows error messages are crap, so use unix ones for common errors. wchar_t *currStr = new wchar_t[len-strlen(str_)];
const char* msg = 0; FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
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); 0, err, 0, currStr, len-1-strlen(str_), 0);
#endif WideCharToMultiByte(CP_UTF8, 0, currStr, -1, str_+strlen(str_),
len-1-strlen(str_), 0, 0);
delete [] currStr;
int l = strlen(str_); int l = strlen(str_);
if ((l >= 2) && (str_[l-2] == '\r') && (str_[l-1] == '\n')) if ((l >= 2) && (str_[l-2] == '\r') && (str_[l-1] == '\n'))
str_[l-2] = 0; str_[l-2] = 0;
}
#else #else
strncat(str_, strerror(err), len-1-strlen(str_)); strncat(str_, strerror(err), len-1-strlen(str_));

View File

@ -42,6 +42,11 @@ namespace rdr {
SystemException(const char* s, int err_); SystemException(const char* s, int err_);
}; };
struct GAIException : public Exception {
int err;
GAIException(const char* s, int err_);
};
struct TimedOut : public Exception { struct TimedOut : public Exception {
TimedOut() : Exception("Timed out") {} TimedOut() : Exception("Timed out") {}
}; };

View File

@ -56,7 +56,7 @@ using namespace rdr;
enum { DEFAULT_BUF_SIZE = 8192, enum { DEFAULT_BUF_SIZE = 8192,
MIN_BULK_SIZE = 1024 }; MIN_BULK_SIZE = 1024 };
FdInStream::FdInStream(int fd_, int timeoutms_, int bufSize_, FdInStream::FdInStream(int fd_, int timeoutms_, size_t bufSize_,
bool closeWhenDone_) bool closeWhenDone_)
: fd(fd_), closeWhenDone(closeWhenDone_), : fd(fd_), closeWhenDone(closeWhenDone_),
timeoutms(timeoutms_), blockCallback(0), timeoutms(timeoutms_), blockCallback(0),
@ -67,7 +67,7 @@ FdInStream::FdInStream(int fd_, int timeoutms_, int bufSize_,
} }
FdInStream::FdInStream(int fd_, FdInStreamBlockCallback* blockCallback_, FdInStream::FdInStream(int fd_, FdInStreamBlockCallback* blockCallback_,
int bufSize_) size_t bufSize_)
: fd(fd_), timeoutms(0), blockCallback(blockCallback_), : fd(fd_), timeoutms(0), blockCallback(blockCallback_),
timing(false), timeWaitedIn100us(5), timedKbits(0), timing(false), timeWaitedIn100us(5), timedKbits(0),
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
@ -92,12 +92,12 @@ void FdInStream::setBlockCallback(FdInStreamBlockCallback* blockCallback_)
timeoutms = 0; timeoutms = 0;
} }
int FdInStream::pos() size_t FdInStream::pos()
{ {
return offset + ptr - start; return offset + ptr - start;
} }
void FdInStream::readBytes(void* data, int length) void FdInStream::readBytes(void* data, size_t length)
{ {
if (length < MIN_BULK_SIZE) { if (length < MIN_BULK_SIZE) {
InStream::readBytes(data, length); InStream::readBytes(data, length);
@ -106,7 +106,7 @@ void FdInStream::readBytes(void* data, int length)
U8* dataPtr = (U8*)data; U8* dataPtr = (U8*)data;
int n = end - ptr; size_t n = end - ptr;
if (n > length) n = length; if (n > length) n = length;
memcpy(dataPtr, ptr, n); memcpy(dataPtr, ptr, n);
@ -123,7 +123,7 @@ void FdInStream::readBytes(void* data, int length)
} }
int FdInStream::overrun(int itemSize, int nItems, bool wait) size_t FdInStream::overrun(size_t itemSize, size_t nItems, bool wait)
{ {
if (itemSize > bufSize) if (itemSize > bufSize)
throw Exception("FdInStream overrun: max itemSize exceeded"); throw Exception("FdInStream overrun: max itemSize exceeded");
@ -135,8 +135,8 @@ int FdInStream::overrun(int itemSize, int nItems, bool wait)
end -= ptr - start; end -= ptr - start;
ptr = start; ptr = start;
int bytes_to_read; size_t bytes_to_read;
while (end < start + itemSize) { while ((size_t)(end - start) < itemSize) {
bytes_to_read = start + bufSize - end; bytes_to_read = start + bufSize - end;
if (!timing) { if (!timing) {
// When not timing, we must be careful not to read too much // When not timing, we must be careful not to read too much
@ -147,13 +147,15 @@ int FdInStream::overrun(int itemSize, int nItems, bool wait)
// bytes is ineffecient. // bytes is ineffecient.
bytes_to_read = vncmin(bytes_to_read, vncmax(itemSize*nItems, 8)); bytes_to_read = vncmin(bytes_to_read, vncmax(itemSize*nItems, 8));
} }
int n = readWithTimeoutOrCallback((U8*)end, bytes_to_read, wait); size_t n = readWithTimeoutOrCallback((U8*)end, bytes_to_read, wait);
if (n == 0) return 0; if (n == 0) return 0;
end += n; end += n;
} }
if (itemSize * nItems > end - ptr) size_t nAvail;
nItems = (end - ptr) / itemSize; nAvail = (end - ptr) / itemSize;
if (nAvail < nItems)
return nAvail;
return nItems; return nItems;
} }
@ -171,7 +173,7 @@ int FdInStream::overrun(int itemSize, int nItems, bool wait)
// returning EINTR. // returning EINTR.
// //
int FdInStream::readWithTimeoutOrCallback(void* buf, int len, bool wait) size_t FdInStream::readWithTimeoutOrCallback(void* buf, size_t len, bool wait)
{ {
struct timeval before, after; struct timeval before, after;
if (timing) if (timing)

View File

@ -37,16 +37,17 @@ namespace rdr {
public: public:
FdInStream(int fd, int timeoutms=-1, int bufSize=0, FdInStream(int fd, int timeoutms=-1, size_t bufSize=0,
bool closeWhenDone_=false); bool closeWhenDone_=false);
FdInStream(int fd, FdInStreamBlockCallback* blockCallback, int bufSize=0); FdInStream(int fd, FdInStreamBlockCallback* blockCallback,
size_t bufSize=0);
virtual ~FdInStream(); virtual ~FdInStream();
void setTimeout(int timeoutms); void setTimeout(int timeoutms);
void setBlockCallback(FdInStreamBlockCallback* blockCallback); void setBlockCallback(FdInStreamBlockCallback* blockCallback);
int getFd() { return fd; } int getFd() { return fd; }
int pos(); size_t pos();
void readBytes(void* data, int length); void readBytes(void* data, size_t length);
void startTiming(); void startTiming();
void stopTiming(); void stopTiming();
@ -54,10 +55,10 @@ namespace rdr {
unsigned int timeWaited() { return timeWaitedIn100us; } unsigned int timeWaited() { return timeWaitedIn100us; }
protected: protected:
int overrun(int itemSize, int nItems, bool wait); size_t overrun(size_t itemSize, size_t nItems, bool wait);
private: private:
int readWithTimeoutOrCallback(void* buf, int len, bool wait=true); size_t readWithTimeoutOrCallback(void* buf, size_t len, bool wait=true);
int fd; int fd;
bool closeWhenDone; bool closeWhenDone;
@ -68,8 +69,8 @@ namespace rdr {
unsigned int timeWaitedIn100us; unsigned int timeWaitedIn100us;
unsigned int timedKbits; unsigned int timedKbits;
int bufSize; size_t bufSize;
int offset; size_t offset;
U8* start; U8* start;
}; };

View File

@ -51,7 +51,7 @@ using namespace rdr;
enum { DEFAULT_BUF_SIZE = 16384 }; enum { DEFAULT_BUF_SIZE = 16384 };
FdOutStream::FdOutStream(int fd_, bool blocking_, int timeoutms_, int bufSize_) FdOutStream::FdOutStream(int fd_, bool blocking_, int timeoutms_, size_t bufSize_)
: fd(fd_), blocking(blocking_), timeoutms(timeoutms_), : fd(fd_), blocking(blocking_), timeoutms(timeoutms_),
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
{ {
@ -79,7 +79,7 @@ void FdOutStream::setBlocking(bool blocking_) {
blocking = blocking_; blocking = blocking_;
} }
int FdOutStream::length() size_t FdOutStream::length()
{ {
return offset + ptr - sentUpTo; return offset + ptr - sentUpTo;
} }
@ -97,7 +97,7 @@ unsigned FdOutStream::getIdleTime()
void FdOutStream::flush() void FdOutStream::flush()
{ {
while (sentUpTo < ptr) { while (sentUpTo < ptr) {
int n = writeWithTimeout((const void*) sentUpTo, size_t n = writeWithTimeout((const void*) sentUpTo,
ptr - sentUpTo, ptr - sentUpTo,
blocking? timeoutms : 0); blocking? timeoutms : 0);
@ -120,7 +120,7 @@ void FdOutStream::flush()
} }
int FdOutStream::overrun(int itemSize, int nItems) size_t FdOutStream::overrun(size_t itemSize, size_t nItems)
{ {
if (itemSize > bufSize) if (itemSize > bufSize)
throw Exception("FdOutStream overrun: max itemSize exceeded"); throw Exception("FdOutStream overrun: max itemSize exceeded");
@ -129,10 +129,10 @@ int FdOutStream::overrun(int itemSize, int nItems)
flush(); flush();
// Still not enough space? // Still not enough space?
if (itemSize > end - ptr) { if (itemSize > (size_t)(end - ptr)) {
// Can we shuffle things around? // Can we shuffle things around?
// (don't do this if it gains us less than 25%) // (don't do this if it gains us less than 25%)
if ((sentUpTo - start > bufSize / 4) && if (((size_t)(sentUpTo - start) > bufSize / 4) &&
(itemSize < bufSize - (ptr - sentUpTo))) { (itemSize < bufSize - (ptr - sentUpTo))) {
memmove(start, sentUpTo, ptr - sentUpTo); memmove(start, sentUpTo, ptr - sentUpTo);
ptr = start + (ptr - sentUpTo); ptr = start + (ptr - sentUpTo);
@ -149,9 +149,10 @@ int FdOutStream::overrun(int itemSize, int nItems)
} }
} }
// Can we fit all the items asked for? size_t nAvail;
if (itemSize * nItems > end - ptr) nAvail = (end - ptr) / itemSize;
nItems = (end - ptr) / itemSize; if (nAvail < nItems)
return nAvail;
return nItems; return nItems;
} }
@ -166,7 +167,7 @@ int FdOutStream::overrun(int itemSize, int nItems)
// select() and send() returning EINTR. // select() and send() returning EINTR.
// //
int FdOutStream::writeWithTimeout(const void* data, int length, int timeoutms) size_t FdOutStream::writeWithTimeout(const void* data, size_t length, int timeoutms)
{ {
int n; int n;

View File

@ -34,7 +34,7 @@ namespace rdr {
public: public:
FdOutStream(int fd, bool blocking=true, int timeoutms=-1, int bufSize=0); FdOutStream(int fd, bool blocking=true, int timeoutms=-1, size_t bufSize=0);
virtual ~FdOutStream(); virtual ~FdOutStream();
void setTimeout(int timeoutms); void setTimeout(int timeoutms);
@ -42,20 +42,20 @@ namespace rdr {
int getFd() { return fd; } int getFd() { return fd; }
void flush(); void flush();
int length(); size_t length();
int bufferUsage(); int bufferUsage();
unsigned getIdleTime(); unsigned getIdleTime();
private: private:
int overrun(int itemSize, int nItems); size_t overrun(size_t itemSize, size_t nItems);
int writeWithTimeout(const void* data, int length, int timeoutms); size_t writeWithTimeout(const void* data, size_t length, int timeoutms);
int fd; int fd;
bool blocking; bool blocking;
int timeoutms; int timeoutms;
int bufSize; size_t bufSize;
int offset; size_t offset;
U8* start; U8* start;
U8* sentUpTo; U8* sentUpTo;
struct timeval lastWrite; struct timeval lastWrite;

View File

@ -48,7 +48,7 @@ void FileInStream::reset(void) {
ptr = end = b; ptr = end = b;
} }
int FileInStream::pos() size_t FileInStream::pos()
{ {
if (!file) if (!file)
throw Exception("File is not open"); throw Exception("File is not open");
@ -56,9 +56,9 @@ int FileInStream::pos()
return ftell(file) + ptr - b; return ftell(file) + ptr - b;
} }
int FileInStream::overrun(int itemSize, int nItems, bool wait) size_t FileInStream::overrun(size_t itemSize, size_t nItems, bool wait)
{ {
if (itemSize > (int)sizeof(b)) if (itemSize > sizeof(b))
throw Exception("FileInStream overrun: max itemSize exceeded"); throw Exception("FileInStream overrun: max itemSize exceeded");
if (end - ptr != 0) if (end - ptr != 0)
@ -68,7 +68,7 @@ int FileInStream::overrun(int itemSize, int nItems, bool wait)
ptr = b; ptr = b;
while (end < b + itemSize) { while ((size_t)(end - b) < itemSize) {
size_t n = fread((U8 *)end, b + sizeof(b) - end, 1, file); size_t n = fread((U8 *)end, b + sizeof(b) - end, 1, file);
if (n == 0) { if (n == 0) {
if (ferror(file)) if (ferror(file))
@ -80,8 +80,10 @@ int FileInStream::overrun(int itemSize, int nItems, bool wait)
end += b + sizeof(b) - end; end += b + sizeof(b) - end;
} }
if (itemSize * nItems > end - ptr) size_t nAvail;
nItems = (end - ptr) / itemSize; nAvail = (end - ptr) / itemSize;
if (nAvail < nItems)
return nAvail;
return nItems; return nItems;
} }

View File

@ -35,10 +35,10 @@ namespace rdr {
void reset(void); void reset(void);
int pos(); size_t pos();
protected: protected:
int overrun(int itemSize, int nItems, bool wait = true); size_t overrun(size_t itemSize, size_t nItems, bool wait = true);
private: private:
U8 b[131072]; U8 b[131072];

View File

@ -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

View File

@ -28,7 +28,7 @@ const int DEFAULT_BUF_LEN = 16384;
static inline int min(int a, int b) {return a<b ? a : b;} static inline int min(int a, int b) {return a<b ? a : b;}
HexInStream::HexInStream(InStream& is, int bufSize_) HexInStream::HexInStream(InStream& is, size_t bufSize_)
: bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_LEN), offset(0), in_stream(is) : bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_LEN), offset(0), in_stream(is)
{ {
ptr = end = start = new U8[bufSize]; ptr = end = start = new U8[bufSize];
@ -50,8 +50,8 @@ bool HexInStream::readHexAndShift(char c, int* v) {
return true; return true;
} }
bool HexInStream::hexStrToBin(const char* s, char** data, int* length) { bool HexInStream::hexStrToBin(const char* s, char** data, size_t* length) {
int l=strlen(s); size_t l=strlen(s);
if ((l % 2) == 0) { if ((l % 2) == 0) {
delete [] *data; delete [] *data;
*data = 0; *length = 0; *data = 0; *length = 0;
@ -59,7 +59,7 @@ bool HexInStream::hexStrToBin(const char* s, char** data, int* length) {
return true; return true;
*data = new char[l/2]; *data = new char[l/2];
*length = l/2; *length = l/2;
for(int i=0;i<l;i+=2) { for(size_t i=0;i<l;i+=2) {
int byte = 0; int byte = 0;
if (!readHexAndShift(s[i], &byte) || if (!readHexAndShift(s[i], &byte) ||
!readHexAndShift(s[i+1], &byte)) !readHexAndShift(s[i+1], &byte))
@ -76,11 +76,11 @@ decodeError:
} }
int HexInStream::pos() { size_t HexInStream::pos() {
return offset + ptr - start; return offset + ptr - start;
} }
int HexInStream::overrun(int itemSize, int nItems, bool wait) { size_t HexInStream::overrun(size_t itemSize, size_t nItems, bool wait) {
if (itemSize > bufSize) if (itemSize > bufSize)
throw Exception("HexInStream overrun: max itemSize exceeded"); throw Exception("HexInStream overrun: max itemSize exceeded");
@ -91,15 +91,15 @@ int HexInStream::overrun(int itemSize, int nItems, bool wait) {
offset += ptr - start; offset += ptr - start;
ptr = start; ptr = start;
while (end < ptr + itemSize) { while ((size_t)(end - ptr) < itemSize) {
int n = in_stream.check(2, 1, wait); size_t n = in_stream.check(2, 1, wait);
if (n == 0) return 0; if (n == 0) return 0;
const U8* iptr = in_stream.getptr(); const U8* iptr = in_stream.getptr();
const U8* eptr = in_stream.getend(); const U8* eptr = in_stream.getend();
int length = min((eptr - iptr)/2, start + bufSize - end); size_t length = min((eptr - iptr)/2, start + bufSize - end);
U8* optr = (U8*) end; U8* optr = (U8*) end;
for (int i=0; i<length; i++) { for (size_t i=0; i<length; i++) {
int v = 0; int v = 0;
readHexAndShift(iptr[i*2], &v); readHexAndShift(iptr[i*2], &v);
readHexAndShift(iptr[i*2+1], &v); readHexAndShift(iptr[i*2+1], &v);
@ -110,8 +110,10 @@ int HexInStream::overrun(int itemSize, int nItems, bool wait) {
end += length; end += length;
} }
if (itemSize * nItems > end - ptr) size_t nAvail;
nItems = (end - ptr) / itemSize; nAvail = (end - ptr) / itemSize;
if (nAvail < nItems)
return nAvail;
return nItems; return nItems;
} }

View File

@ -26,21 +26,21 @@ namespace rdr {
class HexInStream : public InStream { class HexInStream : public InStream {
public: public:
HexInStream(InStream& is, int bufSize=0); HexInStream(InStream& is, size_t bufSize=0);
virtual ~HexInStream(); virtual ~HexInStream();
int pos(); size_t pos();
static bool readHexAndShift(char c, int* v); static bool readHexAndShift(char c, int* v);
static bool hexStrToBin(const char* s, char** data, int* length); static bool hexStrToBin(const char* s, char** data, size_t* length);
protected: protected:
int overrun(int itemSize, int nItems, bool wait); size_t overrun(size_t itemSize, size_t nItems, bool wait);
private: private:
int bufSize; size_t bufSize;
U8* start; U8* start;
int offset; size_t offset;
InStream& in_stream; InStream& in_stream;
}; };

View File

@ -23,9 +23,9 @@ using namespace rdr;
const int DEFAULT_BUF_LEN = 16384; const int DEFAULT_BUF_LEN = 16384;
static inline int min(int a, int b) {return a<b ? a : b;} static inline size_t min(size_t a, size_t b) {return a<b ? a : b;}
HexOutStream::HexOutStream(OutStream& os, int buflen) HexOutStream::HexOutStream(OutStream& os, size_t buflen)
: out_stream(os), offset(0), bufSize(buflen ? buflen : DEFAULT_BUF_LEN) : out_stream(os), offset(0), bufSize(buflen ? buflen : DEFAULT_BUF_LEN)
{ {
if (bufSize % 2) if (bufSize % 2)
@ -48,9 +48,9 @@ char HexOutStream::intToHex(int i) {
throw rdr::Exception("intToHex failed"); throw rdr::Exception("intToHex failed");
} }
char* HexOutStream::binToHexStr(const char* data, int length) { char* HexOutStream::binToHexStr(const char* data, size_t length) {
char* buffer = new char[length*2+1]; char* buffer = new char[length*2+1];
for (int i=0; i<length; i++) { for (size_t i=0; i<length; i++) {
buffer[i*2] = intToHex((data[i] >> 4) & 15); buffer[i*2] = intToHex((data[i] >> 4) & 15);
buffer[i*2+1] = intToHex((data[i] & 15)); buffer[i*2+1] = intToHex((data[i] & 15));
if (!buffer[i*2] || !buffer[i*2+1]) { if (!buffer[i*2] || !buffer[i*2+1]) {
@ -70,9 +70,9 @@ HexOutStream::writeBuffer() {
out_stream.check(2); out_stream.check(2);
U8* optr = out_stream.getptr(); U8* optr = out_stream.getptr();
U8* oend = out_stream.getend(); U8* oend = out_stream.getend();
int length = min(ptr-pos, (oend-optr)/2); size_t length = min(ptr-pos, (oend-optr)/2);
for (int i=0; i<length; i++) { for (size_t i=0; i<length; i++) {
optr[i*2] = intToHex((pos[i] >> 4) & 0xf); optr[i*2] = intToHex((pos[i] >> 4) & 0xf);
optr[i*2+1] = intToHex(pos[i] & 0xf); optr[i*2+1] = intToHex(pos[i] & 0xf);
} }
@ -84,7 +84,7 @@ HexOutStream::writeBuffer() {
ptr = start; ptr = start;
} }
int HexOutStream::length() size_t HexOutStream::length()
{ {
return offset + ptr - start; return offset + ptr - start;
} }
@ -95,15 +95,17 @@ HexOutStream::flush() {
out_stream.flush(); out_stream.flush();
} }
int size_t
HexOutStream::overrun(int itemSize, int nItems) { HexOutStream::overrun(size_t itemSize, size_t nItems) {
if (itemSize > bufSize) if (itemSize > bufSize)
throw Exception("HexOutStream overrun: max itemSize exceeded"); throw Exception("HexOutStream overrun: max itemSize exceeded");
writeBuffer(); writeBuffer();
if (itemSize * nItems > end - ptr) size_t nAvail;
nItems = (end - ptr) / itemSize; nAvail = (end - ptr) / itemSize;
if (nAvail < nItems)
return nAvail;
return nItems; return nItems;
} }

View File

@ -26,24 +26,24 @@ namespace rdr {
class HexOutStream : public OutStream { class HexOutStream : public OutStream {
public: public:
HexOutStream(OutStream& os, int buflen=0); HexOutStream(OutStream& os, size_t buflen=0);
virtual ~HexOutStream(); virtual ~HexOutStream();
void flush(); void flush();
int length(); size_t length();
static char intToHex(int i); static char intToHex(int i);
static char* binToHexStr(const char* data, int length); static char* binToHexStr(const char* data, size_t length);
private: private:
void writeBuffer(); void writeBuffer();
int overrun(int itemSize, int nItems); size_t overrun(size_t itemSize, size_t nItems);
OutStream& out_stream; OutStream& out_stream;
U8* start; U8* start;
int offset; size_t offset;
int bufSize; size_t bufSize;
}; };
} }

View File

@ -39,24 +39,35 @@ namespace rdr {
// itemSize bytes. Returns the number of items in the buffer (up to a // 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 // 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 // for the bytes, zero is returned if the bytes are not immediately
// available. // available. If itemSize or nItems is zero, check() will return zero.
inline int check(int itemSize, int nItems=1, bool wait=true) inline size_t check(size_t itemSize, size_t nItems=1, bool wait=true)
{ {
if (ptr + itemSize * nItems > end) { size_t nAvail;
if (ptr + itemSize > end)
if (itemSize == 0 || nItems == 0)
return 0;
if (itemSize > (size_t)(end - ptr))
return overrun(itemSize, nItems, wait); return overrun(itemSize, nItems, wait);
nItems = (end - ptr) / itemSize; // itemSize cannot be zero at this point
} nAvail = (end - ptr) / itemSize;
if (nAvail < nItems)
return nAvail;
return nItems; return nItems;
} }
// checkNoWait() tries to make sure that the given number of bytes can // 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 // be read without blocking. It returns true if this is the case, false
// otherwise. The length must be "small" (less than the buffer size). // otherwise. The length must be "small" (less than the buffer size).
// If length is zero, checkNoWait() will return true.
inline bool checkNoWait(int length) { return check(length, 1, false)!=0; } inline bool checkNoWait(size_t length)
{
return length == 0 || check(length, 1, false) > 0;
}
// readU/SN() methods read unsigned and signed N-bit integers. // readU/SN() methods read unsigned and signed N-bit integers.
@ -82,24 +93,24 @@ namespace rdr {
static U32 maxStringLength; static U32 maxStringLength;
inline void skip(int bytes) { inline void skip(size_t bytes) {
while (bytes > 0) { while (bytes > 0) {
int n = check(1, bytes); size_t n = check(1, bytes);
ptr += n; ptr += n;
bytes -= n; bytes -= n;
} }
} }
// readBytes() reads an exact number of bytes. // readBytes() reads an exact number of bytes.
// If length is zero, readBytes() will return immediately.
void readBytes(void* data, int length) { void readBytes(void* data, size_t length) {
U8* dataPtr = (U8*)data; while (length > 0) {
U8* dataEnd = dataPtr + length; size_t n = check(1, length);
while (dataPtr < dataEnd) { memcpy(data, ptr, n);
int n = check(1, dataEnd - dataPtr);
memcpy(dataPtr, ptr, n);
ptr += n; ptr += n;
dataPtr += n; data = (U8*)data + n;
length -= n;
} }
} }
@ -114,7 +125,7 @@ namespace rdr {
// pos() returns the position in the stream. // pos() returns the position in the stream.
virtual int pos() = 0; virtual size_t pos() = 0;
// getptr(), getend() and setptr() are "dirty" methods which allow you to // getptr(), getend() and setptr() are "dirty" methods which allow you to
// manipulate the buffer directly. This is useful for a stream which is a // manipulate the buffer directly. This is useful for a stream which is a
@ -133,7 +144,7 @@ namespace rdr {
// instead of blocking to wait for the bytes, zero is returned if the bytes // instead of blocking to wait for the bytes, zero is returned if the bytes
// are not immediately available. // are not immediately available.
virtual int overrun(int itemSize, int nItems, bool wait=true) = 0; virtual size_t overrun(size_t itemSize, size_t nItems, bool wait=true) = 0;
protected: protected:

View File

@ -36,7 +36,7 @@ namespace rdr {
public: public:
MemInStream(const void* data, int len, bool deleteWhenDone_=false) MemInStream(const void* data, size_t len, bool deleteWhenDone_=false)
: start((const U8*)data), deleteWhenDone(deleteWhenDone_) : start((const U8*)data), deleteWhenDone(deleteWhenDone_)
{ {
ptr = start; ptr = start;
@ -48,12 +48,12 @@ namespace rdr {
delete [] start; delete [] start;
} }
int pos() { return ptr - start; } size_t pos() { return ptr - start; }
void reposition(int pos) { ptr = start + pos; } void reposition(size_t pos) { ptr = start + pos; }
private: private:
int overrun(int itemSize, int nItems, bool wait) { throw EndOfStream(); } size_t overrun(size_t itemSize, size_t nItems, bool wait) { throw EndOfStream(); }
const U8* start; const U8* start;
bool deleteWhenDone; bool deleteWhenDone;
}; };

View File

@ -23,6 +23,7 @@
#ifndef __RDR_MEMOUTSTREAM_H__ #ifndef __RDR_MEMOUTSTREAM_H__
#define __RDR_MEMOUTSTREAM_H__ #define __RDR_MEMOUTSTREAM_H__
#include <rdr/Exception.h>
#include <rdr/OutStream.h> #include <rdr/OutStream.h>
namespace rdr { namespace rdr {
@ -40,16 +41,16 @@ namespace rdr {
delete [] start; delete [] start;
} }
void writeBytes(const void* data, int length) { void writeBytes(const void* data, size_t length) {
check(length); check(length);
memcpy(ptr, data, length); memcpy(ptr, data, length);
ptr += length; ptr += length;
} }
int length() { return ptr - start; } size_t length() { return ptr - start; }
void clear() { ptr = start; }; void clear() { ptr = start; };
void clearAndZero() { memset(start, 0, ptr-start); clear(); } void clearAndZero() { memset(start, 0, ptr-start); clear(); }
void reposition(int pos) { ptr = start + pos; } void reposition(size_t pos) { ptr = start + pos; }
// data() returns a pointer to the buffer. // data() returns a pointer to the buffer.
@ -60,11 +61,14 @@ namespace rdr {
// overrun() either doubles the buffer or adds enough space for nItems of // overrun() either doubles the buffer or adds enough space for nItems of
// size itemSize bytes. // size itemSize bytes.
int overrun(int itemSize, int nItems) { size_t overrun(size_t itemSize, size_t nItems) {
int len = ptr - start + itemSize * nItems; size_t len = ptr - start + itemSize * nItems;
if (len < (end - start) * 2) if (len < (size_t)(end - start) * 2)
len = (end - start) * 2; len = (end - start) * 2;
if (len < (size_t)(end - start))
throw Exception("Overflow in MemOutStream::overrun()");
U8* newStart = new U8[len]; U8* newStart = new U8[len];
memcpy(newStart, start, ptr - start); memcpy(newStart, start, ptr - start);
ptr = newStart + (ptr - start); ptr = newStart + (ptr - start);

View File

@ -44,14 +44,17 @@ namespace rdr {
// itemSize bytes. Returns the number of items which fit (up to a maximum // itemSize bytes. Returns the number of items which fit (up to a maximum
// of nItems). // of nItems).
inline int check(int itemSize, int nItems=1) inline size_t check(size_t itemSize, size_t nItems=1)
{ {
if (ptr + itemSize * nItems > end) { size_t nAvail;
if (ptr + itemSize > end)
if (itemSize > (size_t)(end - ptr))
return overrun(itemSize, nItems); return overrun(itemSize, nItems);
nItems = (end - ptr) / itemSize; nAvail = (end - ptr) / itemSize;
} if (nAvail < nItems)
return nAvail;
return nItems; return nItems;
} }
@ -76,13 +79,13 @@ namespace rdr {
writeBytes(str, len); writeBytes(str, len);
} }
inline void pad(int bytes) { inline void pad(size_t bytes) {
while (bytes-- > 0) writeU8(0); while (bytes-- > 0) writeU8(0);
} }
inline void skip(int bytes) { inline void skip(size_t bytes) {
while (bytes > 0) { while (bytes > 0) {
int n = check(1, bytes); size_t n = check(1, bytes);
ptr += n; ptr += n;
bytes -= n; bytes -= n;
} }
@ -90,22 +93,21 @@ namespace rdr {
// writeBytes() writes an exact number of bytes. // writeBytes() writes an exact number of bytes.
void writeBytes(const void* data, int length) { void writeBytes(const void* data, size_t length) {
const U8* dataPtr = (const U8*)data; while (length > 0) {
const U8* dataEnd = dataPtr + length; size_t n = check(1, length);
while (dataPtr < dataEnd) { memcpy(ptr, data, n);
int n = check(1, dataEnd - dataPtr);
memcpy(ptr, dataPtr, n);
ptr += n; ptr += n;
dataPtr += n; data = (U8*)data + n;
length -= n;
} }
} }
// copyBytes() efficiently transfers data between streams // copyBytes() efficiently transfers data between streams
void copyBytes(InStream* is, int length) { void copyBytes(InStream* is, size_t length) {
while (length > 0) { while (length > 0) {
int n = check(1, length); size_t n = check(1, length);
is->readBytes(ptr, n); is->readBytes(ptr, n);
ptr += n; ptr += n;
length -= n; length -= n;
@ -124,7 +126,7 @@ namespace rdr {
// length() returns the length of the stream. // length() returns the length of the stream.
virtual int length() = 0; virtual size_t length() = 0;
// flush() requests that the stream be flushed. // flush() requests that the stream be flushed.
@ -145,7 +147,7 @@ namespace rdr {
// the number of items which fit (up to a maximum of nItems). itemSize is // the number of items which fit (up to a maximum of nItems). itemSize is
// supposed to be "small" (a few bytes). // supposed to be "small" (a few bytes).
virtual int overrun(int itemSize, int nItems) = 0; virtual size_t overrun(size_t itemSize, size_t nItems) = 0;
protected: protected:

View File

@ -32,7 +32,7 @@
using namespace rdr; using namespace rdr;
const int DEFAULT_BUF_LEN = 256; const size_t DEFAULT_BUF_LEN = 256;
unsigned int RandomStream::seed; unsigned int RandomStream::seed;
@ -83,11 +83,11 @@ RandomStream::~RandomStream() {
#endif #endif
} }
int RandomStream::pos() { size_t RandomStream::pos() {
return offset + ptr - start; return offset + ptr - start;
} }
int RandomStream::overrun(int itemSize, int nItems, bool wait) { size_t RandomStream::overrun(size_t itemSize, size_t nItems, bool wait) {
if (itemSize > DEFAULT_BUF_LEN) if (itemSize > DEFAULT_BUF_LEN)
throw Exception("RandomStream overrun: max itemSize exceeded"); throw Exception("RandomStream overrun: max itemSize exceeded");
@ -98,7 +98,7 @@ int RandomStream::overrun(int itemSize, int nItems, bool wait) {
offset += ptr - start; offset += ptr - start;
ptr = start; ptr = start;
int length = start + DEFAULT_BUF_LEN - end; size_t length = start + DEFAULT_BUF_LEN - end;
#ifdef RFB_HAVE_WINCRYPT #ifdef RFB_HAVE_WINCRYPT
if (provider) { if (provider) {
@ -109,7 +109,7 @@ int RandomStream::overrun(int itemSize, int nItems, bool wait) {
#else #else
#ifndef WIN32 #ifndef WIN32
if (fp) { if (fp) {
int n = fread((U8*)end, length, 1, fp); size_t n = fread((U8*)end, length, 1, fp);
if (n != 1) if (n != 1)
throw rdr::SystemException("reading /dev/urandom or /dev/random failed", throw rdr::SystemException("reading /dev/urandom or /dev/random failed",
errno); errno);
@ -119,12 +119,14 @@ int RandomStream::overrun(int itemSize, int nItems, bool wait) {
{ {
#endif #endif
#endif #endif
for (int i=0; i<length; i++) for (size_t i=0; i<length; i++)
*(U8*)end++ = (int) (256.0*rand()/(RAND_MAX+1.0)); *(U8*)end++ = (int) (256.0*rand()/(RAND_MAX+1.0));
} }
if (itemSize * nItems > end - ptr) size_t nAvail;
nItems = (end - ptr) / itemSize; nAvail = (end - ptr) / itemSize;
if (nAvail < nItems)
return nAvail;
return nItems; return nItems;
} }

View File

@ -39,14 +39,14 @@ namespace rdr {
RandomStream(); RandomStream();
virtual ~RandomStream(); virtual ~RandomStream();
int pos(); size_t pos();
protected: protected:
int overrun(int itemSize, int nItems, bool wait); size_t overrun(size_t itemSize, size_t nItems, bool wait);
private: private:
U8* start; U8* start;
int offset; size_t offset;
static unsigned int seed; static unsigned int seed;
#ifdef RFB_HAVE_WINCRYPT #ifdef RFB_HAVE_WINCRYPT

View File

@ -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

View File

@ -43,7 +43,7 @@ ssize_t TLSInStream::pull(gnutls_transport_ptr_t str, void* data, size_t size)
return -1; return -1;
} }
if (in->getend() - in->getptr() < (ptrdiff_t)size) if ((size_t)(in->getend() - in->getptr()) < size)
size = in->getend() - in->getptr(); size = in->getend() - in->getptr();
in->readBytes(data, size); in->readBytes(data, size);
@ -75,12 +75,12 @@ TLSInStream::~TLSInStream()
delete[] start; delete[] start;
} }
int TLSInStream::pos() size_t TLSInStream::pos()
{ {
return offset + ptr - start; return offset + ptr - start;
} }
int TLSInStream::overrun(int itemSize, int nItems, bool wait) size_t TLSInStream::overrun(size_t itemSize, size_t nItems, bool wait)
{ {
if (itemSize > bufSize) if (itemSize > bufSize)
throw Exception("TLSInStream overrun: max itemSize exceeded"); throw Exception("TLSInStream overrun: max itemSize exceeded");
@ -92,26 +92,30 @@ int TLSInStream::overrun(int itemSize, int nItems, bool wait)
end -= ptr - start; end -= ptr - start;
ptr = start; ptr = start;
while (end < start + itemSize) { while ((size_t)(end - start) < itemSize) {
int n = readTLS((U8*) end, start + bufSize - end, wait); size_t n = readTLS((U8*) end, start + bufSize - end, wait);
if (!wait && n == 0) if (!wait && n == 0)
return 0; return 0;
end += n; end += n;
} }
if (itemSize * nItems > end - ptr) size_t nAvail;
nItems = (end - ptr) / itemSize; nAvail = (end - ptr) / itemSize;
if (nAvail < nItems)
return nAvail;
return nItems; return nItems;
} }
int TLSInStream::readTLS(U8* buf, int len, bool wait) size_t TLSInStream::readTLS(U8* buf, size_t len, bool wait)
{ {
int n; int n;
if (gnutls_record_check_pending(session) == 0) {
n = in->check(1, 1, wait); n = in->check(1, 1, wait);
if (n == 0) if (n == 0)
return 0; return 0;
}
n = gnutls_record_recv(session, (void *) buf, len); n = gnutls_record_recv(session, (void *) buf, len);
if (n == GNUTLS_E_INTERRUPTED || n == GNUTLS_E_AGAIN) if (n == GNUTLS_E_INTERRUPTED || n == GNUTLS_E_AGAIN)

View File

@ -36,17 +36,17 @@ namespace rdr {
TLSInStream(InStream* in, gnutls_session_t session); TLSInStream(InStream* in, gnutls_session_t session);
virtual ~TLSInStream(); virtual ~TLSInStream();
int pos(); size_t pos();
private: private:
int overrun(int itemSize, int nItems, bool wait); size_t overrun(size_t itemSize, size_t nItems, bool wait);
int readTLS(U8* buf, int len, bool wait); size_t readTLS(U8* buf, size_t len, bool wait);
static ssize_t pull(gnutls_transport_ptr_t str, void* data, size_t size); static ssize_t pull(gnutls_transport_ptr_t str, void* data, size_t size);
gnutls_session_t session; gnutls_session_t session;
InStream* in; InStream* in;
int bufSize; size_t bufSize;
int offset; size_t offset;
U8* start; U8* start;
}; };
}; };

View File

@ -75,7 +75,7 @@ TLSOutStream::~TLSOutStream()
delete [] start; delete [] start;
} }
int TLSOutStream::length() size_t TLSOutStream::length()
{ {
return offset + ptr - start; return offset + ptr - start;
} }
@ -84,7 +84,7 @@ void TLSOutStream::flush()
{ {
U8* sentUpTo = start; U8* sentUpTo = start;
while (sentUpTo < ptr) { while (sentUpTo < ptr) {
int n = writeTLS(sentUpTo, ptr - sentUpTo); size_t n = writeTLS(sentUpTo, ptr - sentUpTo);
sentUpTo += n; sentUpTo += n;
offset += n; offset += n;
} }
@ -93,20 +93,22 @@ void TLSOutStream::flush()
out->flush(); out->flush();
} }
int TLSOutStream::overrun(int itemSize, int nItems) size_t TLSOutStream::overrun(size_t itemSize, size_t nItems)
{ {
if (itemSize > bufSize) if (itemSize > bufSize)
throw Exception("TLSOutStream overrun: max itemSize exceeded"); throw Exception("TLSOutStream overrun: max itemSize exceeded");
flush(); flush();
if (itemSize * nItems > end - ptr) size_t nAvail;
nItems = (end - ptr) / itemSize; nAvail = (end - ptr) / itemSize;
if (nAvail < nItems)
return nAvail;
return nItems; return nItems;
} }
int TLSOutStream::writeTLS(const U8* data, int length) size_t TLSOutStream::writeTLS(const U8* data, size_t length)
{ {
int n; int n;

View File

@ -36,20 +36,20 @@ namespace rdr {
virtual ~TLSOutStream(); virtual ~TLSOutStream();
void flush(); void flush();
int length(); size_t length();
protected: protected:
int overrun(int itemSize, int nItems); size_t overrun(size_t itemSize, size_t nItems);
private: private:
int writeTLS(const U8* data, int length); size_t writeTLS(const U8* data, size_t length);
static ssize_t push(gnutls_transport_ptr_t str, const void* data, size_t size); static ssize_t push(gnutls_transport_ptr_t str, const void* data, size_t size);
gnutls_session_t session; gnutls_session_t session;
OutStream* out; OutStream* out;
int bufSize; size_t bufSize;
U8* start; U8* start;
int offset; size_t offset;
}; };
}; };

View File

@ -26,7 +26,7 @@ using namespace rdr;
enum { DEFAULT_BUF_SIZE = 16384 }; enum { DEFAULT_BUF_SIZE = 16384 };
ZlibInStream::ZlibInStream(int bufSize_) ZlibInStream::ZlibInStream(size_t bufSize_)
: underlying(0), bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0), : underlying(0), bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0),
zs(NULL), bytesIn(0) zs(NULL), bytesIn(0)
{ {
@ -40,28 +40,28 @@ ZlibInStream::~ZlibInStream()
delete [] start; delete [] start;
} }
void ZlibInStream::setUnderlying(InStream* is, int bytesIn_) void ZlibInStream::setUnderlying(InStream* is, size_t bytesIn_)
{ {
underlying = is; underlying = is;
bytesIn = bytesIn_; bytesIn = bytesIn_;
ptr = end = start; ptr = end = start;
} }
int ZlibInStream::pos() size_t ZlibInStream::pos()
{ {
return offset + ptr - start; return offset + ptr - start;
} }
void ZlibInStream::removeUnderlying() void ZlibInStream::flushUnderlying()
{ {
ptr = end = start; ptr = end = start;
if (!underlying) return;
while (bytesIn > 0) { while (bytesIn > 0) {
decompress(true); decompress(true);
end = start; // throw away any data end = start; // throw away any data
} }
underlying = 0;
setUnderlying(NULL, 0);
} }
void ZlibInStream::reset() void ZlibInStream::reset()
@ -90,18 +90,16 @@ void ZlibInStream::init()
void ZlibInStream::deinit() void ZlibInStream::deinit()
{ {
assert(zs != NULL); assert(zs != NULL);
removeUnderlying(); setUnderlying(NULL, 0);
inflateEnd(zs); inflateEnd(zs);
delete zs; delete zs;
zs = NULL; zs = NULL;
} }
int ZlibInStream::overrun(int itemSize, int nItems, bool wait) size_t ZlibInStream::overrun(size_t itemSize, size_t nItems, bool wait)
{ {
if (itemSize > bufSize) if (itemSize > bufSize)
throw Exception("ZlibInStream overrun: max itemSize exceeded"); throw Exception("ZlibInStream overrun: max itemSize exceeded");
if (!underlying)
throw Exception("ZlibInStream overrun: no underlying stream");
if (end - ptr != 0) if (end - ptr != 0)
memmove(start, ptr, end - ptr); memmove(start, ptr, end - ptr);
@ -110,13 +108,15 @@ int ZlibInStream::overrun(int itemSize, int nItems, bool wait)
end -= ptr - start; end -= ptr - start;
ptr = start; ptr = start;
while (end - ptr < itemSize) { while ((size_t)(end - ptr) < itemSize) {
if (!decompress(wait)) if (!decompress(wait))
return 0; return 0;
} }
if (itemSize * nItems > end - ptr) size_t nAvail;
nItems = (end - ptr) / itemSize; nAvail = (end - ptr) / itemSize;
if (nAvail < nItems)
return nAvail;
return nItems; return nItems;
} }
@ -127,18 +127,21 @@ int ZlibInStream::overrun(int itemSize, int nItems, bool wait)
bool ZlibInStream::decompress(bool wait) bool ZlibInStream::decompress(bool wait)
{ {
if (!underlying)
throw Exception("ZlibInStream overrun: no underlying stream");
zs->next_out = (U8*)end; zs->next_out = (U8*)end;
zs->avail_out = start + bufSize - end; zs->avail_out = start + bufSize - end;
int n = underlying->check(1, 1, wait); size_t n = underlying->check(1, 1, wait);
if (n == 0) return false; if (n == 0) return false;
zs->next_in = (U8*)underlying->getptr(); zs->next_in = (U8*)underlying->getptr();
zs->avail_in = underlying->getend() - underlying->getptr(); zs->avail_in = underlying->getend() - underlying->getptr();
if ((int)zs->avail_in > bytesIn) if (zs->avail_in > bytesIn)
zs->avail_in = bytesIn; zs->avail_in = bytesIn;
int rc = inflate(zs, Z_SYNC_FLUSH); int rc = inflate(zs, Z_SYNC_FLUSH);
if (rc != Z_OK) { if (rc < 0) {
throw Exception("ZlibInStream: inflate failed"); throw Exception("ZlibInStream: inflate failed");
} }

View File

@ -34,12 +34,12 @@ namespace rdr {
public: public:
ZlibInStream(int bufSize=0); ZlibInStream(size_t bufSize=0);
virtual ~ZlibInStream(); virtual ~ZlibInStream();
void setUnderlying(InStream* is, int bytesIn); void setUnderlying(InStream* is, size_t bytesIn);
void removeUnderlying(); void flushUnderlying();
int pos(); size_t pos();
void reset(); void reset();
private: private:
@ -47,14 +47,14 @@ namespace rdr {
void init(); void init();
void deinit(); void deinit();
int overrun(int itemSize, int nItems, bool wait); size_t overrun(size_t itemSize, size_t nItems, bool wait);
bool decompress(bool wait); bool decompress(bool wait);
InStream* underlying; InStream* underlying;
int bufSize; size_t bufSize;
int offset; size_t offset;
z_stream_s* zs; z_stream_s* zs;
int bytesIn; size_t bytesIn;
U8* start; U8* start;
}; };

View File

@ -30,7 +30,7 @@ using namespace rdr;
enum { DEFAULT_BUF_SIZE = 16384 }; enum { DEFAULT_BUF_SIZE = 16384 };
ZlibOutStream::ZlibOutStream(OutStream* os, int bufSize_, int compressLevel) ZlibOutStream::ZlibOutStream(OutStream* os, size_t bufSize_, int compressLevel)
: underlying(os), compressionLevel(compressLevel), newLevel(compressLevel), : underlying(os), compressionLevel(compressLevel), newLevel(compressLevel),
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
{ {
@ -72,7 +72,7 @@ void ZlibOutStream::setCompressionLevel(int level)
newLevel = level; newLevel = level;
} }
int ZlibOutStream::length() size_t ZlibOutStream::length()
{ {
return offset + ptr - start; return offset + ptr - start;
} }
@ -95,7 +95,7 @@ void ZlibOutStream::flush()
ptr = start; ptr = start;
} }
int ZlibOutStream::overrun(int itemSize, int nItems) size_t ZlibOutStream::overrun(size_t itemSize, size_t nItems)
{ {
#ifdef ZLIBOUT_DEBUG #ifdef ZLIBOUT_DEBUG
fprintf(stderr,"zos overrun\n"); fprintf(stderr,"zos overrun\n");
@ -106,7 +106,7 @@ int ZlibOutStream::overrun(int itemSize, int nItems)
checkCompressionLevel(); checkCompressionLevel();
while (end - ptr < itemSize) { while ((size_t)(end - ptr) < itemSize) {
zs->next_in = start; zs->next_in = start;
zs->avail_in = ptr - start; zs->avail_in = ptr - start;
@ -127,8 +127,10 @@ int ZlibOutStream::overrun(int itemSize, int nItems)
} }
} }
if (itemSize * nItems > end - ptr) size_t nAvail;
nItems = (end - ptr) / itemSize; nAvail = (end - ptr) / itemSize;
if (nAvail < nItems)
return nAvail;
return nItems; return nItems;
} }
@ -154,7 +156,7 @@ void ZlibOutStream::deflate(int flush)
#endif #endif
rc = ::deflate(zs, flush); rc = ::deflate(zs, flush);
if (rc != Z_OK) { if (rc < 0) {
// Silly zlib returns an error if you try to flush something twice // Silly zlib returns an error if you try to flush something twice
if ((rc == Z_BUF_ERROR) && (flush != Z_NO_FLUSH)) if ((rc == Z_BUF_ERROR) && (flush != Z_NO_FLUSH))
break; break;
@ -188,7 +190,7 @@ void ZlibOutStream::checkCompressionLevel()
deflate(Z_SYNC_FLUSH); deflate(Z_SYNC_FLUSH);
rc = deflateParams (zs, newLevel, Z_DEFAULT_STRATEGY); rc = deflateParams (zs, newLevel, Z_DEFAULT_STRATEGY);
if (rc != Z_OK) { if (rc < 0) {
// The implicit flush can result in this error, caused by the // The implicit flush can result in this error, caused by the
// explicit flush we did above. It should be safe to ignore though // explicit flush we did above. It should be safe to ignore though
// as the first flush should have left things in a stable state... // as the first flush should have left things in a stable state...

View File

@ -35,25 +35,25 @@ namespace rdr {
public: public:
ZlibOutStream(OutStream* os=0, int bufSize=0, int compressionLevel=-1); ZlibOutStream(OutStream* os=0, size_t bufSize=0, int compressionLevel=-1);
virtual ~ZlibOutStream(); virtual ~ZlibOutStream();
void setUnderlying(OutStream* os); void setUnderlying(OutStream* os);
void setCompressionLevel(int level=-1); void setCompressionLevel(int level=-1);
void flush(); void flush();
int length(); size_t length();
private: private:
int overrun(int itemSize, int nItems); size_t overrun(size_t itemSize, size_t nItems);
void deflate(int flush); void deflate(int flush);
void checkCompressionLevel(); void checkCompressionLevel();
OutStream* underlying; OutStream* underlying;
int compressionLevel; int compressionLevel;
int newLevel; int newLevel;
int bufSize; size_t bufSize;
int offset; size_t offset;
z_stream_s* zs; z_stream_s* zs;
U8* start; U8* start;
}; };

View File

@ -22,7 +22,6 @@ set(RFB_SOURCES
EncCache.cxx EncCache.cxx
EncodeManager.cxx EncodeManager.cxx
Encoder.cxx Encoder.cxx
HTTPServer.cxx
HextileDecoder.cxx HextileDecoder.cxx
HextileEncoder.cxx HextileEncoder.cxx
JpegCompressor.cxx JpegCompressor.cxx

View File

@ -23,6 +23,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <strings.h>
#include <os/Mutex.h> #include <os/Mutex.h>
@ -432,6 +433,7 @@ bool StringParameter::setParam(const char* v) {
if (immutable) return true; if (immutable) return true;
if (!v) if (!v)
throw rfb::Exception("setParam(<null>) not allowed"); throw rfb::Exception("setParam(<null>) not allowed");
if (strcasecmp(getName(), "BasicAuth")) // don't log the auth info
vlog.debug("set %s(String) to %s", getName(), v); vlog.debug("set %s(String) to %s", getName(), v);
CharArray oldValue(value); CharArray oldValue(value);
value = strDup(v); value = strDup(v);
@ -454,7 +456,7 @@ StringParameter::operator const char *() const {
// -=- BinaryParameter // -=- BinaryParameter
BinaryParameter::BinaryParameter(const char* name_, const char* desc_, BinaryParameter::BinaryParameter(const char* name_, const char* desc_,
const void* v, int l, ConfigurationObject co) const void* v, size_t l, ConfigurationObject co)
: VoidParameter(name_, desc_, co), value(0), length(0), def_value((char*)v), def_length(l) { : VoidParameter(name_, desc_, co), value(0), length(0), def_value((char*)v), def_length(l) {
if (l) { if (l) {
value = new char[l]; value = new char[l];
@ -474,7 +476,7 @@ bool BinaryParameter::setParam(const char* v) {
return rdr::HexInStream::hexStrToBin(v, &value, &length); return rdr::HexInStream::hexStrToBin(v, &value, &length);
} }
void BinaryParameter::setParam(const void* v, int len) { void BinaryParameter::setParam(const void* v, size_t len) {
LOCK_CONFIG; LOCK_CONFIG;
if (immutable) return; if (immutable) return;
vlog.debug("set %s(Binary)", getName()); vlog.debug("set %s(Binary)", getName());
@ -495,7 +497,7 @@ char* BinaryParameter::getValueStr() const {
return rdr::HexOutStream::binToHexStr(value, length); return rdr::HexOutStream::binToHexStr(value, length);
} }
void BinaryParameter::getData(void** data_, int* length_) const { void BinaryParameter::getData(void** data_, size_t* length_) const {
LOCK_CONFIG; LOCK_CONFIG;
if (length_) *length_ = length; if (length_) *length_ = length;
if (data_) { if (data_) {

View File

@ -268,24 +268,25 @@ namespace rfb {
class BinaryParameter : public VoidParameter { class BinaryParameter : public VoidParameter {
public: public:
BinaryParameter(const char* name_, const char* desc_, const void* v, int l, BinaryParameter(const char* name_, const char* desc_,
const void* v, size_t l,
ConfigurationObject co=ConfGlobal); ConfigurationObject co=ConfGlobal);
using VoidParameter::setParam; using VoidParameter::setParam;
virtual ~BinaryParameter(); virtual ~BinaryParameter();
virtual bool setParam(const char* value); virtual bool setParam(const char* value);
virtual void setParam(const void* v, int l); virtual void setParam(const void* v, size_t l);
virtual char* getDefaultStr() const; virtual char* getDefaultStr() const;
virtual char* getValueStr() const; virtual char* getValueStr() const;
// getData() will return length zero if there is no data // getData() will return length zero if there is no data
// NB: data may be set to zero, OR set to a zero-length buffer // NB: data may be set to zero, OR set to a zero-length buffer
void getData(void** data, int* length) const; void getData(void** data, size_t* length) const;
protected: protected:
char* value; char* value;
int length; size_t length;
char* def_value; char* def_value;
int def_length; size_t def_length;
}; };
// -=- ParameterIterator // -=- ParameterIterator

View File

@ -31,6 +31,7 @@
#include <rfb/SMsgWriter.h> #include <rfb/SMsgWriter.h>
#include <rfb/UpdateTracker.h> #include <rfb/UpdateTracker.h>
#include <rfb/LogWriter.h> #include <rfb/LogWriter.h>
#include <rfb/Exception.h>
#include <rfb/RawEncoder.h> #include <rfb/RawEncoder.h>
#include <rfb/RREEncoder.h> #include <rfb/RREEncoder.h>
@ -154,7 +155,9 @@ static void updateMaxVideoRes(uint16_t *x, uint16_t *y) {
EncodeManager::EncodeManager(SConnection* conn_, EncCache *encCache_) : conn(conn_), EncodeManager::EncodeManager(SConnection* conn_, EncCache *encCache_) : conn(conn_),
dynamicQualityMin(-1), dynamicQualityOff(-1), dynamicQualityMin(-1), dynamicQualityOff(-1),
areaCur(0), videoDetected(false), videoTimer(this), encCache(encCache_) areaCur(0), videoDetected(false), videoTimer(this),
maxEncodingTime(0), framesSinceEncPrint(0),
encCache(encCache_)
{ {
StatsVector::iterator iter; StatsVector::iterator iter;
@ -355,9 +358,10 @@ void EncodeManager::doUpdate(bool allowLossy, const Region& changed_,
changed = changed_; changed = changed_;
gettimeofday(&start, NULL);
if (allowLossy && activeEncoders[encoderFullColour] == encoderTightWEBP) { if (allowLossy && activeEncoders[encoderFullColour] == encoderTightWEBP) {
const unsigned rate = 1024 * 1000 / rfb::Server::frameRate; const unsigned rate = 1024 * 1000 / rfb::Server::frameRate;
gettimeofday(&start, NULL);
screenArea = pb->getRect().width() * pb->getRect().height(); screenArea = pb->getRect().width() * pb->getRect().height();
screenArea *= 1024; screenArea *= 1024;
@ -400,8 +404,7 @@ void EncodeManager::doUpdate(bool allowLossy, const Region& changed_,
writeSolidRects(&changed, pb); writeSolidRects(&changed, pb);
writeRects(changed, pb, writeRects(changed, pb,
allowLossy && activeEncoders[encoderFullColour] == encoderTightWEBP ? &start, true);
&start : NULL, true);
if (!videoDetected) // In case detection happened between the calls if (!videoDetected) // In case detection happened between the calls
writeRects(cursorRegion, renderedCursor); writeRects(cursorRegion, renderedCursor);
@ -1135,6 +1138,24 @@ void EncodeManager::writeRects(const Region& changed, const PixelBuffer* pb,
checkWebpFallback(start); checkWebpFallback(start);
} }
if (start) {
encodingTime = msSince(start);
if (vlog.getLevel() >= vlog.LEVEL_DEBUG) {
framesSinceEncPrint++;
if (maxEncodingTime < encodingTime)
maxEncodingTime = encodingTime;
if (framesSinceEncPrint >= rfb::Server::frameRate) {
vlog.info("Max encoding time during the last %u frames: %u ms (limit %u, near limit %.0f)",
framesSinceEncPrint, maxEncodingTime, 1000/rfb::Server::frameRate,
1000/rfb::Server::frameRate * 0.8f);
maxEncodingTime = 0;
framesSinceEncPrint = 0;
}
}
}
if (webpTookTooLong) if (webpTookTooLong)
activeEncoders[encoderFullColour] = encoderTightJPEG; activeEncoders[encoderFullColour] = encoderTightJPEG;
@ -1494,6 +1515,11 @@ void EncodeManager::OffsetPixelBuffer::update(const PixelFormat& pf,
stride = stride_; stride = stride_;
} }
rdr::U8* EncodeManager::OffsetPixelBuffer::getBufferRW(const Rect& r, int* stride)
{
throw rfb::Exception("Invalid write attempt to OffsetPixelBuffer");
}
// Preprocessor generated, optimised methods // Preprocessor generated, optimised methods
#define BPP 8 #define BPP 8

View File

@ -68,6 +68,10 @@ namespace rfb {
const RenderedCursor* renderedCursor, const RenderedCursor* renderedCursor,
size_t maxUpdateSize); size_t maxUpdateSize);
unsigned getEncodingTime() const {
return encodingTime;
};
protected: protected:
void doUpdate(bool allowLossy, const Region& changed, void doUpdate(bool allowLossy, const Region& changed,
const Region& copied, const Point& copy_delta, const Region& copied, const Point& copy_delta,
@ -177,6 +181,8 @@ namespace rfb {
unsigned webpFallbackUs; unsigned webpFallbackUs;
unsigned webpBenchResult; unsigned webpBenchResult;
bool webpTookTooLong; bool webpTookTooLong;
unsigned encodingTime;
unsigned maxEncodingTime, framesSinceEncPrint;
EncCache *encCache; EncCache *encCache;
@ -187,6 +193,9 @@ namespace rfb {
void update(const PixelFormat& pf, int width, int height, void update(const PixelFormat& pf, int width, int height,
const rdr::U8* data_, int stride); const rdr::U8* data_, int stride);
private:
virtual rdr::U8* getBufferRW(const Rect& r, int* stride);
}; };
}; };
} }

View File

@ -1,424 +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>
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: KasmVNC/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::processSocketReadEvent(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::processSocketWriteEvent(network::Socket* sock) {
std::list<Session*>::iterator i;
for (i=sessions.begin(); i!=sessions.end(); i++) {
if ((*i)->getSock() == sock) {
try {
sock->outStream().flush();
} 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;
}

View File

@ -1,111 +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 <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);
// 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);
// processSocketReadEvent()
// The platform-specific side of the server implementation calls
// this method whenever data arrives on one of the active
// network sockets.
virtual void processSocketReadEvent(network::Socket* sock);
// processSocketWriteEvent()
// Similar to processSocketReadEvent(), but called when it is
// possible to write more data to a socket.
virtual void processSocketWriteEvent(network::Socket* sock);
// Check for socket timeouts
virtual int checkTimeouts();
// -=- 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

View File

@ -49,7 +49,7 @@ namespace rfb {
inline rdr::U8* getstart() { return start; } inline rdr::U8* getstart() { return start; }
inline int overrun(int itemSize, int nItems) { virtual inline size_t overrun(size_t itemSize, size_t nItems) {
return MemOutStream::overrun(itemSize, nItems); return MemOutStream::overrun(itemSize, nItems);
} }

View File

@ -38,7 +38,7 @@ PlainPasswd::PlainPasswd() {}
PlainPasswd::PlainPasswd(char* pwd) : CharArray(pwd) { PlainPasswd::PlainPasswd(char* pwd) : CharArray(pwd) {
} }
PlainPasswd::PlainPasswd(int len) : CharArray(len) { PlainPasswd::PlainPasswd(size_t len) : CharArray(len) {
} }
PlainPasswd::PlainPasswd(const ObfuscatedPasswd& obfPwd) : CharArray(9) { PlainPasswd::PlainPasswd(const ObfuscatedPasswd& obfPwd) : CharArray(9) {
@ -63,11 +63,11 @@ void PlainPasswd::replaceBuf(char* b) {
ObfuscatedPasswd::ObfuscatedPasswd() : length(0) { ObfuscatedPasswd::ObfuscatedPasswd() : length(0) {
} }
ObfuscatedPasswd::ObfuscatedPasswd(int len) : CharArray(len), length(len) { ObfuscatedPasswd::ObfuscatedPasswd(size_t len) : CharArray(len), length(len) {
} }
ObfuscatedPasswd::ObfuscatedPasswd(const PlainPasswd& plainPwd) : CharArray(8), length(8) { ObfuscatedPasswd::ObfuscatedPasswd(const PlainPasswd& plainPwd) : CharArray(8), length(8) {
int l = strlen(plainPwd.buf), i; size_t l = strlen(plainPwd.buf), i;
for (i=0; i<8; i++) for (i=0; i<8; i++)
buf[i] = i<l ? plainPwd.buf[i] : 0; buf[i] = i<l ? plainPwd.buf[i] : 0;
deskey(d3desObfuscationKey, EN0); deskey(d3desObfuscationKey, EN0);

View File

@ -28,7 +28,7 @@ namespace rfb {
public: public:
PlainPasswd(); PlainPasswd();
PlainPasswd(char* pwd); PlainPasswd(char* pwd);
PlainPasswd(int len); PlainPasswd(size_t len);
PlainPasswd(const ObfuscatedPasswd& obfPwd); PlainPasswd(const ObfuscatedPasswd& obfPwd);
~PlainPasswd(); ~PlainPasswd();
void replaceBuf(char* b); void replaceBuf(char* b);
@ -37,10 +37,10 @@ namespace rfb {
class ObfuscatedPasswd : public CharArray { class ObfuscatedPasswd : public CharArray {
public: public:
ObfuscatedPasswd(); ObfuscatedPasswd();
ObfuscatedPasswd(int l); ObfuscatedPasswd(size_t l);
ObfuscatedPasswd(const PlainPasswd& plainPwd); ObfuscatedPasswd(const PlainPasswd& plainPwd);
~ObfuscatedPasswd(); ~ObfuscatedPasswd();
int length; size_t length;
}; };
} }

View File

@ -205,6 +205,12 @@ bool PixelFormat::is888(void) const
return false; return false;
if (blueMax != 255) if (blueMax != 255)
return false; return false;
if ((redShift & 0x7) != 0)
return false;
if ((greenShift & 0x7) != 0)
return false;
if ((blueShift & 0x7) != 0)
return false;
return true; return true;
} }
@ -678,7 +684,14 @@ bool PixelFormat::isSane(void)
return false; return false;
totalBits = bits(redMax) + bits(greenMax) + bits(blueMax); totalBits = bits(redMax) + bits(greenMax) + bits(blueMax);
if (totalBits > bpp) if (totalBits > depth)
return false;
if ((bits(redMax) + redShift) > bpp)
return false;
if ((bits(greenMax) + greenShift) > bpp)
return false;
if ((bits(blueMax) + blueShift) > bpp)
return false; return false;
if (((redMax << redShift) & (greenMax << greenShift)) != 0) if (((redMax << redShift) & (greenMax << greenShift)) != 0)

View File

@ -54,6 +54,8 @@ namespace rfb {
virtual void enableContinuousUpdates(bool enable, virtual void enableContinuousUpdates(bool enable,
int x, int y, int w, int h) = 0; int x, int y, int w, int h) = 0;
virtual void sendStats() = 0;
// InputHandler interface // InputHandler interface
// The InputHandler methods will be called for the corresponding messages. // The InputHandler methods will be called for the corresponding messages.

View File

@ -74,6 +74,9 @@ void SMsgReader::readMsg()
case msgTypeClientFence: case msgTypeClientFence:
readFence(); readFence();
break; break;
case msgTypeRequestStats:
readRequestStats();
break;
case msgTypeKeyEvent: case msgTypeKeyEvent:
readKeyEvent(); readKeyEvent();
break; break;
@ -236,6 +239,12 @@ void SMsgReader::readClientCutText()
handler->clientCutText(ca.buf, len); handler->clientCutText(ca.buf, len);
} }
void SMsgReader::readRequestStats()
{
is->skip(3);
handler->sendStats();
}
void SMsgReader::readQEMUMessage() void SMsgReader::readQEMUMessage()
{ {
int subType = is->readU8(); int subType = is->readU8();

View File

@ -55,6 +55,7 @@ namespace rfb {
void readKeyEvent(); void readKeyEvent();
void readPointerEvent(); void readPointerEvent();
void readClientCutText(); void readClientCutText();
void readRequestStats();
void readQEMUMessage(); void readQEMUMessage();
void readQEMUKeyEvent(); void readQEMUKeyEvent();

View File

@ -88,6 +88,15 @@ void SMsgWriter::writeServerCutText(const char* str, int len)
endMsg(); endMsg();
} }
void SMsgWriter::writeStats(const char* str, int len)
{
startMsg(msgTypeStats);
os->pad(3);
os->writeU32(len);
os->writeBytes(str, len);
endMsg();
}
void SMsgWriter::writeFence(rdr::U32 flags, unsigned len, const char data[]) void SMsgWriter::writeFence(rdr::U32 flags, unsigned len, const char data[])
{ {
if (!cp->supportsFence) if (!cp->supportsFence)

View File

@ -55,6 +55,7 @@ namespace rfb {
// writeBell() and writeServerCutText() do the obvious thing. // writeBell() and writeServerCutText() do the obvious thing.
void writeBell(); void writeBell();
void writeServerCutText(const char* str, int len); void writeServerCutText(const char* str, int len);
void writeStats(const char* str, int len);
// writeFence() sends a new fence request or response to the client. // writeFence() sends a new fence request or response to the client.
void writeFence(rdr::U32 flags, unsigned len, const char data[]); void writeFence(rdr::U32 flags, unsigned len, const char data[]);

View File

@ -191,6 +191,11 @@ rfb::BoolParameter rfb::Server::printVideoArea
"Print the detected video area % value.", "Print the detected video area % value.",
false); false);
rfb::StringParameter rfb::Server::kasmPasswordFile
("KasmPasswordFile",
"Password file for BasicAuth, created with the kasmvncpasswd utility.",
"~/.kasmpasswd");
static void bandwidthPreset() { static void bandwidthPreset() {
rfb::Server::dynamicQualityMin.setParam(2); rfb::Server::dynamicQualityMin.setParam(2);
rfb::Server::dynamicQualityMax.setParam(9); rfb::Server::dynamicQualityMax.setParam(9);

View File

@ -56,6 +56,7 @@ namespace rfb {
static IntParameter videoOutTime; static IntParameter videoOutTime;
static IntParameter videoArea; static IntParameter videoArea;
static IntParameter videoScaling; static IntParameter videoScaling;
static StringParameter kasmPasswordFile;
static BoolParameter printVideoArea; static BoolParameter printVideoArea;
static BoolParameter protocol3_3; static BoolParameter protocol3_3;
static BoolParameter alwaysShared; static BoolParameter alwaysShared;

View File

@ -340,7 +340,8 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,
zis[streamId].readBytes(netbuf, dataSize); zis[streamId].readBytes(netbuf, dataSize);
zis[streamId].removeUnderlying(); zis[streamId].flushUnderlying();
zis[streamId].setUnderlying(NULL, 0);
delete ms; delete ms;
bufptr = netbuf; bufptr = netbuf;

View File

@ -21,11 +21,7 @@
#define __RFB_TIMER_H__ #define __RFB_TIMER_H__
#include <list> #include <list>
#ifdef WIN32
#include <winsock2.h>
#else
#include <sys/time.h> #include <sys/time.h>
#endif
namespace rfb { namespace rfb {

View File

@ -53,7 +53,8 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
fenceDataLen(0), fenceData(NULL), congestionTimer(this), fenceDataLen(0), fenceData(NULL), congestionTimer(this),
losslessTimer(this), kbdLogTimer(this), server(server_), updates(false), losslessTimer(this), kbdLogTimer(this), server(server_), updates(false),
updateRenderedCursor(false), removeRenderedCursor(false), updateRenderedCursor(false), removeRenderedCursor(false),
continuousUpdates(false), encodeManager(this, &server_->encCache), pointerEventTime(0), continuousUpdates(false), encodeManager(this, &server_->encCache),
pointerEventTime(0),
clientHasCursor(false), clientHasCursor(false),
accessRights(AccessDefault), startTime(time(0)) accessRights(AccessDefault), startTime(time(0))
{ {
@ -61,6 +62,9 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
peerEndpoint.buf = sock->getPeerEndpoint(); peerEndpoint.buf = sock->getPeerEndpoint();
VNCServerST::connectionsLog.write(1,"accepted: %s", peerEndpoint.buf); VNCServerST::connectionsLog.write(1,"accepted: %s", peerEndpoint.buf);
memset(bstats_total, 0, sizeof(bstats_total));
gettimeofday(&connStart, NULL);
// Configure the socket // Configure the socket
setSocketTimeouts(); setSocketTimeouts();
lastEventTime = time(0); lastEventTime = time(0);
@ -1037,6 +1041,14 @@ bool VNCSConnectionST::isCongested()
if (eta >= 0) if (eta >= 0)
congestionTimer.start(eta); congestionTimer.start(eta);
if (eta > 1000 / rfb::Server::frameRate) {
struct timeval now;
gettimeofday(&now, NULL);
bstats[BS_NET_SLOW].push_back(now);
bstats_total[BS_NET_SLOW]++;
}
return true; return true;
} }
@ -1083,6 +1095,11 @@ void VNCSConnectionST::writeFramebufferUpdate()
sock->cork(false); sock->cork(false);
congestion.updatePosition(sock->outStream().length()); congestion.updatePosition(sock->outStream().length());
struct timeval now;
gettimeofday(&now, NULL);
bstats[BS_FRAME].push_back(now);
bstats_total[BS_FRAME]++;
} }
void VNCSConnectionST::writeNoDataUpdate() void VNCSConnectionST::writeNoDataUpdate()
@ -1236,6 +1253,27 @@ void VNCSConnectionST::writeDataUpdate()
copypassed.clear(); copypassed.clear();
gettimeofday(&lastRealUpdate, NULL); gettimeofday(&lastRealUpdate, NULL);
losslessTimer.start(losslessThreshold); losslessTimer.start(losslessThreshold);
const unsigned ms = encodeManager.getEncodingTime();
const unsigned limit = 1000 / rfb::Server::frameRate;
if (ms >= limit) {
bstats[BS_CPU_SLOW].push_back(lastRealUpdate);
bstats_total[BS_CPU_SLOW]++;
// If it was several frames' worth, add several so as to react faster
int i = ms / limit;
i--;
for (; i > 0; i--) {
bstats[BS_CPU_SLOW].push_back(lastRealUpdate);
bstats_total[BS_CPU_SLOW]++;
bstats[BS_FRAME].push_back(lastRealUpdate);
bstats_total[BS_FRAME]++;
}
} else if (ms >= limit * 0.8f) {
bstats[BS_CPU_CLOSE].push_back(lastRealUpdate);
bstats_total[BS_CPU_CLOSE]++;
}
} else { } else {
encodeManager.writeLosslessRefresh(req, server->getPixelBuffer(), encodeManager.writeLosslessRefresh(req, server->getPixelBuffer(),
cursor, maxUpdateSize); cursor, maxUpdateSize);
@ -1265,6 +1303,60 @@ void VNCSConnectionST::screenLayoutChange(rdr::U16 reason)
cp.screenLayout); cp.screenLayout);
} }
static const unsigned recentSecs = 10;
static void pruneStatList(std::list<struct timeval> &list, const struct timeval &now) {
std::list<struct timeval>::iterator it;
for (it = list.begin(); it != list.end(); ) {
if ((*it).tv_sec + recentSecs < now.tv_sec)
it = list.erase(it);
else
it++;
}
}
void VNCSConnectionST::sendStats() {
char buf[1024];
struct timeval now;
// Prune too old stats from the recent lists
gettimeofday(&now, NULL);
pruneStatList(bstats[BS_CPU_CLOSE], now);
pruneStatList(bstats[BS_CPU_SLOW], now);
pruneStatList(bstats[BS_NET_SLOW], now);
pruneStatList(bstats[BS_FRAME], now);
const unsigned minuteframes = bstats[BS_FRAME].size();
// Calculate stats
float cpu_recent = bstats[BS_CPU_SLOW].size() + bstats[BS_CPU_CLOSE].size() * 0.2f;
cpu_recent /= minuteframes;
float cpu_total = bstats_total[BS_CPU_SLOW] + bstats_total[BS_CPU_CLOSE] * 0.2f;
cpu_total /= bstats_total[BS_FRAME];
float net_recent = bstats[BS_NET_SLOW].size();
net_recent /= minuteframes;
if (net_recent > 1)
net_recent = 1;
float net_total = bstats_total[BS_NET_SLOW];
net_total /= bstats_total[BS_FRAME];
if (net_total > 1)
net_total = 1;
#define ten(x) (10 - x * 10.0f)
sprintf(buf, "[ %.1f, %.1f, %.1f, %.1f ]",
ten(cpu_recent), ten(cpu_total),
ten(net_recent), ten(net_total));
#undef ten
vlog.info("Sending client stats:\n%s\n", buf);
writer()->writeStats(buf, strlen(buf));
}
// setCursor() is called whenever the cursor has changed shape or pixel format. // setCursor() is called whenever the cursor has changed shape or pixel format.
// If the client supports local cursor then it will arrange for the cursor to // If the client supports local cursor then it will arrange for the cursor to

View File

@ -178,6 +178,8 @@ namespace rfb {
virtual void supportsContinuousUpdates(); virtual void supportsContinuousUpdates();
virtual void supportsLEDState(); virtual void supportsLEDState();
virtual void sendStats();
// setAccessRights() allows a security package to limit the access rights // setAccessRights() allows a security package to limit the access rights
// of a VNCSConnectioST to the server. These access rights are applied // of a VNCSConnectioST to the server. These access rights are applied
// such that the actual rights granted are the minimum of the server's // such that the actual rights granted are the minimum of the server's
@ -235,6 +237,18 @@ namespace rfb {
std::map<rdr::U32, rdr::U32> pressedKeys; std::map<rdr::U32, rdr::U32> pressedKeys;
enum {
BS_CPU_CLOSE,
BS_CPU_SLOW,
BS_NET_SLOW,
BS_FRAME,
BS_NUM
};
std::list<struct timeval> bstats[BS_NUM]; // Bottleneck stats
rdr::U64 bstats_total[BS_NUM];
struct timeval connStart;
time_t lastEventTime; time_t lastEventTime;
time_t pointerEventTime; time_t pointerEventTime;
Point pointerEventPos; Point pointerEventPos;

View File

@ -28,6 +28,9 @@ namespace rfb {
const int msgTypeEndOfContinuousUpdates = 150; const int msgTypeEndOfContinuousUpdates = 150;
// kasm
const int msgTypeStats = 178;
const int msgTypeServerFence = 248; const int msgTypeServerFence = 248;
// client to server // client to server
@ -42,6 +45,9 @@ namespace rfb {
const int msgTypeEnableContinuousUpdates = 150; const int msgTypeEnableContinuousUpdates = 150;
// kasm
const int msgTypeRequestStats = 178;
const int msgTypeClientFence = 248; const int msgTypeClientFence = 248;
const int msgTypeSetDesktopSize = 251; const int msgTypeSetDesktopSize = 251;

View File

@ -56,15 +56,17 @@ TightDecoder::FilterGradient24(const rdr::U8 *inbuf,
int rectWidth = r.width(); int rectWidth = r.width();
for (y = 0; y < rectHeight; y++) { for (y = 0; y < rectHeight; y++) {
for (x = 0; x < rectWidth; x++) {
/* First pixel in a row */ /* First pixel in a row */
if (x == 0) {
for (c = 0; c < 3; c++) { for (c = 0; c < 3; c++) {
pix[c] = inbuf[y*rectWidth*3+c] + prevRow[c]; pix[c] = inbuf[y*rectWidth*3+c] + prevRow[c];
thisRow[c] = pix[c]; thisRow[c] = pix[c];
} }
pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride], pix, 1); pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride], pix, 1);
continue;
}
/* Remaining pixels of a row */
for (x = 1; x < rectWidth; x++) {
for (c = 0; c < 3; c++) { for (c = 0; c < 3; c++) {
est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c]; est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c];
if (est[c] > 0xff) { if (est[c] > 0xff) {
@ -103,7 +105,9 @@ void TightDecoder::FilterGradient(const rdr::U8* inbuf,
int rectWidth = r.width(); int rectWidth = r.width();
for (y = 0; y < rectHeight; y++) { for (y = 0; y < rectHeight; y++) {
for (x = 0; x < rectWidth; x++) {
/* First pixel in a row */ /* First pixel in a row */
if (x == 0) {
pf.rgbFromBuffer(pix, &inbuf[y*rectWidth], 1); pf.rgbFromBuffer(pix, &inbuf[y*rectWidth], 1);
for (c = 0; c < 3; c++) for (c = 0; c < 3; c++)
pix[c] += prevRow[c]; pix[c] += prevRow[c];
@ -112,8 +116,9 @@ void TightDecoder::FilterGradient(const rdr::U8* inbuf,
pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride], pix, 1); pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride], pix, 1);
/* Remaining pixels of a row */ continue;
for (x = 1; x < rectWidth; x++) { }
for (c = 0; c < 3; c++) { for (c = 0; c < 3; c++) {
est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c]; est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c];
if (est[c] > 255) { if (est[c] > 255) {

View File

@ -49,8 +49,8 @@ namespace rfb {
public: public:
CharArray() : buf(0) {} CharArray() : buf(0) {}
CharArray(char* str) : buf(str) {} // note: assumes ownership CharArray(char* str) : buf(str) {} // note: assumes ownership
CharArray(int len) { CharArray(size_t len) {
buf = new char[len]; buf = new char[len]();
} }
~CharArray() { ~CharArray() {
delete [] buf; delete [] buf;

View File

@ -174,7 +174,8 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is,
} }
} }
zis->removeUnderlying(); zis->flushUnderlying();
zis->setUnderlying(NULL, 0);
} }
#undef ZRLE_DECODE #undef ZRLE_DECODE

View File

@ -17,3 +17,8 @@
typedef long ssize_t; typedef long ssize_t;
#endif #endif
#endif #endif
/* We know we use deprecated stuff, it's to support older macOS */
#if defined(__APPLE__) && defined(__clang__)
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif

View File

@ -1,347 +0,0 @@
#!/bin/bash
# -*- mode: shell-script; coding: UTF-8 -*-
#
# Build Xvnc with Xorg 7.4 or 7.5
#
set -e
PREFIX=
MAKE="make"
PARALLEL_MAKE=0
XORG_VERSION=7.5
XONLY=0
CFGHOST=
SRCDIR=`dirname $0`/../..
modules="dri2proto \
libpthread-stubs \
glproto \
xf86vidmodeproto \
xextproto \
xproto \
kbproto \
inputproto \
xcmiscproto \
bigreqsproto \
fixesproto \
damageproto \
xf86driproto \
randrproto \
renderproto \
scrnsaverproto \
resourceproto \
fontsproto \
videoproto \
compositeproto \
xineramaproto \
libdrm \
libXau \
xtrans \
libXdmcp \
libX11 \
libXext \
libXxf86vm \
libICE \
libSM \
libXt \
libXmu \
libXfixes \
libXdamage \
libXi \
libxkbfile \
libfontenc \
libXfont \
libpciaccess \
pixman"
init()
{
update_modules
pushd xorg
tar jxf ~/.tigervnc-xorg-$XORG_VERSION/util-macros.tar.bz2
pushd util-macros-*
echo "Building macros"
./configure --prefix=${PREFIX}
($MAKE install)
popd
pushd xserver
patch -p1 < $SRCDIR/unix/xserver18.patch
for all in `find $SRCDIR/contrib/xorg/xorg-$XORG_VERSION-patches/ -type f |grep '.*\.patch$'`; do
echo Applying $all
patch -p1 < $all
done
popd
popd
}
update_modules()
{
if [ -d xorg ]; then rm -rf xorg; fi
if [ -d xorg.build ]; then rm -rf xorg.build; fi
mkdir xorg
pushd xorg
$SRCDIR/contrib/xorg/download-xorg-$XORG_VERSION
for module in ${modules}; do
tar jxf ~/.tigervnc-xorg-$XORG_VERSION/${module}.tar.bz2
done
[ -r ~/.tigervnc-xorg-$XORG_VERSION/Mesa.tar.bz2 ] && \
tar jxf ~/.tigervnc-xorg-$XORG_VERSION/Mesa.tar.bz2
[ -r ~/.tigervnc-xorg-$XORG_VERSION/Mesa.tar.gz ] && \
tar zxf ~/.tigervnc-xorg-$XORG_VERSION/Mesa.tar.gz
tar jxf ~/.tigervnc-xorg-$XORG_VERSION/freetype.tar.bz2
tar jxf ~/.tigervnc-xorg-$XORG_VERSION/xorg-server.tar.bz2
cp -r $SRCDIR/unix/xserver xserver
cp -r xorg-server-1.*/* xserver
popd
}
build ()
{
if [ $XONLY -eq 0 ]; then
# Build VNC
echo "*** Building VNC ***"
cmake -G"Unix Makefiles" ${1+"$@"} -DBUILD_STATIC=1 $SRCDIR
$MAKE
# Build Xorg
echo "*** Building Xorg ***"
pushd xorg
# build freetype
echo "*** Building freetype ***"
pushd freetype-*
./configure ${CFGHOST} --prefix=${PREFIX} --enable-static --disable-shared
if [ $? -ne 0 ]; then
echo "Failed to configure freetype."
exit
fi
$MAKE install
popd
for module in ${modules}; do
extraoptions=""
cd ${module}-*
echo ======================
echo configuring ${module}
echo ======================
if [ "${module}" = "libX11" ]; then
extraoptions="${extraoptions} --without-xcb --disable-specs"
fi
if [ "${module}" = "libSM" ]; then
extraoptions="${extraoptions} --without-libuuid"
fi
if [ "${module}" = "pixman" ]; then
extraoptions="${extraoptions} --disable-gtk"
fi
if [ "${module}" = "libXfont" ]; then
extraoptions="${extraoptions} --with-freetype-config=${PREFIX}/bin/freetype-config"
fi
OLD_CFLAGS=${CFLAGS}
OLD_CXXFLAGS=${CXXFLAGS}
CFLAGS=${CFLAGS}' -fPIC'
CXXFLAGS=${CXXFLAGS}' -fPIC'
export CFLAGS CXXFLAGS
./configure ${CFGHOST} --prefix="${PREFIX}" ${extraoptions} --enable-static --disable-shared
CFLAGS=${OLD_CFLAGS}
CXXFLAGS=${OLD_CXXFLAGS}
export CFLAGS CXXFLAGS
echo ======================
echo building ${module}
echo ======================
if [ $? -ne 0 ]; then
echo "Failed to configure ${module}."
exit
fi
$MAKE install
cd ..
done
# build mesa
echo "*** Building Mesa ***"
pushd Mesa-*
./configure ${CFGHOST} --prefix=${PREFIX} --disable-driglx-direct --with-dri-drivers=swrast --with-driver=dri --disable-glut --without-demos
if [ $? -ne 0 ]; then
echo "Failed to configure Mesa."
exit
fi
$MAKE
$MAKE install
popd
popd
fi # XONLY
# build xserver
echo "*** Building xserver ***"
pushd xorg/xserver
autoreconf -fiv
XORGCFGFLAGS="--disable-dri --enable-dri2 --disable-composite --disable-xinerama --disable-xvfb --disable-xnest --disable-xorg --disable-dmx --disable-xwin --disable-xephyr --disable-kdrive --disable-config-dbus --disable-config-hal --disable-config-udev --with-sha1=libgcrypt SHA1_LIB=-lcrypto --disable-shared --enable-static ${XORGCFGFLAGS}"
./configure ${CFGHOST} --prefix=${PREFIX} ${XORGCFGFLAGS}
if [ $? -ne 0 ]; then
echo "Failed to configure X server."
exit
fi
$MAKE TIGERVNC_SRCDIR=$SRCDIR install
popd
}
rebuild ()
{
# Build VNC
echo "*** Building VNC ***"
$MAKE ${1+"$@"}
# build xserver
echo "*** Building xserver ***"
pushd xorg/xserver
$MAKE TIGERVNC_SRCDIR=$SRCDIR install ${1+"$@"}
popd
}
usage ()
{
echo "Usage: $0 init [-version <7.4 | 7.5>]"
echo
echo " $0 build [-version <7.4 | 7.5>]"
echo " [additional CMake flags]"
echo
echo " $0 rebuild [additional make options]"
echo
echo " $0 update [-version <7.4 | 7.5>]"
echo
exit 1
}
if [ -x '/usr/bin/getconf' -a "$PARALLEL_MAKE" = "1" ]; then
MAKE_PARALLEL=`/usr/bin/getconf _NPROCESSORS_ONLN 2>&1`
[ "$MAKE_PARALLEL" -gt 1 ] && MAKE="$MAKE -j$MAKE_PARALLEL"
fi
while [ $# -gt 0 ]
do
case "$1" in
init) MODE=init ;;
build) MODE=build ;;
xbuild) MODE=build; XONLY=1 ;;
rebuild) MODE=rebuild ;;
update) MODE=update ;;
-parallel) PARALLEL_MAKE=1; ;;
-srcdir) SRCDIR=$2; shift ;;
*) break ;;
esac
shift
done
pushd $SRCDIR
SRCDIR=`pwd`
echo "*** Using TigerVNC source tree at $SRCDIR ***"
popd
if [ "`pwd`" = "$SRCDIR/unix" ]; then
cd $SRCDIR
fi
if [ "$PREFIX" = "" ]; then
PREFIX=`pwd`/xorg.build
fi
if [ "$MODE" = "build" ]; then
if [ ! -d ./xorg.build/syslib ]; then
mkdir -p ./xorg.build/syslib
fi
for i in "$@"; do
case "$i" in
CC=*) CC=`echo $i | sed s/^CC=//g` ;;
CXX=*) CXX=`echo $i | sed s/^CXX=//g` ;;
CFLAGS=*) CFLAGS=`echo $i | sed s/^CFLAGS=//g` ;;
CXXFLAGS=*) CXXFLAGS=`echo $i | sed s/^CXXFLAGS=//g` ;;
LDFLAGS=*) LDFLAGS=`echo $i | sed s/^LDFLAGS=//g` ;;
esac
done
if [ "$CC" = "" ]; then
CC=gcc
fi
if [ "$CXX" = "" ]; then
CXX=g++
fi
if [ "$CFLAGS" = "" ]; then
CFLAGS=-O3
fi
if [ "$CXXFLAGS" = "" ]; then
CXXFLAGS=-O3
fi
CFLAGS="$CFLAGS -fPIC"
CXXFLAGS="$CXXFLAGS -fPIC"
LDFLAGS="$LDFLAGS -static-libgcc -L`pwd`/xorg.build/syslib"
echo CC = $CC
echo CXX = $CXX
echo CFLAGS = $CFLAGS
echo CXXFLAGS = $CXXFLAGS
echo LDFLAGS = $LDFLAGS
if [[ $CFLAGS = *-m32* ]]; then
CFGHOST="--host i686-pc-linux-gnu"
fi
STATICLIBS='libcrypto.a libz.a'
for lib in $STATICLIBS; do
if [ -f ./xorg.build/syslib/$lib ]; then
rm -f ./xorg.build/syslib/$lib
fi
done
IS64BIT=`echo -e "#ifdef __x86_64__\nis64bit_yes\n#else\nis64bit_no\n#endif" | $CC $CFLAGS -E - | grep is64bit`
STATICLIBDIR=
case $IS64BIT in
is64bit_yes)
if [ -d /usr/lib64 ]; then STATICLIBDIR=lib64;
else STATICLIBDIR=lib; fi
;;
is64bit_no)
if [ -d /usr/lib32 ]; then STATICLIBDIR=lib32;
else STATICLIBDIR=lib; fi
;;
*)
echo "Cannot determine whether compiler output is 64-bit or 32-bit. Are you using GCC?"
exit 1
;;
esac
for lib in $STATICLIBS; do
if [ -f /usr/$STATICLIBDIR/$lib ]; then
ln -fs /usr/$STATICLIBDIR/$lib ./xorg.build/syslib
else
if [ -f /$STATICLIBDIR/$lib ]; then
ln -fs /$STATICLIBDIR/$lib ./xorg.build/syslib
else
DYLIB=`echo $lib | sed s/\\\.a/\\.so/g`
if [ -f /usr/$STATICLIBDIR/$DYLIB -o -f /$STATICLIBDIR/$DYLIB ]; then
echo WARNING: Cannot find suitable $lib. Xvnc will depend on $DYLIB.
fi
fi
fi
done
fi
export ACLOCAL="aclocal -I ${PREFIX}/share/aclocal"
export PKG_CONFIG_PATH="${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"
case "$MODE" in
init) init ;;
build)
export CFLAGS CXXFLAGS LDFLAGS
build ${1+"$@"};
;;
rebuild) rebuild ${1+"$@"} ;;
update) update ;;
*) usage ;;
esac

View File

@ -1,120 +0,0 @@
#!/usr/bin/env python
# -*-mode: python; coding: utf-8 -*-
import os
import glob
import sys
import urllib2
#INDI = "http://ftp.sunet.se/pub/X11/ftp.x.org/individual"
INDI = "http://ftp.x.org/pub/individual/"
PROTO = INDI + "proto/"
LIB = INDI + "lib/"
SERVER = INDI + "xserver/"
UTIL = INDI + "util/"
DATA = INDI + "data/"
APP = INDI + "app/"
packages = {
"damageproto": PROTO + "damageproto-1.2.0.tar.bz2",
"fixesproto": PROTO + "fixesproto-4.1.1.tar.bz2",
"resourceproto": PROTO + "resourceproto-1.1.0.tar.bz2",
"fontsproto": PROTO + "fontsproto-2.1.0.tar.bz2",
"bigreqsproto": PROTO + "bigreqsproto-1.1.0.tar.bz2",
"kbproto": PROTO + "kbproto-1.0.4.tar.bz2",
"inputproto": PROTO + "inputproto-2.0.tar.bz2",
"glproto": PROTO + "glproto-1.4.12.tar.bz2",
"xineramaproto": PROTO + "xineramaproto-1.2.tar.bz2",
"randrproto": PROTO + "randrproto-1.3.1.tar.bz2",
"scrnsaverproto": PROTO + "scrnsaverproto-1.2.0.tar.bz2",
"renderproto": PROTO + "renderproto-0.11.tar.bz2",
"xcmiscproto": PROTO + "xcmiscproto-1.2.0.tar.bz2",
"xextproto": PROTO + "xextproto-7.1.1.tar.bz2",
"xf86driproto": PROTO + "xf86driproto-2.1.0.tar.bz2",
"dri2proto": PROTO + "dri2proto-2.1.tar.bz2",
"compositeproto": PROTO + "compositeproto-0.4.1.tar.bz2",
"xf86vidmodeproto": PROTO + "xf86vidmodeproto-2.3.tar.bz2",
"videoproto": PROTO + "videoproto-2.3.0.tar.bz2",
"xproto": PROTO + "xproto-7.0.16.tar.bz2",
"libxkbfile": LIB + "libxkbfile-1.0.6.tar.bz2",
"libXxf86vm": LIB + "libXxf86vm-1.1.0.tar.bz2",
"libXext": LIB + "libXext-1.1.2.tar.bz2",
"libfontenc": LIB + "libfontenc-1.0.5.tar.bz2",
"libXau": LIB + "libXau-1.0.6.tar.bz2",
"libXfont": LIB + "libXfont-1.4.2.tar.bz2",
"libXfixes": LIB + "libXfixes-4.0.5.tar.bz2",
"libSM": LIB + "libSM-1.1.1.tar.bz2",
"libXi": LIB + "libXi-1.3.2.tar.bz2",
"libXmu": LIB + "libXmu-1.0.5.tar.bz2",
"libX11": LIB + "libX11-1.3.5.tar.bz2",
"libXdmcp": LIB + "libXdmcp-1.0.3.tar.bz2",
"xtrans": LIB + "xtrans-1.2.5.tar.bz2",
"libXt": LIB + "libXt-1.0.8.tar.bz2",
"libpciaccess": LIB + "libpciaccess-0.12.0.tar.bz2",
"libICE": LIB + "libICE-1.0.6.tar.bz2",
"pixman": LIB + "pixman-0.19.2.tar.bz2",
"libXdamage": LIB + "libXdamage-1.1.3.tar.bz2",
"util-macros": UTIL + "util-macros-1.10.0.tar.bz2",
"xorg-server": SERVER + "xorg-server-1.8.2.tar.bz2",
"libdrm": "http://dri.freedesktop.org/libdrm/libdrm-2.4.21.tar.bz2",
"Mesa": "ftp://ftp.freedesktop.org/pub/mesa/beta/MesaLib-7.8.3-rc1.tar.bz2",
"libpthread-stubs": "http://xcb.freedesktop.org/dist/libpthread-stubs-0.3.tar.bz2",
"freetype": "http://downloads.sourceforge.net/freetype/freetype-2.4.2.tar.bz2",
}
# Python-based replacement for wget, which allows us to catch exceptions
def webget(url, file_name):
file_name = "%s/%s" % (os.getcwd(), file_name)
print "Downloading: %s" % (url)
try:
u = urllib2.urlopen(url)
except urllib2.URLError:
print sys.exc_info()[0]
sys.exit("ERROR: Unable to open URL: %s" % url)
try:
f = open(file_name, 'wb')
except IOError:
sys.exit("ERROR: Unable to save to: %s" % file_name)
else:
meta = u.info()
file_size = int(meta.getheaders("Content-Length")[0])
print " Saving as: %s Bytes: %s" % (file_name, file_size)
file_size_dl = 0
block_sz = 4096
while True:
buffer = u.read(block_sz)
if not buffer:
break
file_size_dl += len(buffer)
f.write(buffer)
status = r" Progress: %7d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
status = status + chr(8)*(len(status)+1)
print status,
f.close()
print status
def main():
dir = os.path.expanduser("~")+"/.tigervnc-xorg-7.5"
cwd = os.getcwd()
if not os.path.exists(dir):
os.mkdir(dir)
os.chdir(dir)
for pkg in packages.keys():
loc = packages[pkg]
if ".tar.bz2" in loc:
fname = pkg + ".tar.bz2"
else :
fname = pkg + ".tar.gz"
if not os.path.exists(fname):
webget(loc, fname)
os.chdir(cwd)
main()

View File

@ -1,131 +0,0 @@
From 0acffdd6f443198378012405e7f814f5abf278b3 Mon Sep 17 00:00:00 2001
From: Adam Tkac <atkac@redhat.com>
Date: Wed, 15 Sep 2010 15:37:01 +0200
Subject: [PATCH] Add -dridir parameter to specify DRI drivers directory from command line.
Signed-off-by: Adam Tkac <atkac@redhat.com>
---
glx/glxdri.c | 2 --
glx/glxdri2.c | 2 --
glx/glxdriswrast.c | 2 --
glx/glxext.c | 27 +++++++++++++++++++++++++++
glx/glxserver.h | 3 +++
os/utils.c | 9 +++++++++
6 files changed, 39 insertions(+), 6 deletions(-)
diff --git a/glx/glxdri.c b/glx/glxdri.c
index 5b78cec..ce29ae2 100644
--- a/glx/glxdri.c
+++ b/glx/glxdri.c
@@ -860,8 +860,6 @@ static const __DRIextension *loader_extensions[] = {
-static const char dri_driver_path[] = DRI_DRIVER_PATH;
-
static Bool
glxDRIEnterVT (int index, int flags)
{
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 2d6090c..49265ec 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -579,8 +579,6 @@ static const __DRIextension *loader_extensions[] = {
NULL
};
-static const char dri_driver_path[] = DRI_DRIVER_PATH;
-
static Bool
glxDRIEnterVT (int index, int flags)
{
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index 6a34393..37c1dce 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -438,8 +438,6 @@ initializeExtensions(__GLXDRIscreen *screen)
}
}
-static const char dri_driver_path[] = DRI_DRIVER_PATH;
-
static __GLXscreen *
__glXDRIscreenProbe(ScreenPtr pScreen)
{
diff --git a/glx/glxext.c b/glx/glxext.c
index 89e58b0..5e7cf23 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -608,3 +608,30 @@ static int __glXDispatch(ClientPtr client)
return retval;
}
+
+char *dri_driver_path = DRI_DRIVER_PATH;
+
+int GlxProcessArguments(int argc, char *argv[], int i)
+{
+ if (strncmp(argv[i], "-dridir", 7) == 0) {
+ if (++i < argc) {
+#if !defined(WIN32) && !defined(__CYGWIN__)
+ if (getuid() != geteuid()) {
+ LogMessage(X_WARNING, "-dridir is not available for setuid X servers\n");
+ return -1;
+ } else
+#endif
+ {
+ if (strlen(argv[i]) < PATH_MAX) {
+ dri_driver_path = argv[i];
+ return 2;
+ } else {
+ LogMessage(X_ERROR, "-dridir pathname too long\n");
+ return -1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/glx/glxserver.h b/glx/glxserver.h
index 1daf977..082ff82 100644
--- a/glx/glxserver.h
+++ b/glx/glxserver.h
@@ -251,4 +251,7 @@ extern unsigned glxMinorVersion;
extern int __glXEventBase;
+extern char *dri_driver_path;
+extern int GlxProcessArguments(int argc, char *argv[], int i);
+
#endif /* !__GLX_server_h__ */
diff --git a/os/utils.c b/os/utils.c
index 13d3b3f..ff97c86 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -141,6 +141,7 @@ Bool noDPMSExtension = FALSE;
#ifdef GLXEXT
Bool noGlxExtension = FALSE;
Bool noGlxVisualInit = FALSE;
+extern int GlxProcessArguments(int argc, char *argv[], int i);
#endif
#ifdef SCREENSAVER
Bool noScreenSaverExtension = FALSE;
@@ -721,6 +722,14 @@ ProcessCommandLine(int argc, char *argv[])
i+= skip-1;
else UseMsg();
}
+#ifdef GLXEXT
+ else if ((skip = GlxProcessArguments(argc,argv,i)) != 0) {
+ if (skip > 0)
+ i += skip - 1;
+ else
+ UseMsg();
+ }
+#endif
#ifdef RLIMIT_DATA
else if ( strcmp( argv[i], "-ld") == 0)
{
--
1.7.3.2

View File

@ -1,46 +0,0 @@
From 5e6e99eaef3ca346c78a3e520ed58ec8b8100b41 Mon Sep 17 00:00:00 2001
From: Adam Tkac <atkac@redhat.com>
Date: Thu, 2 Sep 2010 17:24:38 +0200
Subject: [PATCH] Add -xkbcompdir parameter to modify "xkbcomp" path from commandline.
Signed-off-by: Adam Tkac <atkac@redhat.com>
---
xkb/xkbInit.c | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index fbf8f14..29fb33e 100644
--- a/xkb/xkbInit.c
+++ b/xkb/xkbInit.c
@@ -742,7 +742,28 @@ XkbProcessArguments(int argc,char *argv[],int i)
}
}
return j;
+ } else if (strncmp(argv[i], "-xkbcompdir", 11)==0) {
+ if (++i < argc) {
+#if !defined(WIN32) && !defined(__CYGWIN__)
+ if (getuid() != geteuid()) {
+ LogMessage(X_WARNING, "-xkbdir is not available for setuid X servers\n");
+ return -1;
+ } else
+#endif
+ {
+ if (strlen(argv[i]) < PATH_MAX) {
+ XkbBinDirectory = argv[i];
+ return 2;
+ } else {
+ LogMessage(X_ERROR, "-xkbcompdir pathname too long\n");
+ return -1;
+ }
+ }
+ } else {
+ return -1;
+ }
}
+
if ((strcmp(argv[i], "-ardelay") == 0) ||
(strcmp (argv[i], "-ar1") == 0)) { /* -ardelay int */
if (++i >= argc) UseMsg ();
--
1.7.2.3

View File

@ -274,6 +274,20 @@ select:active {
overflow: auto; overflow: auto;
} }
/* ----------------------------------------
* Connection Stats
* ----------------------------------------
*/
#noVNC_connection_stats {
top: 0;
left: auto;
right: 0;
position: fixed;
background: #9fa5a2d4;
color: #00ffa2d4;
visibility: hidden;
}
/* ---------------------------------------- /* ----------------------------------------
* Control Bar * Control Bar
* ---------------------------------------- * ----------------------------------------

View File

@ -174,6 +174,7 @@ const UI = {
UI.initSetting('prefer_local_cursor', true); UI.initSetting('prefer_local_cursor', true);
UI.initSetting('enable_webp', true); UI.initSetting('enable_webp', true);
UI.initSetting('toggle_control_panel', false); UI.initSetting('toggle_control_panel', false);
UI.initSetting('enable_perf_stats', false);
UI.setupSettingLabels(); UI.setupSettingLabels();
}, },
@ -349,6 +350,8 @@ const UI = {
document.getElementById("noVNC_settings_button") document.getElementById("noVNC_settings_button")
.addEventListener('click', UI.toggleSettingsPanel); .addEventListener('click', UI.toggleSettingsPanel);
document.getElementById("noVNC_setting_enable_perf_stats").addEventListener('click', UI.showStats);
UI.addSettingChangeHandler('encrypt'); UI.addSettingChangeHandler('encrypt');
UI.addSettingChangeHandler('resize'); UI.addSettingChangeHandler('resize');
UI.addSettingChangeHandler('resize', UI.applyResizeMode); UI.addSettingChangeHandler('resize', UI.applyResizeMode);
@ -368,6 +371,10 @@ const UI = {
UI.addSettingChangeHandler('logging', UI.updateLogging); UI.addSettingChangeHandler('logging', UI.updateLogging);
UI.addSettingChangeHandler('reconnect'); UI.addSettingChangeHandler('reconnect');
UI.addSettingChangeHandler('reconnect_delay'); UI.addSettingChangeHandler('reconnect_delay');
UI.addSettingChangeHandler('enable_webp');
UI.addSettingChangeHandler('clipboard_seamless');
UI.addSettingChangeHandler('clipboard_up');
UI.addSettingChangeHandler('clipboard_down');
}, },
addFullscreenHandlers() { addFullscreenHandlers() {
@ -450,6 +457,24 @@ const UI = {
.classList.remove('noVNC_open'); .classList.remove('noVNC_open');
}, },
showStats() {
UI.saveSetting('enable_perf_stats');
let enable_stats = UI.getSetting('enable_perf_stats');
if (enable_stats === true && UI.statsInterval == undefined) {
document.getElementById("noVNC_connection_stats").style.visibility = "visible";
UI.statsInterval = setInterval(function() {
if (UI.rfb !== undefined) {
UI.rfb.requestBottleneckStats();
}
} , 5000);
} else {
document.getElementById("noVNC_connection_stats").style.visibility = "hidden";
UI.statsInterval = null;
}
},
showStatus(text, status_type, time) { showStatus(text, status_type, time) {
const statusElem = document.getElementById('noVNC_status'); const statusElem = document.getElementById('noVNC_status');
@ -979,6 +1004,13 @@ const UI = {
} }
}, },
//recieved bottleneck stats
bottleneckStatsRecieve(e) {
var obj = JSON.parse(e.detail.text);
document.getElementById("noVNC_connection_stats").innerHTML = "CPU: " + obj[0] + "/" + obj[1] + " | Network: " + obj[2] + "/" + obj[3];
console.log(e.detail.text);
},
popupMessage: function(msg, secs) { popupMessage: function(msg, secs) {
if (!secs){ if (!secs){
secs = 500; secs = 500;
@ -1208,6 +1240,7 @@ const UI = {
UI.rfb.addEventListener("securityfailure", UI.securityFailed); UI.rfb.addEventListener("securityfailure", UI.securityFailed);
UI.rfb.addEventListener("capabilities", UI.updatePowerButton); UI.rfb.addEventListener("capabilities", UI.updatePowerButton);
UI.rfb.addEventListener("clipboard", UI.clipboardReceive); UI.rfb.addEventListener("clipboard", UI.clipboardReceive);
UI.rfb.addEventListener("bottleneck_stats", UI.bottleneckStatsRecieve);
document.addEventListener('mouseenter', UI.enterVNC); document.addEventListener('mouseenter', UI.enterVNC);
document.addEventListener('mouseleave', UI.leaveVNC); document.addEventListener('mouseleave', UI.leaveVNC);
@ -1346,6 +1379,7 @@ const UI = {
msg = _("Connected (unencrypted) to ") + UI.desktopName; msg = _("Connected (unencrypted) to ") + UI.desktopName;
} }
UI.showStatus(msg); UI.showStatus(msg);
UI.showStats();
UI.updateVisualState('connected'); UI.updateVisualState('connected');
// Do this last because it can only be used on rendered elements // Do this last because it can only be used on rendered elements

View File

@ -457,6 +457,10 @@ export default class RFB extends EventTargetMixin {
RFB.messages.clientCutText(this._sock, text); RFB.messages.clientCutText(this._sock, text);
} }
requestBottleneckStats() {
RFB.messages.requestStats(this._sock);
}
// ===== PRIVATE METHODS ===== // ===== PRIVATE METHODS =====
_connect() { _connect() {
@ -1495,6 +1499,22 @@ export default class RFB extends EventTargetMixin {
return true; return true;
} }
_handle_server_stats_msg() {
this._sock.rQskipBytes(3); // Padding
const length = this._sock.rQshift32();
if (this._sock.rQwait("KASM bottleneck stats", length, 8)) { return false; }
const text = this._sock.rQshiftStr(length);
console.log("Received KASM bottleneck stats:");
console.log(text);
this.dispatchEvent(new CustomEvent(
"bottleneck_stats",
{ detail: { text: text } }));
return true;
}
_handle_server_fence_msg() { _handle_server_fence_msg() {
if (this._sock.rQwait("ServerFence header", 8, 1)) { return false; } if (this._sock.rQwait("ServerFence header", 8, 1)) { return false; }
this._sock.rQskipBytes(3); // Padding this._sock.rQskipBytes(3); // Padding
@ -1605,6 +1625,9 @@ export default class RFB extends EventTargetMixin {
} }
return true; return true;
case 178: // KASM bottleneck stats
return this._handle_server_stats_msg();
case 248: // ServerFence case 248: // ServerFence
return this._handle_server_fence_msg(); return this._handle_server_fence_msg();
@ -2108,6 +2131,22 @@ RFB.messages = {
sock.flush(); sock.flush();
}, },
requestStats(sock) {
const buff = sock._sQ;
const offset = sock._sQlen;
if (buff == null) { return; }
buff[offset] = 178; // msg-type
buff[offset + 1] = 0; // padding
buff[offset + 2] = 0; // padding
buff[offset + 3] = 0; // padding
sock._sQlen += 4;
sock.flush();
},
enableContinuousUpdates(sock, enable, x, y, width, height) { enableContinuousUpdates(sock, enable, x, y, width, height) {
const buff = sock._sQ; const buff = sock._sQ;
const offset = sock._sQlen; const offset = sock._sQlen;

View File

@ -90,6 +90,10 @@
</div> </div>
</div> </div>
<div id="noVNC_connection_stats">
Loading statistics...
</div>
<!-- noVNC Control Bar --> <!-- noVNC Control Bar -->
<div id="noVNC_control_bar_anchor" class="noVNC_vcenter"> <div id="noVNC_control_bar_anchor" class="noVNC_vcenter">
@ -214,6 +218,8 @@
<label><input id="noVNC_setting_prefer_local_cursor" type="checkbox" /> Prefer Local Cursor</label></li> <label><input id="noVNC_setting_prefer_local_cursor" type="checkbox" /> Prefer Local Cursor</label></li>
<li> <li>
<label><input id="noVNC_setting_enable_webp" type="checkbox" /> Enable WebP Compression</label></li> <label><input id="noVNC_setting_enable_webp" type="checkbox" /> Enable WebP Compression</label></li>
<li>
<label><input id="noVNC_setting_enable_perf_stats" type="checkbox" /> Enable Performance Stats</label></li>
<li> <li>
<label><input id="noVNC_setting_toggle_control_panel" type="checkbox" /> Toggle Control Panel via Keystrokes</label></li> <label><input id="noVNC_setting_toggle_control_panel" type="checkbox" /> Toggle Control Panel via Keystrokes</label></li>
<li> <li>

View File

@ -2,6 +2,7 @@ add_subdirectory(tx)
add_subdirectory(common) add_subdirectory(common)
add_subdirectory(vncconfig) add_subdirectory(vncconfig)
add_subdirectory(vncpasswd) add_subdirectory(vncpasswd)
add_subdirectory(kasmvncpasswd)
install(PROGRAMS vncserver DESTINATION ${BIN_DIR}) install(PROGRAMS vncserver DESTINATION ${BIN_DIR})
install(FILES vncserver.man DESTINATION ${MAN_DIR}/man1 RENAME vncserver.1) install(FILES vncserver.man DESTINATION ${MAN_DIR}/man1 RENAME vncserver.1)

1
unix/kasmvncpasswd/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
kasmvncpasswd

View File

@ -0,0 +1,8 @@
include_directories(${CMAKE_SOURCE_DIR}/common)
add_executable(kasmvncpasswd
kasmvncpasswd.c)
target_link_libraries(kasmvncpasswd crypt)
install(TARGETS kasmvncpasswd DESTINATION ${BIN_DIR})

View File

@ -0,0 +1,155 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2010 Antoine Martin. All Rights Reserved.
* Copyright (C) 2010 D. R. Commander. All Rights Reserved.
* Copyright (C) 2020 Kasm. 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 <crypt.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include <unistd.h>
#include <wordexp.h>
static void usage(const char *prog)
{
fprintf(stderr, "Usage: %s [file]\n", prog);
fprintf(stderr, " %s -f\n", prog);
exit(1);
}
static void enableEcho(unsigned char enable) {
struct termios attrs;
tcgetattr(fileno(stdin), &attrs);
if (enable)
attrs.c_lflag |= ECHO;
else
attrs.c_lflag &= ~ECHO;
attrs.c_lflag |= ECHONL;
tcsetattr(fileno(stdin), TCSAFLUSH, &attrs);
}
static const char *encryptpw(const char *in) {
return crypt(in, "$5$kasm$");
}
static char* getpassword(const char* prompt, char *buf) {
if (prompt) fputs(prompt, stdout);
enableEcho(0);
char* result = fgets(buf, 4096, stdin);
enableEcho(1);
if (result) {
if (result[strlen(result)-1] == '\n')
result[strlen(result)-1] = 0;
return buf;
}
return NULL;
}
static char pw1[4096];
static char pw2[4096];
// Reads passwords from stdin and prints encrypted passwords to stdout.
static int encrypt_pipe() {
char *result = getpassword(NULL, pw1);
if (!result)
return 1;
printf("%s", encryptpw(result));
fflush(stdout);
return 0;
}
static const char *readpassword() {
while (1) {
if (!getpassword("Password:", pw1)) {
perror("getpassword error");
exit(1);
}
if (strlen(pw1) < 6) {
if (strlen(pw1) == 0) {
fprintf(stderr,"Password not changed\n");
exit(1);
}
fprintf(stderr,"Password must be at least 6 characters - try again\n");
continue;
}
if (!getpassword("Verify:", pw2)) {
perror("getpass error");
exit(1);
}
if (strcmp(pw1, pw2) != 0) {
fprintf(stderr,"Passwords don't match - try again\n");
continue;
}
return encryptpw(pw1);
}
}
int main(int argc, char** argv)
{
char* fname = 0;
for (int i = 1; i < argc; i++) {
if (strncmp(argv[i], "-f", 2) == 0) {
return encrypt_pipe();
} else if (argv[i][0] == '-') {
usage(argv[0]);
} else if (!fname) {
fname = argv[i];
} else {
usage(argv[0]);
}
}
if (!fname) {
wordexp_t wexp;
if (!wordexp("~/.kasmpasswd", &wexp, WRDE_NOCMD) && wexp.we_wordv[0])
fname = strdup(wexp.we_wordv[0]);
wordfree(&wexp);
}
if (!fname)
usage(argv[0]);
while (1) {
const char *encrypted = readpassword();
FILE* fp = fopen(fname, "w");
if (!fp) {
fprintf(stderr, "Couldn't open %s for writing\n", fname);
exit(1);
}
chmod(fname, S_IRUSR|S_IWUSR);
if (fwrite(encrypted, strlen(encrypted), 1, fp) != 1) {
fprintf(stderr,"Writing to %s failed\n",fname);
exit(1);
}
fclose(fp);
return 0;
}
}

103
unix/vncserver Executable file → Normal file
View File

@ -33,8 +33,6 @@ if($slashndx>=0) {
$exedir = substr($0, 0, $slashndx+1); $exedir = substr($0, 0, $slashndx+1);
} }
$vncClasses = "";
&SanityCheck(); &SanityCheck();
# #
@ -44,12 +42,11 @@ $vncClasses = "";
$geometry = "1024x768"; $geometry = "1024x768";
#$depth = 16; #$depth = 16;
$vncJavaFiles = (((-d "$vncClasses") && "$vncClasses") ||
((-d "/usr/share/vnc/classes") && "/usr/share/vnc/classes") ||
((-d "/usr/local/vnc/classes") && "/usr/local/vnc/classes"));
$vncUserDir = "$ENV{HOME}/.vnc"; $vncUserDir = "$ENV{HOME}/.vnc";
$vncUserConfig = "$vncUserDir/config"; $vncUserConfig = "$vncUserDir/config";
$vncUserName = `id -u -n`;
$vncUserName =~ s/^\s+|\s+$//g;
$vncSystemConfigDir = "/etc/kasmvnc"; $vncSystemConfigDir = "/etc/kasmvnc";
$vncSystemConfigDefaultsFile = "$vncSystemConfigDir/vncserver-config-defaults"; $vncSystemConfigDefaultsFile = "$vncSystemConfigDir/vncserver-config-defaults";
@ -83,7 +80,7 @@ $defaultXStartup
"[ -r \$HOME/.Xresources ] && xrdb \$HOME/.Xresources\n". "[ -r \$HOME/.Xresources ] && xrdb \$HOME/.Xresources\n".
"xsetroot -solid grey\n". "xsetroot -solid grey\n".
"xterm -geometry 80x24+10+10 -ls -title \"\$VNCDESKTOP Desktop\" &\n". "xterm -geometry 80x24+10+10 -ls -title \"\$VNCDESKTOP Desktop\" &\n".
"twm &\n"); "twm\n");
$defaultConfig $defaultConfig
= ("## Supported server options to pass to vncserver upon invocation can be listed\n". = ("## Supported server options to pass to vncserver upon invocation can be listed\n".
@ -94,7 +91,8 @@ $defaultConfig
"# desktop=sandbox\n". "# desktop=sandbox\n".
"# geometry=2000x1200\n". "# geometry=2000x1200\n".
"# localhost\n". "# localhost\n".
"# alwaysshared\n"); "# alwaysshared\n".
"username=$vncUserName");
chop($host = `uname -n`); chop($host = `uname -n`);
@ -206,7 +204,6 @@ my %config;
# We set some reasonable defaults. Config file settings # We set some reasonable defaults. Config file settings
# override these where present. # override these where present.
$default_opts{desktop} = &quotedString($desktopName); $default_opts{desktop} = &quotedString($desktopName);
$default_opts{httpd} = $vncJavaFiles if ($vncJavaFiles);
$default_opts{auth} = &quotedString($xauthorityFile); $default_opts{auth} = &quotedString($xauthorityFile);
$default_opts{geometry} = $geometry if ($geometry); $default_opts{geometry} = $geometry if ($geometry);
$default_opts{depth} = $depth if ($depth); $default_opts{depth} = $depth if ($depth);
@ -243,46 +240,50 @@ $passwordArgSpecified = 0;
@vncAuthStrings = ("vncauth", "tlsvnc", "x509vnc"); @vncAuthStrings = ("vncauth", "tlsvnc", "x509vnc");
# ...first we check our configuration files' settings # ...first we check our configuration files' settings
if ($config{'securitytypes'}) { #if ($config{'securitytypes'}) {
$securityTypeArgSpecified = 1; # $securityTypeArgSpecified = 1;
foreach $arg2 (split(',', $config{'securitytypes'})) { # foreach $arg2 (split(',', $config{'securitytypes'})) {
if (grep {$_ eq lc($arg2)} @vncAuthStrings) { # if (grep {$_ eq lc($arg2)} @vncAuthStrings) {
$vncAuthEnabled = 1; # $vncAuthEnabled = 1;
} # }
} # }
} #}
# ...and finally we check CLI args, which in the case of the topic at # ...and finally we check CLI args, which in the case of the topic at
# hand (VNC auth or not), override anything found in configuration files # hand (VNC auth or not), override anything found in configuration files
# (even so-called "mandatory" settings). # (even so-called "mandatory" settings).
for ($i = 0; $i < @ARGV; ++$i) { #for ($i = 0; $i < @ARGV; ++$i) {
# -SecurityTypes can be followed by a space or "=" # # -SecurityTypes can be followed by a space or "="
my @splitargs = split('=', $ARGV[$i]); # my @splitargs = split('=', $ARGV[$i]);
if (@splitargs <= 1 && $i < @ARGV - 1) { # if (@splitargs <= 1 && $i < @ARGV - 1) {
push(@splitargs, $ARGV[$i + 1]); # push(@splitargs, $ARGV[$i + 1]);
} # }
if (lc(@splitargs[0]) eq "-securitytypes") { # if (lc(@splitargs[0]) eq "-securitytypes") {
if (@splitargs > 1) { # if (@splitargs > 1) {
$securityTypeArgSpecified = 1; # $securityTypeArgSpecified = 1;
} # }
foreach $arg2 (split(',', @splitargs[1])) { # foreach $arg2 (split(',', @splitargs[1])) {
if (grep {$_ eq lc($arg2)} @vncAuthStrings) { # if (grep {$_ eq lc($arg2)} @vncAuthStrings) {
$vncAuthEnabled = 1; # $vncAuthEnabled = 1;
} # }
} # }
} # }
if ((lc(@splitargs[0]) eq "-password") # if ((lc(@splitargs[0]) eq "-password")
|| (lc(@splitargs[0]) eq "-passwordfile" # || (lc(@splitargs[0]) eq "-passwordfile"
|| (lc(@splitargs[0]) eq "-rfbauth"))) { # || (lc(@splitargs[0]) eq "-rfbauth"))) {
$passwordArgSpecified = 1; # $passwordArgSpecified = 1;
} # }
} #}
if ((!$securityTypeArgSpecified || $vncAuthEnabled) && !$passwordArgSpecified) { # Disable vnc auth, kasmvnc uses https basic auth
($z,$z,$mode) = stat("$vncUserDir/passwd"); system("echo '' | ".$exedir."vncpasswd -f > $vncUserDir/passwd");
if (!(-e "$vncUserDir/passwd") || ($mode & 077)) {
$kasmAuthEnabled = 1;
if ($kasmAuthEnabled) {
if (!(-e "$ENV{HOME}/.kasmpasswd")) {
warn "\nYou will require a password to access your desktops.\n\n"; warn "\nYou will require a password to access your desktops.\n\n";
system($exedir."vncpasswd -q $vncUserDir/passwd"); system($exedir."kasmvncpasswd $ENV{HOME}/.kasmpasswd");
if (($? >> 8) != 0) { if (($? >> 8) != 0) {
exit 1; exit 1;
} }
@ -373,7 +374,8 @@ unless (kill 0, `cat $pidFile`) {
die "\n"; die "\n";
} }
warn "\nNew '$desktopName' desktop is $host:$displayNumber\n\n"; warn "\nNew '$desktopName' desktop is $host:$displayNumber\n";
warn "\nUsername: $vncUserName\n\n";
# Create the user's xstartup script if necessary. # Create the user's xstartup script if necessary.
if (! $skipxstartup) { if (! $skipxstartup) {
@ -462,7 +464,13 @@ sub LoadConfig {
if ($warnoverride && $config{$k}) { if ($warnoverride && $config{$k}) {
print("Warning: $configFile is overriding previously defined '$k' to be '$v'\n"); print("Warning: $configFile is overriding previously defined '$k' to be '$v'\n");
} }
# change username option to basicAuth and add colon as required by Xvnc, password will be taken from file
if ($k = "username") {
$config{"basicauth"} = "$v:";
$vncUserName = $v;
} else {
$config{$k} = $v; $config{$k} = $v;
}
} elsif ($_ =~ m/^\s*(\S+)/) { } elsif ($_ =~ m/^\s*(\S+)/) {
# We can't reasonably warn on override of toggles (e.g. AlwaysShared) # We can't reasonably warn on override of toggles (e.g. AlwaysShared)
# because it would get crazy to do so. We'd have to check if the # because it would get crazy to do so. We'd have to check if the
@ -558,13 +566,6 @@ sub CheckDisplayNumber
return 0; return 0;
} }
if (-e "/usr/spool/sockets/X11/$n") {
warn("\nWarning: $host:$n is taken because of ".
"/usr/spool/sockets/X11/$n\n");
warn "Remove this file if there is no X server $host:$n\n";
return 0;
}
return 1; return 1;
} }
@ -848,7 +849,6 @@ sub SanityCheck
foreach $cmd ("Xvnc","vncpasswd") { foreach $cmd ("Xvnc","vncpasswd") {
for (split(/:/,$ENV{PATH})) { for (split(/:/,$ENV{PATH})) {
if (-x "$_/$cmd") { if (-x "$_/$cmd") {
$vncClasses = "$_/../vnc/classes";
next cmd2; next cmd2;
} }
} }
@ -860,7 +860,6 @@ sub SanityCheck
foreach $cmd ($exedir."Xvnc",$exedir."vncpasswd") { foreach $cmd ($exedir."Xvnc",$exedir."vncpasswd") {
for (split(/:/,$ENV{PATH})) { for (split(/:/,$ENV{PATH})) {
if (-x "$cmd") { if (-x "$cmd") {
$vncClasses = $exedir."../vnc/classes";
next cmd3; next cmd3;
} }
} }

View File

@ -687,3 +687,12 @@ static void vncKeysymKeyboardEvent(KeySym keysym, int down)
*/ */
mieqProcessInputEvents(); mieqProcessInputEvents();
} }
#if INPUTTHREAD
/** This function is called in Xserver/os/inputthread.c when starting
the input thread. */
void
ddxInputThreadInit(void)
{
}
#endif

View File

@ -46,7 +46,7 @@ Xvnc_CPPFLAGS = $(XVNC_CPPFLAGS) -DKASMVNC -DNO_MODULE_EXTS \
-I$(top_srcdir)/include ${XSERVERLIBS_CFLAGS} -I$(includedir) -I$(top_srcdir)/include ${XSERVERLIBS_CFLAGS} -I$(includedir)
Xvnc_LDADD = $(XVNC_LIBS) libvnccommon.la $(COMMON_LIBS) \ Xvnc_LDADD = $(XVNC_LIBS) libvnccommon.la $(COMMON_LIBS) \
$(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XVNC_SYS_LIBS) -lX11 -lwebp -lssl -lcrypto $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XVNC_SYS_LIBS) -lX11 -lwebp -lssl -lcrypto -lcrypt
Xvnc_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) -fopenmp Xvnc_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) -fopenmp

View File

@ -143,6 +143,22 @@ const char* vncGetParamDesc(const char *name)
return param->getDescription(); return param->getDescription();
} }
int vncIsParamBool(const char *name)
{
VoidParameter *param;
BoolParameter *bparam;
param = rfb::Configuration::getParam(name);
if (param == NULL)
return false;
bparam = dynamic_cast<BoolParameter*>(param);
if (bparam == NULL)
return false;
return true;
}
int vncGetParamCount(void) int vncGetParamCount(void)
{ {
int count; int count;

View File

@ -41,6 +41,7 @@ int vncSetParam(const char *name, const char *value);
int vncSetParamSimple(const char *nameAndValue); int vncSetParamSimple(const char *nameAndValue);
char* vncGetParam(const char *name); char* vncGetParam(const char *name);
const char* vncGetParamDesc(const char *name); const char* vncGetParamDesc(const char *name);
int vncIsParamBool(const char *name);
int vncGetParamCount(void); int vncGetParamCount(void);
char *vncGetParamList(void); char *vncGetParamList(void);

View File

@ -35,7 +35,6 @@
#include <network/Socket.h> #include <network/Socket.h>
#include <rfb/Exception.h> #include <rfb/Exception.h>
#include <rfb/VNCServerST.h> #include <rfb/VNCServerST.h>
#include <rfb/HTTPServer.h>
#include <rfb/LogWriter.h> #include <rfb/LogWriter.h>
#include <rfb/Configuration.h> #include <rfb/Configuration.h>
#include <rfb/ServerCore.h> #include <rfb/ServerCore.h>
@ -67,54 +66,13 @@ IntParameter queryConnectTimeout("QueryConnectTimeout",
"rejecting the connection", "rejecting the connection",
10); 10);
class FileHTTPServer : public rfb::HTTPServer {
public:
FileHTTPServer(XserverDesktop* d) : desktop(d) {}
virtual ~FileHTTPServer() {}
virtual rdr::InStream* getFile(const char* name, const char** contentType,
int* contentLength, time_t* lastModified)
{
if (name[0] != '/' || strstr(name, "..") != 0) {
vlog.info("http request was for invalid file name");
return 0;
}
if (strcmp(name, "/") == 0) name = "/index.vnc";
CharArray httpDirStr(httpDir.getData());
CharArray fname(strlen(httpDirStr.buf)+strlen(name)+1);
sprintf(fname.buf, "%s%s", httpDirStr.buf, name);
int fd = open(fname.buf, O_RDONLY);
if (fd < 0) return 0;
rdr::InStream* is = new rdr::FdInStream(fd, -1, 0, true);
*contentType = guessContentType(name, *contentType);
if (strlen(name) > 4 && strcasecmp(&name[strlen(name)-4], ".vnc") == 0) {
is = new rdr::SubstitutingInStream(is, desktop, 20);
*contentType = "text/html";
} else {
struct stat st;
if (fstat(fd, &st) == 0) {
*contentLength = st.st_size;
*lastModified = st.st_mtime;
}
}
return is;
}
XserverDesktop* desktop;
};
XserverDesktop::XserverDesktop(int screenIndex_, XserverDesktop::XserverDesktop(int screenIndex_,
std::list<network::SocketListener*> listeners_, std::list<network::SocketListener*> listeners_,
std::list<network::SocketListener*> httpListeners_,
const char* name, const rfb::PixelFormat &pf, const char* name, const rfb::PixelFormat &pf,
int width, int height, int width, int height,
void* fbptr, int stride) void* fbptr, int stride)
: screenIndex(screenIndex_), : screenIndex(screenIndex_),
server(0), httpServer(0), server(0), listeners(listeners_),
listeners(listeners_), httpListeners(httpListeners_),
directFbptr(true), directFbptr(true),
queryConnectId(0), queryConnectTimer(this) queryConnectId(0), queryConnectTimer(this)
{ {
@ -124,20 +82,11 @@ XserverDesktop::XserverDesktop(int screenIndex_,
setFramebuffer(width, height, fbptr, stride); setFramebuffer(width, height, fbptr, stride);
server->setQueryConnectionHandler(this); server->setQueryConnectionHandler(this);
if (!httpListeners.empty ())
httpServer = new FileHTTPServer(this);
for (std::list<SocketListener*>::iterator i = listeners.begin(); for (std::list<SocketListener*>::iterator i = listeners.begin();
i != listeners.end(); i != listeners.end();
i++) { i++) {
vncSetNotifyFd((*i)->getFd(), screenIndex, true, false); vncSetNotifyFd((*i)->getFd(), screenIndex, true, false);
} }
for (std::list<SocketListener*>::iterator i = httpListeners.begin();
i != httpListeners.end();
i++) {
vncSetNotifyFd((*i)->getFd(), screenIndex, true, false);
}
} }
XserverDesktop::~XserverDesktop() XserverDesktop::~XserverDesktop()
@ -147,14 +96,8 @@ XserverDesktop::~XserverDesktop()
delete listeners.back(); delete listeners.back();
listeners.pop_back(); listeners.pop_back();
} }
while (!httpListeners.empty()) {
vncRemoveNotifyFd(listeners.back()->getFd());
delete httpListeners.back();
httpListeners.pop_back();
}
if (!directFbptr) if (!directFbptr)
delete [] data; delete [] data;
delete httpServer;
delete server; delete server;
} }
@ -201,56 +144,6 @@ void XserverDesktop::refreshScreenLayout()
server->setScreenLayout(::computeScreenLayout(&outputIdMap)); server->setScreenLayout(::computeScreenLayout(&outputIdMap));
} }
char* XserverDesktop::substitute(const char* varName)
{
if (strcmp(varName, "$$") == 0) {
return rfb::strDup("$");
}
if (strcmp(varName, "$PORT") == 0) {
char* str = new char[10];
sprintf(str, "%d", listeners.empty () ? 0 : (*listeners.begin ())->getMyPort());
return str;
}
if (strcmp(varName, "$WIDTH") == 0) {
char* str = new char[10];
sprintf(str, "%d", width());
return str;
}
if (strcmp(varName, "$HEIGHT") == 0) {
char* str = new char[10];
sprintf(str, "%d", height());
return str;
}
if (strcmp(varName, "$APPLETWIDTH") == 0) {
char* str = new char[10];
sprintf(str, "%d", width());
return str;
}
if (strcmp(varName, "$APPLETHEIGHT") == 0) {
char* str = new char[10];
sprintf(str, "%d", height());
return str;
}
if (strcmp(varName, "$DESKTOP") == 0) {
return rfb::strDup(server->getName());
}
if (strcmp(varName, "$DISPLAY") == 0) {
struct utsname uts;
uname(&uts);
char* str = new char[256];
strncpy(str, uts.nodename, 240);
str[239] = '\0'; /* Ensure string is zero-terminated */
strcat(str, ":");
strncat(str, vncGetDisplay(), 10);
return str;
}
if (strcmp(varName, "$USER") == 0) {
struct passwd* user = getpwuid(getuid());
return rfb::strDup(user ? user->pw_name : "?");
}
return 0;
}
rfb::VNCServerST::queryResult rfb::VNCServerST::queryResult
XserverDesktop::queryConnection(network::Socket* sock, XserverDesktop::queryConnection(network::Socket* sock,
const char* userName, const char* userName,
@ -370,14 +263,10 @@ void XserverDesktop::handleSocketEvent(int fd, bool read, bool write)
if (read) { if (read) {
if (handleListenerEvent(fd, &listeners, server)) if (handleListenerEvent(fd, &listeners, server))
return; return;
if (handleListenerEvent(fd, &httpListeners, httpServer))
return;
} }
if (handleSocketEvent(fd, server, read, write)) if (handleSocketEvent(fd, server, read, write))
return; return;
if (handleSocketEvent(fd, httpServer, read, write))
return;
vlog.error("Cannot find file descriptor for socket event"); vlog.error("Cannot find file descriptor for socket event");
} catch (rdr::Exception& e) { } catch (rdr::Exception& e) {
@ -458,21 +347,6 @@ void XserverDesktop::blockHandler(int* timeout)
vncSetNotifyFd(fd, screenIndex, true, (*i)->outStream().bufferUsage() > 0); vncSetNotifyFd(fd, screenIndex, true, (*i)->outStream().bufferUsage() > 0);
} }
} }
if (httpServer) {
httpServer->getSockets(&sockets);
for (i = sockets.begin(); i != sockets.end(); i++) {
int fd = (*i)->getFd();
if ((*i)->isShutdown()) {
vlog.debug("http client gone, sock %d",fd);
vncRemoveNotifyFd(fd);
httpServer->removeSocket(*i);
delete (*i);
} else {
/* Update existing NotifyFD to listen for write (or not) */
vncSetNotifyFd(fd, screenIndex, true, (*i)->outStream().bufferUsage() > 0);
}
}
}
// We are responsible for propagating mouse movement between clients // We are responsible for propagating mouse movement between clients
int cursorX, cursorY; int cursorX, cursorY;

View File

@ -32,11 +32,9 @@
#include <stdint.h> #include <stdint.h>
#include <rfb/SDesktop.h> #include <rfb/SDesktop.h>
#include <rfb/HTTPServer.h>
#include <rfb/PixelBuffer.h> #include <rfb/PixelBuffer.h>
#include <rfb/Configuration.h> #include <rfb/Configuration.h>
#include <rfb/VNCServerST.h> #include <rfb/VNCServerST.h>
#include <rdr/SubstitutingInStream.h>
#include <unixcommon.h> #include <unixcommon.h>
#include "Input.h" #include "Input.h"
@ -47,14 +45,12 @@ namespace rfb {
namespace network { class SocketListener; class Socket; class SocketServer; } namespace network { class SocketListener; class Socket; class SocketServer; }
class XserverDesktop : public rfb::SDesktop, public rfb::FullFramePixelBuffer, class XserverDesktop : public rfb::SDesktop, public rfb::FullFramePixelBuffer,
public rdr::Substitutor,
public rfb::VNCServerST::QueryConnectionHandler, public rfb::VNCServerST::QueryConnectionHandler,
public rfb::Timer::Callback { public rfb::Timer::Callback {
public: public:
XserverDesktop(int screenIndex, XserverDesktop(int screenIndex,
std::list<network::SocketListener*> listeners_, std::list<network::SocketListener*> listeners_,
std::list<network::SocketListener*> httpListeners_,
const char* name, const rfb::PixelFormat &pf, const char* name, const rfb::PixelFormat &pf,
int width, int height, void* fbptr, int stride); int width, int height, void* fbptr, int stride);
virtual ~XserverDesktop(); virtual ~XserverDesktop();
@ -99,9 +95,6 @@ public:
// rfb::PixelBuffer callbacks // rfb::PixelBuffer callbacks
virtual void grabRegion(const rfb::Region& r); virtual void grabRegion(const rfb::Region& r);
// rdr::Substitutor callback
virtual char* substitute(const char* varName);
// rfb::VNCServerST::QueryConnectionHandler callback // rfb::VNCServerST::QueryConnectionHandler callback
virtual rfb::VNCServerST::queryResult queryConnection(network::Socket* sock, virtual rfb::VNCServerST::queryResult queryConnection(network::Socket* sock,
const char* userName, const char* userName,
@ -121,9 +114,7 @@ private:
int screenIndex; int screenIndex;
rfb::VNCServerST* server; rfb::VNCServerST* server;
rfb::HTTPServer* httpServer;
std::list<network::SocketListener*> listeners; std::list<network::SocketListener*> listeners;
std::list<network::SocketListener*> httpListeners;
bool directFbptr; bool directFbptr;
uint32_t queryConnectId; uint32_t queryConnectId;

View File

@ -37,15 +37,13 @@ Specify the size of the desktop to be created. Default is 1024x768.
.TP .TP
.B \-depth \fIdepth\fP .B \-depth \fIdepth\fP
Specify the pixel depth in bits of the desktop to be created. Default is 24, Specify the pixel depth in bits of the desktop to be created. Default is 24,
other possible values are 8, 15, and 16 - anything else is likely to cause other possible values are 16 and 32. Anything else is likely to cause strange
strange behaviour by applications. behaviour by applications and may prevent the server from starting at all.
. .
.TP .TP
.B \-pixelformat \fIformat\fP .B \-pixelformat \fIformat\fP
Specify pixel format for server to use (BGRnnn or RGBnnn). The default for Specify pixel format for server to use (BGRnnn or RGBnnn). The default for
depth 8 is BGR233 (meaning the most significant two bits represent blue, the depth 16 is RGB565 and for depth 24 and 32 is RGB888.
next three green, and the least significant three represent red), the default
for depth 16 is RGB565 and for depth 24 is RGB888.
. .
.TP .TP
.B \-interface \fIIP address\fP .B \-interface \fIIP address\fP
@ -119,6 +117,11 @@ the \fBvncpasswd\fP(1) utility. The file is accessed each time a connection
comes in, so it can be changed on the fly. comes in, so it can be changed on the fly.
. .
.TP .TP
.B \-KasmPasswordFile \fIpasswd-file\fP
Password file for BasicAuth, created with the \fBkasmvncpasswd\fP utility.
Default \fI~/.kasmpasswd\fP.
.
.TP
.B \-AcceptCutText .B \-AcceptCutText
Accept clipboard updates from clients. Default is on. Accept clipboard updates from clients. Default is on.
. .
@ -318,6 +321,7 @@ Require SSL for websocket connections. Default off, non-SSL allowed.
.TP .TP
.B \-basicAuth \fIuser:pass\fP .B \-basicAuth \fIuser:pass\fP
Username and password for websocket connections. Default empty, no authentication required. Username and password for websocket connections. Default empty, no authentication required.
If the password is empty, read it from the \fB-KasmPasswordFile\fP.
. .
.TP .TP
.B \-SecurityTypes \fIsec-types\fP .B \-SecurityTypes \fIsec-types\fP

View File

@ -155,10 +155,10 @@ void vncExtensionInit(void)
vncExtGeneration = vncGetServerGeneration(); vncExtGeneration = vncGetServerGeneration();
if (vncGetScreenCount() > MAXSCREENS) if (vncGetScreenCount() > MAXSCREENS)
vncFatalError("vncExtensionInit: too many screens"); vncFatalError("vncExtensionInit: too many screens\n");
if (sizeof(ShortRect) != sizeof(struct UpdateRect)) if (sizeof(ShortRect) != sizeof(struct UpdateRect))
vncFatalError("vncExtensionInit: Incompatible ShortRect size"); vncFatalError("vncExtensionInit: Incompatible ShortRect size\n");
vncAddExtension(); vncAddExtension();
@ -193,7 +193,6 @@ void vncExtensionInit(void)
if (!desktop[scr]) { if (!desktop[scr]) {
std::list<network::SocketListener*> listeners; std::list<network::SocketListener*> listeners;
std::list<network::SocketListener*> httpListeners;
if (scr == 0 && vncInetdSock != -1) { if (scr == 0 && vncInetdSock != -1) {
if (network::isSocketListening(vncInetdSock)) if (network::isSocketListening(vncInetdSock))
{ {
@ -247,7 +246,6 @@ void vncExtensionInit(void)
vncSetGlueContext(scr); vncSetGlueContext(scr);
desktop[scr] = new XserverDesktop(scr, desktop[scr] = new XserverDesktop(scr,
listeners, listeners,
httpListeners,
desktopNameStr.buf, desktopNameStr.buf,
pf, pf,
vncGetScreenWidth(), vncGetScreenWidth(),
@ -266,7 +264,7 @@ void vncExtensionInit(void)
vncHooksInit(scr); vncHooksInit(scr);
} }
} catch (rdr::Exception& e) { } catch (rdr::Exception& e) {
vncFatalError("vncExtInit: %s",e.str()); vncFatalError("vncExtInit: %s\n",e.str());
} }
vncRegisterBlockHandlers(); vncRegisterBlockHandlers();
@ -280,7 +278,7 @@ void vncExtensionClose(void)
desktop[scr] = NULL; desktop[scr] = NULL;
} }
} catch (rdr::Exception& e) { } catch (rdr::Exception& e) {
vncFatalError("vncExtInit: %s",e.str()); vncFatalError("vncExtInit: %s\n",e.str());
} }
} }
@ -432,8 +430,13 @@ void vncPostScreenResize(int scrIdx, int success, int width, int height)
{ {
if (success) { if (success) {
// Let the RFB core know of the new dimensions and framebuffer // Let the RFB core know of the new dimensions and framebuffer
try {
desktop[scrIdx]->setFramebuffer(width, height, desktop[scrIdx]->setFramebuffer(width, height,
vncFbptr[scrIdx], vncFbstride[scrIdx]); vncFbptr[scrIdx],
vncFbstride[scrIdx]);
} catch (rdr::Exception& e) {
vncFatalError("vncPostScreenResize: %s\n", e.str());
}
} }
desktop[scrIdx]->unblockUpdates(); desktop[scrIdx]->unblockUpdates();
@ -449,7 +452,7 @@ void vncRefreshScreenLayout(int scrIdx)
try { try {
desktop[scrIdx]->refreshScreenLayout(); desktop[scrIdx]->refreshScreenLayout();
} catch (rdr::Exception& e) { } catch (rdr::Exception& e) {
vncFatalError("%s", e.str()); vncFatalError("vncRefreshScreenLayout: %s\n", e.str());
} }
} }

View File

@ -388,10 +388,12 @@ static inline void add_changed(ScreenPtr pScreen, RegionPtr reg)
vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen); vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen);
if (vncHooksScreen->ignoreHooks) if (vncHooksScreen->ignoreHooks)
return; return;
if (RegionNil(reg))
return;
vncAddChanged(pScreen->myNum, vncAddChanged(pScreen->myNum,
(const struct UpdateRect*)REGION_EXTENTS(pScreen, reg), (const struct UpdateRect*)RegionExtents(reg),
REGION_NUM_RECTS(reg), RegionNumRects(reg),
(const struct UpdateRect*)REGION_RECTS(reg)); (const struct UpdateRect*)RegionRects(reg));
} }
static inline void add_copied(ScreenPtr pScreen, RegionPtr dst, static inline void add_copied(ScreenPtr pScreen, RegionPtr dst,
@ -400,10 +402,12 @@ static inline void add_copied(ScreenPtr pScreen, RegionPtr dst,
vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen); vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen);
if (vncHooksScreen->ignoreHooks) if (vncHooksScreen->ignoreHooks)
return; return;
if (RegionNil(dst))
return;
vncAddCopied(pScreen->myNum, vncAddCopied(pScreen->myNum,
(const struct UpdateRect*)REGION_EXTENTS(pScreen, dst), (const struct UpdateRect*)RegionExtents(dst),
REGION_NUM_RECTS(dst), RegionNumRects(dst),
(const struct UpdateRect*)REGION_RECTS(dst), dx, dy); (const struct UpdateRect*)RegionRects(dst), dx, dy);
} }
static inline Bool is_visible(DrawablePtr drawable) static inline Bool is_visible(DrawablePtr drawable)
@ -538,15 +542,15 @@ static void vncHooksCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
SCREEN_PROLOGUE(pWin->drawable.pScreen, CopyWindow); SCREEN_PROLOGUE(pWin->drawable.pScreen, CopyWindow);
REGION_NULL(pScreen, &copied); RegionNull(&copied);
REGION_COPY(pScreen, &copied, pOldRegion); RegionCopy(&copied, pOldRegion);
screen_box.x1 = 0; screen_box.x1 = 0;
screen_box.y1 = 0; screen_box.y1 = 0;
screen_box.x2 = pScreen->width; screen_box.x2 = pScreen->width;
screen_box.y2 = pScreen->height; screen_box.y2 = pScreen->height;
REGION_INIT(pScreen, &screen_rgn, &screen_box, 1); RegionInitBoxes(&screen_rgn, &screen_box, 1);
dx = pWin->drawable.x - ptOldOrg.x; dx = pWin->drawable.x - ptOldOrg.x;
dy = pWin->drawable.y - ptOldOrg.y; dy = pWin->drawable.y - ptOldOrg.y;
@ -555,18 +559,17 @@ static void vncHooksCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
// We also need to copy with changes to the Window's clipping region. // We also need to copy with changes to the Window's clipping region.
// Finally, make sure we don't get copies to or from regions outside // Finally, make sure we don't get copies to or from regions outside
// the framebuffer. // the framebuffer.
REGION_INTERSECT(pScreen, &copied, &copied, &screen_rgn); RegionIntersect(&copied, &copied, &screen_rgn);
REGION_TRANSLATE(pScreen, &copied, dx, dy); RegionTranslate(&copied, dx, dy);
REGION_INTERSECT(pScreen, &copied, &copied, &screen_rgn); RegionIntersect(&copied, &copied, &screen_rgn);
REGION_INTERSECT(pScreen, &copied, &copied, &pWin->borderClip); RegionIntersect(&copied, &copied, &pWin->borderClip);
(*pScreen->CopyWindow) (pWin, ptOldOrg, pOldRegion); (*pScreen->CopyWindow) (pWin, ptOldOrg, pOldRegion);
if (REGION_NOTEMPTY(pScreen, &copied))
add_copied(pScreen, &copied, dx, dy); add_copied(pScreen, &copied, dx, dy);
REGION_UNINIT(pScreen, &copied); RegionUninit(&copied);
REGION_UNINIT(pScreen, &screen_rgn); RegionUninit(&screen_rgn);
SCREEN_EPILOGUE(CopyWindow); SCREEN_EPILOGUE(CopyWindow);
} }
@ -587,8 +590,8 @@ static void vncHooksClearToBackground(WindowPtr pWin, int x, int y, int w,
box.x2 = w ? (box.x1 + w) : (pWin->drawable.x + pWin->drawable.width); box.x2 = w ? (box.x1 + w) : (pWin->drawable.x + pWin->drawable.width);
box.y2 = h ? (box.y1 + h) : (pWin->drawable.y + pWin->drawable.height); box.y2 = h ? (box.y1 + h) : (pWin->drawable.y + pWin->drawable.height);
REGION_INIT(pScreen, &reg, &box, 0); RegionInitBoxes(&reg, &box, 1);
REGION_INTERSECT(pScreen, &reg, &reg, &pWin->clipList); RegionIntersect(&reg, &reg, &pWin->clipList);
(*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures); (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
@ -596,7 +599,7 @@ static void vncHooksClearToBackground(WindowPtr pWin, int x, int y, int w,
add_changed(pScreen, &reg); add_changed(pScreen, &reg);
} }
REGION_UNINIT(pScreen, &reg); RegionUninit(&reg);
SCREEN_EPILOGUE(ClearToBackground); SCREEN_EPILOGUE(ClearToBackground);
} }
@ -788,29 +791,28 @@ static void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
box.y1 = max(pDst->pDrawable->y + yDst, 0); box.y1 = max(pDst->pDrawable->y + yDst, 0);
box.x2 = box.x1 + width; box.x2 = box.x1 + width;
box.y2 = box.y1 + height; box.y2 = box.y1 + height;
REGION_INIT(pScreen, &changed, &box, 0); RegionInitBoxes(&changed, &box, 1);
box.x1 = 0; box.x1 = 0;
box.y1 = 0; box.y1 = 0;
box.x2 = pScreen->width; box.x2 = pScreen->width;
box.y2 = pScreen->height; box.y2 = pScreen->height;
REGION_INIT(pScreen, &fbreg, &box, 0); RegionInitBoxes(&fbreg, &box, 1);
REGION_INTERSECT(pScreen, &changed, &changed, &fbreg); RegionIntersect(&changed, &changed, &fbreg);
REGION_UNINIT(pScreen, &fbreg); RegionUninit(&fbreg);
} else { } else {
REGION_NULL(pScreen, &changed); RegionNull(&changed);
} }
(*ps->Composite)(op, pSrc, pMask, pDst, xSrc, ySrc, (*ps->Composite)(op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height); xMask, yMask, xDst, yDst, width, height);
if (REGION_NOTEMPTY(pScreen, &changed))
add_changed(pScreen, &changed); add_changed(pScreen, &changed);
REGION_UNINIT(pScreen, &changed); RegionUninit(&changed);
RENDER_EPILOGUE(Composite); RENDER_EPILOGUE(Composite);
} }
@ -878,28 +880,27 @@ static void vncHooksGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
RegionRec fbreg; RegionRec fbreg;
changed = GlyphsToRegion(pScreen, nlists, lists, glyphs); changed = GlyphsToRegion(pScreen, nlists, lists, glyphs);
REGION_TRANSLATE(pScreen, changed, RegionTranslate(changed,
pDst->pDrawable->x, pDst->pDrawable->y); pDst->pDrawable->x, pDst->pDrawable->y);
fbbox.x1 = 0; fbbox.x1 = 0;
fbbox.y1 = 0; fbbox.y1 = 0;
fbbox.x2 = pScreen->width; fbbox.x2 = pScreen->width;
fbbox.y2 = pScreen->height; fbbox.y2 = pScreen->height;
REGION_INIT(pScreen, &fbreg, &fbbox, 0); RegionInitBoxes(&fbreg, &fbbox, 1);
REGION_INTERSECT(pScreen, changed, changed, &fbreg); RegionIntersect(changed, changed, &fbreg);
REGION_UNINIT(pScreen, &fbreg); RegionUninit(&fbreg);
} else { } else {
changed = REGION_CREATE(pScreen, NullBox, 0); changed = RegionCreate(NullBox, 0);
} }
(*ps->Glyphs)(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlists, lists, glyphs); (*ps->Glyphs)(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlists, lists, glyphs);
if (REGION_NOTEMPTY(pScreen, changed))
add_changed(pScreen, changed); add_changed(pScreen, changed);
REGION_DESTROY(pScreen, changed); RegionDestroy(changed);
RENDER_EPILOGUE(Glyphs); RENDER_EPILOGUE(Glyphs);
} }
@ -914,15 +915,14 @@ static void vncHooksCompositeRects(CARD8 op, PicturePtr pDst,
if (is_visible(pDst->pDrawable)) { if (is_visible(pDst->pDrawable)) {
changed = RECTS_TO_REGION(pScreen, nRect, rects, CT_NONE); changed = RECTS_TO_REGION(pScreen, nRect, rects, CT_NONE);
} else { } else {
changed = REGION_CREATE(pScreen, NullBox, 0); changed = RegionCreate(NullBox, 0);
} }
(*ps->CompositeRects)(op, pDst, color, nRect, rects); (*ps->CompositeRects)(op, pDst, color, nRect, rects);
if (REGION_NOTEMPTY(pScreen, changed))
add_changed(pScreen, changed); add_changed(pScreen, changed);
REGION_DESTROY(pScreen, changed); RegionDestroy(changed);
RENDER_EPILOGUE(CompositeRects); RENDER_EPILOGUE(CompositeRects);
} }
@ -970,27 +970,26 @@ static void vncHooksTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
box.y1 += pDst->pDrawable->y; box.y1 += pDst->pDrawable->y;
box.x2 += pDst->pDrawable->x; box.x2 += pDst->pDrawable->x;
box.y2 += pDst->pDrawable->y; box.y2 += pDst->pDrawable->y;
REGION_INIT(pScreen, &changed, &box, 0); RegionInitBoxes(&changed, &box, 1);
box.x1 = 0; box.x1 = 0;
box.y1 = 0; box.y1 = 0;
box.x2 = pScreen->width; box.x2 = pScreen->width;
box.y2 = pScreen->height; box.y2 = pScreen->height;
REGION_INIT(pScreen, &fbreg, &box, 0); RegionInitBoxes(&fbreg, &box, 1);
REGION_INTERSECT(pScreen, &changed, &changed, &fbreg); RegionIntersect(&changed, &changed, &fbreg);
REGION_UNINIT(pScreen, &fbreg); RegionUninit(&fbreg);
} else { } else {
REGION_NULL(pScreen, &changed); RegionNull(&changed);
} }
(*ps->Trapezoids)(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps); (*ps->Trapezoids)(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
if (REGION_NOTEMPTY(pScreen, &changed))
add_changed(pScreen, &changed); add_changed(pScreen, &changed);
REGION_UNINIT(pScreen, &changed); RegionUninit(&changed);
RENDER_EPILOGUE(Trapezoids); RENDER_EPILOGUE(Trapezoids);
} }
@ -1036,27 +1035,26 @@ static void vncHooksTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
box.y1 += pDst->pDrawable->y; box.y1 += pDst->pDrawable->y;
box.x2 += pDst->pDrawable->x; box.x2 += pDst->pDrawable->x;
box.y2 += pDst->pDrawable->y; box.y2 += pDst->pDrawable->y;
REGION_INIT(pScreen, &changed, &box, 0); RegionInitBoxes(&changed, &box, 1);
box.x1 = 0; box.x1 = 0;
box.y1 = 0; box.y1 = 0;
box.x2 = pScreen->width; box.x2 = pScreen->width;
box.y2 = pScreen->height; box.y2 = pScreen->height;
REGION_INIT(pScreen, &fbreg, &box, 0); RegionInitBoxes(&fbreg, &box, 1);
REGION_INTERSECT(pScreen, &changed, &changed, &fbreg); RegionIntersect(&changed, &changed, &fbreg);
REGION_UNINIT(pScreen, &fbreg); RegionUninit(&fbreg);
} else { } else {
REGION_NULL(pScreen, &changed); RegionNull(&changed);
} }
(*ps->Triangles)(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris); (*ps->Triangles)(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
if (REGION_NOTEMPTY(pScreen, &changed))
add_changed(pScreen, &changed); add_changed(pScreen, &changed);
REGION_UNINIT(pScreen, &changed); RegionUninit(&changed);
RENDER_EPILOGUE(Triangles); RENDER_EPILOGUE(Triangles);
} }
@ -1097,27 +1095,26 @@ static void vncHooksTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
box.y1 += pDst->pDrawable->y; box.y1 += pDst->pDrawable->y;
box.x2 += pDst->pDrawable->x; box.x2 += pDst->pDrawable->x;
box.y2 += pDst->pDrawable->y; box.y2 += pDst->pDrawable->y;
REGION_INIT(pScreen, &changed, &box, 0); RegionInitBoxes(&changed, &box, 1);
box.x1 = 0; box.x1 = 0;
box.y1 = 0; box.y1 = 0;
box.x2 = pScreen->width; box.x2 = pScreen->width;
box.y2 = pScreen->height; box.y2 = pScreen->height;
REGION_INIT(pScreen, &fbreg, &box, 0); RegionInitBoxes(&fbreg, &box, 1);
REGION_INTERSECT(pScreen, &changed, &changed, &fbreg); RegionIntersect(&changed, &changed, &fbreg);
REGION_UNINIT(pScreen, &fbreg); RegionUninit(&fbreg);
} else { } else {
REGION_NULL(pScreen, &changed); RegionNull(&changed);
} }
(*ps->TriStrip)(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, points); (*ps->TriStrip)(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, points);
if (REGION_NOTEMPTY(pScreen, &changed))
add_changed(pScreen, &changed); add_changed(pScreen, &changed);
REGION_UNINIT(pScreen, &changed); RegionUninit(&changed);
RENDER_EPILOGUE(TriStrip); RENDER_EPILOGUE(TriStrip);
} }
@ -1156,27 +1153,26 @@ static void vncHooksTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
box.y1 += pDst->pDrawable->y; box.y1 += pDst->pDrawable->y;
box.x2 += pDst->pDrawable->x; box.x2 += pDst->pDrawable->x;
box.y2 += pDst->pDrawable->y; box.y2 += pDst->pDrawable->y;
REGION_INIT(pScreen, &changed, &box, 0); RegionInitBoxes(&changed, &box, 1);
box.x1 = 0; box.x1 = 0;
box.y1 = 0; box.y1 = 0;
box.x2 = pScreen->width; box.x2 = pScreen->width;
box.y2 = pScreen->height; box.y2 = pScreen->height;
REGION_INIT(pScreen, &fbreg, &box, 0); RegionInitBoxes(&fbreg, &box, 1);
REGION_INTERSECT(pScreen, &changed, &changed, &fbreg); RegionIntersect(&changed, &changed, &fbreg);
REGION_UNINIT(pScreen, &fbreg); RegionUninit(&fbreg);
} else { } else {
REGION_NULL(pScreen, &changed); RegionNull(&changed);
} }
(*ps->TriFan)(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, points); (*ps->TriFan)(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, points);
if (REGION_NOTEMPTY(pScreen, &changed))
add_changed(pScreen, &changed); add_changed(pScreen, &changed);
REGION_UNINIT(pScreen, &changed); RegionUninit(&changed);
RENDER_EPILOGUE(TriFan); RENDER_EPILOGUE(TriFan);
} }
@ -1365,17 +1361,17 @@ static void vncHooksFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit,
GC_OP_PROLOGUE(pGC, FillSpans); GC_OP_PROLOGUE(pGC, FillSpans);
REGION_NULL(pGC->pScreen, &reg); RegionNull(&reg);
REGION_COPY(pGC->pScreen, &reg, pGC->pCompositeClip); RegionCopy(&reg, pGC->pCompositeClip);
if (pDrawable->type == DRAWABLE_WINDOW) if (pDrawable->type == DRAWABLE_WINDOW)
REGION_INTERSECT(pScreen, &reg, &reg, &((WindowPtr)pDrawable)->borderClip); RegionIntersect(&reg, &reg, &((WindowPtr)pDrawable)->borderClip);
(*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted); (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
add_changed(pGC->pScreen, &reg); add_changed(pGC->pScreen, &reg);
REGION_UNINIT(pGC->pScreen, &reg); RegionUninit(&reg);
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
} }
@ -1391,17 +1387,17 @@ static void vncHooksSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
GC_OP_PROLOGUE(pGC, SetSpans); GC_OP_PROLOGUE(pGC, SetSpans);
REGION_NULL(pGC->pScreen, &reg); RegionNull(&reg);
REGION_COPY(pGC->pScreen, &reg, pGC->pCompositeClip); RegionCopy(&reg, pGC->pCompositeClip);
if (pDrawable->type == DRAWABLE_WINDOW) if (pDrawable->type == DRAWABLE_WINDOW)
REGION_INTERSECT(pScreen, &reg, &reg, &((WindowPtr)pDrawable)->borderClip); RegionIntersect(&reg, &reg, &((WindowPtr)pDrawable)->borderClip);
(*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
add_changed(pGC->pScreen, &reg); add_changed(pGC->pScreen, &reg);
REGION_UNINIT(pGC->pScreen, &reg); RegionUninit(&reg);
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
} }
@ -1422,15 +1418,15 @@ static void vncHooksPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
box.x2 = box.x1 + w; box.x2 = box.x1 + w;
box.y2 = box.y1 + h; box.y2 = box.y1 + h;
REGION_INIT(pGC->pScreen, &reg, &box, 0); RegionInitBoxes(&reg, &box, 1);
REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip); RegionIntersect(&reg, &reg, pGC->pCompositeClip);
(*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, leftPad, format, (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, leftPad, format,
pBits); pBits);
add_changed(pGC->pScreen, &reg); add_changed(pGC->pScreen, &reg);
REGION_UNINIT(pGC->pScreen, &reg); RegionUninit(&reg);
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
} }
@ -1451,7 +1447,7 @@ static RegionPtr vncHooksCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
// Apparently this happens now and then... // Apparently this happens now and then...
if ((w == 0) || (h == 0)) if ((w == 0) || (h == 0))
REGION_NULL(pGC->pScreen, &dst); RegionNull(&dst);
else { else {
BoxRec box; BoxRec box;
@ -1460,10 +1456,10 @@ static RegionPtr vncHooksCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
box.x2 = box.x1 + w; box.x2 = box.x1 + w;
box.y2 = box.y1 + h; box.y2 = box.y1 + h;
REGION_INIT(pGC->pScreen, &dst, &box, 0); RegionInitBoxes(&dst, &box, 1);
} }
REGION_INTERSECT(pGC->pScreen, &dst, &dst, pGC->pCompositeClip); RegionIntersect(&dst, &dst, pGC->pCompositeClip);
// The source of the data has to be something that's on screen. // The source of the data has to be something that's on screen.
if (is_visible(pSrc)) { if (is_visible(pSrc)) {
@ -1474,38 +1470,36 @@ static RegionPtr vncHooksCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
box.x2 = box.x1 + w; box.x2 = box.x1 + w;
box.y2 = box.y1 + h; box.y2 = box.y1 + h;
REGION_INIT(pGC->pScreen, &src, &box, 0); RegionInitBoxes(&src, &box, 1);
if ((pSrc->type == DRAWABLE_WINDOW) && if ((pSrc->type == DRAWABLE_WINDOW) &&
REGION_NOTEMPTY(pScreen, &((WindowPtr)pSrc)->clipList)) { RegionNotEmpty(&((WindowPtr)pSrc)->clipList)) {
REGION_INTERSECT(pScreen, &src, &src, &((WindowPtr)pSrc)->clipList); RegionIntersect(&src, &src, &((WindowPtr)pSrc)->clipList);
} }
REGION_TRANSLATE(pScreen, &src, RegionTranslate(&src,
dstx + pDst->x - srcx - pSrc->x, dstx + pDst->x - srcx - pSrc->x,
dsty + pDst->y - srcy - pSrc->y); dsty + pDst->y - srcy - pSrc->y);
} else { } else {
REGION_NULL(pGC->pScreen, &src); RegionNull(&src);
} }
REGION_NULL(pGC->pScreen, &changed); RegionNull(&changed);
REGION_SUBTRACT(pScreen, &changed, &dst, &src); RegionSubtract(&changed, &dst, &src);
REGION_INTERSECT(pScreen, &dst, &dst, &src); RegionIntersect(&dst, &dst, &src);
ret = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); ret = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
if (REGION_NOTEMPTY(pScreen, &dst))
add_copied(pGC->pScreen, &dst, add_copied(pGC->pScreen, &dst,
dstx + pDst->x - srcx - pSrc->x, dstx + pDst->x - srcx - pSrc->x,
dsty + pDst->y - srcy - pSrc->y); dsty + pDst->y - srcy - pSrc->y);
if (REGION_NOTEMPTY(pScreen, &changed))
add_changed(pGC->pScreen, &changed); add_changed(pGC->pScreen, &changed);
REGION_UNINIT(pGC->pScreen, &dst); RegionUninit(&dst);
REGION_UNINIT(pGC->pScreen, &src); RegionUninit(&src);
REGION_UNINIT(pGC->pScreen, &changed); RegionUninit(&changed);
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -1532,15 +1526,15 @@ static RegionPtr vncHooksCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
box.x2 = box.x1 + w; box.x2 = box.x1 + w;
box.y2 = box.y1 + h; box.y2 = box.y1 + h;
REGION_INIT(pGC->pScreen, &reg, &box, 0); RegionInitBoxes(&reg, &box, 1);
REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip); RegionIntersect(&reg, &reg, pGC->pCompositeClip);
ret = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h, ret = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h,
dstx, dsty, plane); dstx, dsty, plane);
add_changed(pGC->pScreen, &reg); add_changed(pGC->pScreen, &reg);
REGION_UNINIT(pGC->pScreen, &reg); RegionUninit(&reg);
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -1596,14 +1590,14 @@ static void vncHooksPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
box.x2 = maxX + 1 + pDrawable->x; box.x2 = maxX + 1 + pDrawable->x;
box.y2 = maxY + 1 + pDrawable->y; box.y2 = maxY + 1 + pDrawable->y;
REGION_INIT(pGC->pScreen, &reg, &box, 0); RegionInitBoxes(&reg, &box, 1);
REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip); RegionIntersect(&reg, &reg, pGC->pCompositeClip);
(*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pts); (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pts);
add_changed(pGC->pScreen, &reg); add_changed(pGC->pScreen, &reg);
REGION_UNINIT(pGC->pScreen, &reg); RegionUninit(&reg);
out: out:
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -1723,13 +1717,13 @@ static void vncHooksPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
} }
reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE); reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE);
REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip); RegionIntersect(reg, reg, pGC->pCompositeClip);
(*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, ppts); (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, ppts);
add_changed(pGC->pScreen, reg); add_changed(pGC->pScreen, reg);
REGION_DESTROY(pGC->pScreen, reg); RegionDestroy(reg);
out: out:
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -1808,13 +1802,13 @@ static void vncHooksPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
} }
reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE); reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE);
REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip); RegionIntersect(reg, reg, pGC->pCompositeClip);
(*pGC->ops->PolySegment) (pDrawable, pGC, nseg, segs); (*pGC->ops->PolySegment) (pDrawable, pGC, nseg, segs);
add_changed(pGC->pScreen, reg); add_changed(pGC->pScreen, reg);
REGION_DESTROY(pGC->pScreen, reg); RegionDestroy(reg);
out: out:
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -1897,13 +1891,13 @@ static void vncHooksPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
} }
reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE); reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE);
REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip); RegionIntersect(reg, reg, pGC->pCompositeClip);
(*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, rects); (*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, rects);
add_changed(pGC->pScreen, reg); add_changed(pGC->pScreen, reg);
REGION_DESTROY(pGC->pScreen, reg); RegionDestroy(reg);
out: out:
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -1972,13 +1966,13 @@ static void vncHooksPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs,
} }
reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE); reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE);
REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip); RegionIntersect(reg, reg, pGC->pCompositeClip);
(*pGC->ops->PolyArc) (pDrawable, pGC, narcs, arcs); (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, arcs);
add_changed(pGC->pScreen, reg); add_changed(pGC->pScreen, reg);
REGION_DESTROY(pGC->pScreen, reg); RegionDestroy(reg);
out: out:
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -2035,14 +2029,14 @@ static void vncHooksFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape,
box.x2 = maxX + 1 + pDrawable->x; box.x2 = maxX + 1 + pDrawable->x;
box.y2 = maxY + 1 + pDrawable->y; box.y2 = maxY + 1 + pDrawable->y;
REGION_INIT(pGC->pScreen, &reg, &box, 0); RegionInitBoxes(&reg, &box, 1);
REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip); RegionIntersect(&reg, &reg, pGC->pCompositeClip);
(*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pts); (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pts);
add_changed(pGC->pScreen, &reg); add_changed(pGC->pScreen, &reg);
REGION_UNINIT(pGC->pScreen, &reg); RegionUninit(&reg);
out: out:
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -2101,13 +2095,13 @@ static void vncHooksPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrects,
} }
reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE); reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE);
REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip); RegionIntersect(reg, reg, pGC->pCompositeClip);
(*pGC->ops->PolyFillRect) (pDrawable, pGC, nrects, rects); (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrects, rects);
add_changed(pGC->pScreen, reg); add_changed(pGC->pScreen, reg);
REGION_DESTROY(pGC->pScreen, reg); RegionDestroy(reg);
out: out:
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -2176,13 +2170,13 @@ static void vncHooksPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs,
} }
reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE); reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE);
REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip); RegionIntersect(reg, reg, pGC->pCompositeClip);
(*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, arcs); (*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, arcs);
add_changed(pGC->pScreen, reg); add_changed(pGC->pScreen, reg);
REGION_DESTROY(pGC->pScreen, reg); RegionDestroy(reg);
out: out:
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -2227,14 +2221,14 @@ static int vncHooksPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box); GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box);
REGION_INIT(pGC->pScreen, &reg, &box, 0); RegionInitBoxes(&reg, &box, 1);
REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip); RegionIntersect(&reg, &reg, pGC->pCompositeClip);
ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars); ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars);
add_changed(pGC->pScreen, &reg); add_changed(pGC->pScreen, &reg);
REGION_UNINIT(pGC->pScreen, &reg); RegionUninit(&reg);
out: out:
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -2261,14 +2255,14 @@ static int vncHooksPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box); GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box);
REGION_INIT(pGC->pScreen, &reg, &box, 0); RegionInitBoxes(&reg, &box, 1);
REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip); RegionIntersect(&reg, &reg, pGC->pCompositeClip);
ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars); ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars);
add_changed(pGC->pScreen, &reg); add_changed(pGC->pScreen, &reg);
REGION_UNINIT(pGC->pScreen, &reg); RegionUninit(&reg);
out: out:
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -2294,14 +2288,14 @@ static void vncHooksImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box); GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box);
REGION_INIT(pGC->pScreen, &reg, &box, 0); RegionInitBoxes(&reg, &box, 1);
REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip); RegionIntersect(&reg, &reg, pGC->pCompositeClip);
(*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars); (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars);
add_changed(pGC->pScreen, &reg); add_changed(pGC->pScreen, &reg);
REGION_UNINIT(pGC->pScreen, &reg); RegionUninit(&reg);
out: out:
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -2325,14 +2319,14 @@ static void vncHooksImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box); GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box);
REGION_INIT(pGC->pScreen, &reg, &box, 0); RegionInitBoxes(&reg, &box, 1);
REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip); RegionIntersect(&reg, &reg, pGC->pCompositeClip);
(*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars); (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars);
add_changed(pGC->pScreen, &reg); add_changed(pGC->pScreen, &reg);
REGION_UNINIT(pGC->pScreen, &reg); RegionUninit(&reg);
out: out:
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -2357,14 +2351,14 @@ static void vncHooksImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x,
GetTextBoundingRect(pDrawable, pGC->font, x, y, nglyph, &box); GetTextBoundingRect(pDrawable, pGC->font, x, y, nglyph, &box);
REGION_INIT(pGC->pScreen, &reg, &box, 0); RegionInitBoxes(&reg, &box, 1);
REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip); RegionIntersect(&reg, &reg, pGC->pCompositeClip);
(*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
add_changed(pGC->pScreen, &reg); add_changed(pGC->pScreen, &reg);
REGION_UNINIT(pGC->pScreen, &reg); RegionUninit(&reg);
out: out:
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -2389,14 +2383,14 @@ static void vncHooksPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x,
GetTextBoundingRect(pDrawable, pGC->font, x, y, nglyph, &box); GetTextBoundingRect(pDrawable, pGC->font, x, y, nglyph, &box);
REGION_INIT(pGC->pScreen, &reg, &box, 0); RegionInitBoxes(&reg, &box, 1);
REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip); RegionIntersect(&reg, &reg, pGC->pCompositeClip);
(*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
add_changed(pGC->pScreen, &reg); add_changed(pGC->pScreen, &reg);
REGION_UNINIT(pGC->pScreen, &reg); RegionUninit(&reg);
out: out:
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
@ -2419,14 +2413,14 @@ static void vncHooksPushPixels(GCPtr pGC, PixmapPtr pBitMap,
box.x2 = box.x1 + w; box.x2 = box.x1 + w;
box.y2 = box.y1 + h; box.y2 = box.y1 + h;
REGION_INIT(pGC->pScreen, &reg, &box, 0); RegionInitBoxes(&reg, &box, 1);
REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip); RegionIntersect(&reg, &reg, pGC->pCompositeClip);
(*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y); (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y);
add_changed(pGC->pScreen, &reg); add_changed(pGC->pScreen, &reg);
REGION_UNINIT(pGC->pScreen, &reg); RegionUninit(&reg);
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
} }

View File

@ -596,7 +596,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
if (displayNumFree(displayNum)) break; if (displayNumFree(displayNum)) break;
if (displayNum == 100) if (displayNum == 100)
FatalError("Xvnc error: no free display number for -inetd"); FatalError("Xvnc error: no free display number for -inetd\n");
} }
display = displayNumStr; display = displayNumStr;
@ -639,6 +639,20 @@ ddxProcessArgument(int argc, char *argv[], int i)
exit(0); exit(0);
} }
/* We need to resolve an ambiguity for booleans */
if (argv[i][0] == '-' && i+1 < argc &&
vncIsParamBool(&argv[i][1])) {
if ((strcasecmp(argv[i+1], "0") == 0) ||
(strcasecmp(argv[i+1], "1") == 0) ||
(strcasecmp(argv[i+1], "true") == 0) ||
(strcasecmp(argv[i+1], "false") == 0) ||
(strcasecmp(argv[i+1], "yes") == 0) ||
(strcasecmp(argv[i+1], "no") == 0)) {
vncSetParam(&argv[i][1], argv[i+1]);
return 2;
}
}
if (vncSetParamSimple(argv[i])) if (vncSetParamSimple(argv[i]))
return 1; return 1;
@ -1003,8 +1017,8 @@ xf86SetRootClip (ScreenPtr pScreen, Bool enable)
{ {
RegionPtr borderVisible; RegionPtr borderVisible;
borderVisible = REGION_CREATE(pScreen, NullBox, 1); borderVisible = RegionCreate(NullBox, 1);
REGION_SUBTRACT(pScreen, borderVisible, RegionSubtract(borderVisible,
&pWin->borderClip, &pWin->winSize); &pWin->borderClip, &pWin->winSize);
pWin->valdata->before.borderVisible = borderVisible; pWin->valdata->before.borderVisible = borderVisible;
} }
@ -1013,7 +1027,7 @@ xf86SetRootClip (ScreenPtr pScreen, Bool enable)
} }
/* /*
* Use REGION_BREAK to avoid optimizations in ValidateTree * Use RegionBreak to avoid optimizations in ValidateTree
* that assume the root borderClip can't change well, normally * that assume the root borderClip can't change well, normally
* it doesn't...) * it doesn't...)
*/ */
@ -1023,18 +1037,18 @@ xf86SetRootClip (ScreenPtr pScreen, Bool enable)
box.y1 = 0; box.y1 = 0;
box.x2 = pScreen->width; box.x2 = pScreen->width;
box.y2 = pScreen->height; box.y2 = pScreen->height;
REGION_INIT (pScreen, &pWin->winSize, &box, 1); RegionInit(&pWin->winSize, &box, 1);
REGION_INIT (pScreen, &pWin->borderSize, &box, 1); RegionInit(&pWin->borderSize, &box, 1);
if (WasViewable) if (WasViewable)
REGION_RESET(pScreen, &pWin->borderClip, &box); RegionReset(&pWin->borderClip, &box);
pWin->drawable.width = pScreen->width; pWin->drawable.width = pScreen->width;
pWin->drawable.height = pScreen->height; pWin->drawable.height = pScreen->height;
REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); RegionBreak(&pWin->clipList);
} }
else else
{ {
REGION_EMPTY(pScreen, &pWin->borderClip); RegionEmpty(&pWin->borderClip);
REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); RegionBreak(&pWin->clipList);
} }
ResizeChildrenWinSize (pWin, 0, 0, 0, 0); ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
@ -1577,16 +1591,6 @@ vfbScreenInit(ScreenPtr pScreen, int argc, char **argv)
miSetPixmapDepths(); miSetPixmapDepths();
switch (pvfb->fb.depth) { switch (pvfb->fb.depth) {
case 8:
miSetVisualTypesAndMasks (8,
((1 << StaticGray) |
(1 << GrayScale) |
(1 << StaticColor) |
(1 << PseudoColor) |
(1 << TrueColor) |
(1 << DirectColor)),
8, PseudoColor, 0, 0, 0);
break;
case 16: case 16:
miSetVisualTypesAndMasks (16, miSetVisualTypesAndMasks (16,
((1 << TrueColor) | ((1 << TrueColor) |
@ -1804,7 +1808,7 @@ InitOutput(ScreenInfo *scrInfo, int argc, char **argv)
{ {
if (-1 == AddScreen(vfbScreenInit, argc, argv)) if (-1 == AddScreen(vfbScreenInit, argc, argv))
{ {
FatalError("Couldn't add screen %d", i); FatalError("Couldn't add screen %d\n", i);
} }
} }

View File

@ -1,91 +0,0 @@
diff -up xserver/configure.ac.vnc xserver/configure.ac
--- xserver/configure.ac.vnc 2011-05-11 11:19:24.410708163 +0200
+++ xserver/configure.ac 2011-05-11 11:19:26.409635824 +0200
@@ -30,7 +30,6 @@ AC_INIT([xorg-server], 1.10.1.901, [http
RELEASE_DATE="2011-05-06"
AC_CONFIG_SRCDIR([Makefile.am])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
-AM_MAINTAINER_MODE
# Require xorg-macros minimum of 1.10 for XORG_CHECK_SGML_DOCTOOLS
m4_ifndef([XORG_MACROS_VERSION],
@@ -65,6 +64,7 @@ dnl forcing an entire recompile.x
AC_CONFIG_HEADERS(include/version-config.h)
AM_PROG_AS
+AC_PROG_CXX
AC_PROG_LN_S
AC_LIBTOOL_WIN32_DLL
AC_DISABLE_STATIC
@@ -1513,6 +1513,10 @@ if test "x$XVFB" = xyes; then
AC_SUBST([XVFB_SYS_LIBS])
fi
+dnl Xvnc DDX
+AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XEXT_INC $FB_INC $MI_INC $RENDER_INC $RANDR_INC"])
+AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"])
+AC_SUBST([XVNC_SYS_LIBS], ["$GLX_SYS_LIBS"])
dnl Xnest DDX
@@ -1551,6 +1555,8 @@ xorg_bus_linuxpci=no
xorg_bus_bsdpci=no
xorg_bus_sparc=no
+AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+
if test "x$XORG" = xyes; then
XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
@@ -1797,7 +1803,6 @@ if test "x$XORG" = xyes; then
AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
AC_DEFINE(XFree86LOADER, 1, [Building loadable XFree86 server])
- AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs])
AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions])
AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
@@ -2259,6 +2264,7 @@ hw/dmx/Makefile
hw/dmx/man/Makefile
hw/vfb/Makefile
hw/vfb/man/Makefile
+hw/vnc/Makefile
hw/xnest/Makefile
hw/xnest/man/Makefile
hw/xwin/Makefile
diff -up xserver/hw/Makefile.am.vnc xserver/hw/Makefile.am
--- xserver/hw/Makefile.am.vnc 2011-05-11 11:19:24.476705776 +0200
+++ xserver/hw/Makefile.am 2011-05-11 11:19:26.409635824 +0200
@@ -33,7 +33,8 @@ SUBDIRS = \
$(XNEST_SUBDIRS) \
$(DMX_SUBDIRS) \
$(KDRIVE_SUBDIRS) \
- $(XQUARTZ_SUBDIRS)
+ $(XQUARTZ_SUBDIRS) \
+ vnc
DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive
diff -up xserver/mi/miinitext.c.vnc xserver/mi/miinitext.c
--- xserver/mi/miinitext.c.vnc 2011-05-11 11:19:24.549703133 +0200
+++ xserver/mi/miinitext.c 2011-05-11 11:19:42.022070885 +0200
@@ -263,6 +263,9 @@ extern void DamageExtensionInit(INITARGS
extern void CompositeExtensionInit(INITARGS);
#endif
extern void GEExtensionInit(INITARGS);
+#ifdef KASMVNC
+extern void vncExtensionInit(INITARGS);
+#endif
/* The following is only a small first step towards run-time
* configurable extensions.
@@ -433,6 +436,9 @@ InitExtensions(int argc, char *argv[])
#ifdef XF86BIGFONT
if (!noXFree86BigfontExtension) XFree86BigfontExtensionInit();
#endif
+#ifdef KASMVNC
+ vncExtensionInit();
+#endif
#if !defined(NO_HW_ONLY_EXTS)
#if defined(XF86VIDMODE)
if (!noXFree86VidModeExtension) XFree86VidModeExtensionInit();

View File

@ -1,91 +0,0 @@
diff -up xserver/configure.ac.vnc xserver/configure.ac
--- xserver/configure.ac.vnc 2012-08-28 14:08:11.523694314 +0200
+++ xserver/configure.ac 2012-08-28 14:08:59.122696574 +0200
@@ -30,7 +30,6 @@ AC_INIT([xorg-server], 1.11.4, [https://
RELEASE_DATE="2012-01-27"
AC_CONFIG_SRCDIR([Makefile.am])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
-AM_MAINTAINER_MODE
# Require xorg-macros minimum of 1.14 for XORG_COMPILER_BRAND in XORG_DEFAULT_OPTIONS
m4_ifndef([XORG_MACROS_VERSION],
@@ -72,6 +71,7 @@ dnl forcing an entire recompile.x
AC_CONFIG_HEADERS(include/version-config.h)
AM_PROG_AS
+AC_PROG_CXX
AC_PROG_LN_S
AC_LIBTOOL_WIN32_DLL
AC_DISABLE_STATIC
@@ -1476,6 +1476,10 @@ if test "x$XVFB" = xyes; then
AC_SUBST([XVFB_SYS_LIBS])
fi
+dnl Xvnc DDX
+AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XEXT_INC $FB_INC $MI_INC $RENDER_INC $RANDR_INC"])
+AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"])
+AC_SUBST([XVNC_SYS_LIBS], ["$GLX_SYS_LIBS"])
dnl Xnest DDX
@@ -1514,6 +1518,8 @@ xorg_bus_linuxpci=no
xorg_bus_bsdpci=no
xorg_bus_sparc=no
+AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+
if test "x$XORG" = xyes; then
XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
@@ -1750,7 +1756,6 @@ if test "x$XORG" = xyes; then
AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
AC_DEFINE(XFree86LOADER, 1, [Building loadable XFree86 server])
- AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs])
AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions])
AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
@@ -2217,6 +2222,7 @@ hw/dmx/Makefile
hw/dmx/man/Makefile
hw/vfb/Makefile
hw/vfb/man/Makefile
+hw/vnc/Makefile
hw/xnest/Makefile
hw/xnest/man/Makefile
hw/xwin/Makefile
diff -up xserver/hw/Makefile.am.vnc xserver/hw/Makefile.am
--- xserver/hw/Makefile.am.vnc 2012-08-28 14:08:12.554694327 +0200
+++ xserver/hw/Makefile.am 2012-08-28 14:08:59.123696574 +0200
@@ -33,7 +33,8 @@ SUBDIRS = \
$(XNEST_SUBDIRS) \
$(DMX_SUBDIRS) \
$(KDRIVE_SUBDIRS) \
- $(XQUARTZ_SUBDIRS)
+ $(XQUARTZ_SUBDIRS) \
+ vnc
DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive
diff -up xserver/mi/miinitext.c.vnc xserver/mi/miinitext.c
--- xserver/mi/miinitext.c.vnc 2012-08-28 14:08:13.063694337 +0200
+++ xserver/mi/miinitext.c 2012-08-28 14:08:59.123696574 +0200
@@ -263,6 +263,9 @@ extern void DamageExtensionInit(INITARGS
extern void CompositeExtensionInit(INITARGS);
#endif
extern void GEExtensionInit(INITARGS);
+#ifdef KASMVNC
+extern void vncExtensionInit(INITARGS);
+#endif
/* The following is only a small first step towards run-time
* configurable extensions.
@@ -433,6 +436,9 @@ InitExtensions(int argc, char *argv[])
#ifdef XF86BIGFONT
if (!noXFree86BigfontExtension) XFree86BigfontExtensionInit();
#endif
+#ifdef KASMVNC
+ vncExtensionInit();
+#endif
#if !defined(NO_HW_ONLY_EXTS)
#if defined(XF86VIDMODE)
if (!noXFree86VidModeExtension) XFree86VidModeExtensionInit();

View File

@ -1,91 +0,0 @@
diff -up xserver/configure.ac.vnc xserver/configure.ac
--- xserver/configure.ac.vnc 2012-08-28 15:01:35.142325880 +0200
+++ xserver/configure.ac 2012-08-28 15:02:06.292300682 +0200
@@ -30,7 +30,6 @@ AC_INIT([xorg-server], 1.12.4, [https://
RELEASE_DATE="2012-08-27"
AC_CONFIG_SRCDIR([Makefile.am])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
-AM_MAINTAINER_MODE
# Require xorg-macros minimum of 1.14 for XORG_COMPILER_BRAND in XORG_DEFAULT_OPTIONS
m4_ifndef([XORG_MACROS_VERSION],
@@ -72,6 +71,7 @@ dnl forcing an entire recompile.x
AC_CONFIG_HEADERS(include/version-config.h)
AM_PROG_AS
+AC_PROG_CXX
AC_PROG_LN_S
AC_LIBTOOL_WIN32_DLL
AC_DISABLE_STATIC
@@ -1493,6 +1493,10 @@ if test "x$XVFB" = xyes; then
AC_SUBST([XVFB_SYS_LIBS])
fi
+dnl Xvnc DDX
+AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XEXT_INC $FB_INC $MI_INC $RENDER_INC $RANDR_INC"])
+AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"])
+AC_SUBST([XVNC_SYS_LIBS], ["$GLX_SYS_LIBS"])
dnl Xnest DDX
@@ -1527,6 +1531,8 @@ if test "x$XORG" = xauto; then
fi
AC_MSG_RESULT([$XORG])
+AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+
if test "x$XORG" = xyes; then
XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
@@ -1743,7 +1749,6 @@ if test "x$XORG" = xyes; then
AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
AC_DEFINE(XFree86LOADER, 1, [Building loadable XFree86 server])
- AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs])
AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions])
AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
@@ -2209,6 +2214,7 @@ hw/dmx/Makefile
hw/dmx/man/Makefile
hw/vfb/Makefile
hw/vfb/man/Makefile
+hw/vnc/Makefile
hw/xnest/Makefile
hw/xnest/man/Makefile
hw/xwin/Makefile
diff -up xserver/hw/Makefile.am.vnc xserver/hw/Makefile.am
--- xserver/hw/Makefile.am.vnc 2012-08-28 15:01:35.225325813 +0200
+++ xserver/hw/Makefile.am 2012-08-28 15:02:06.292300682 +0200
@@ -33,7 +33,8 @@ SUBDIRS = \
$(XNEST_SUBDIRS) \
$(DMX_SUBDIRS) \
$(KDRIVE_SUBDIRS) \
- $(XQUARTZ_SUBDIRS)
+ $(XQUARTZ_SUBDIRS) \
+ vnc
DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive
diff -up xserver/mi/miinitext.c.vnc xserver/mi/miinitext.c
--- xserver/mi/miinitext.c.vnc 2012-08-28 15:01:35.311325743 +0200
+++ xserver/mi/miinitext.c 2012-08-28 15:02:06.293300681 +0200
@@ -266,6 +266,9 @@ extern void DamageExtensionInit(INITARGS
extern void CompositeExtensionInit(INITARGS);
#endif
extern void GEExtensionInit(INITARGS);
+#ifdef KASMVNC
+extern void vncExtensionInit(INITARGS);
+#endif
/* The following is only a small first step towards run-time
* configurable extensions.
@@ -449,6 +452,9 @@ InitExtensions(int argc, char *argv[])
if (!noXFree86BigfontExtension)
XFree86BigfontExtensionInit();
#endif
+#ifdef KASMVNC
+ vncExtensionInit();
+#endif
#if !defined(NO_HW_ONLY_EXTS)
#if defined(XF86VIDMODE)
if (!noXFree86VidModeExtension)

View File

@ -1,92 +0,0 @@
diff -up xserver/configure.ac.vnc xserver/configure.ac
--- xserver/configure.ac.vnc 2012-08-28 15:35:23.778810954 +0200
+++ xserver/configure.ac 2012-08-28 15:54:46.396743431 +0200
@@ -31,7 +31,6 @@ RELEASE_DATE="2012-08-21"
RELEASE_NAME="Splashing Orca"
AC_CONFIG_SRCDIR([Makefile.am])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
-AM_MAINTAINER_MODE
# Require xorg-macros minimum of 1.14 for XORG_COMPILER_BRAND in XORG_DEFAULT_OPTIONS
m4_ifndef([XORG_MACROS_VERSION],
@@ -73,6 +72,7 @@ dnl forcing an entire recompile.x
AC_CONFIG_HEADERS(include/version-config.h)
AM_PROG_AS
+AC_PROG_CXX
AC_PROG_LN_S
AC_LIBTOOL_WIN32_DLL
AC_DISABLE_STATIC
@@ -1561,6 +1561,10 @@ if test "x$XVFB" = xyes; then
AC_SUBST([XVFB_SYS_LIBS])
fi
+dnl Xvnc DDX
+AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XSERVER_CFLAGS"])
+AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"])
+AC_SUBST([XVNC_SYS_LIBS], ["$GLX_SYS_LIBS"])
dnl Xnest DDX
@@ -1596,6 +1600,8 @@ if test "x$XORG" = xauto; then
fi
AC_MSG_RESULT([$XORG])
+AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+
if test "x$XORG" = xyes; then
XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
@@ -1815,7 +1821,6 @@ if test "x$XORG" = xyes; then
AC_DEFINE(XORG_SERVER, 1, [Building Xorg server])
AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
- AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs])
AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions])
AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
@@ -2280,6 +2285,7 @@ hw/dmx/Makefile
hw/dmx/man/Makefile
hw/vfb/Makefile
hw/vfb/man/Makefile
+hw/vnc/Makefile
hw/xnest/Makefile
hw/xnest/man/Makefile
hw/xwin/Makefile
diff -up xserver/hw/Makefile.am.vnc xserver/hw/Makefile.am
--- xserver/hw/Makefile.am.vnc 2012-08-28 15:35:23.856810890 +0200
+++ xserver/hw/Makefile.am 2012-08-28 15:35:42.272795917 +0200
@@ -33,7 +33,8 @@ SUBDIRS = \
$(XNEST_SUBDIRS) \
$(DMX_SUBDIRS) \
$(KDRIVE_SUBDIRS) \
- $(XQUARTZ_SUBDIRS)
+ $(XQUARTZ_SUBDIRS) \
+ vnc
DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive
diff -up xserver/mi/miinitext.c.vnc xserver/mi/miinitext.c
--- xserver/mi/miinitext.c.vnc 2012-08-28 15:35:23.000000000 +0200
+++ xserver/mi/miinitext.c 2012-09-05 15:07:40.714953972 +0200
@@ -112,6 +112,10 @@ SOFTWARE.
#include "micmap.h"
#include "globals.h"
+#ifdef KASMVNC
+extern void vncExtensionInit(void);
+#endif
+
/* The following is only a small first step towards run-time
* configurable extensions.
*/
@@ -238,6 +242,9 @@ EnableDisableExtensionError(const char *
/* List of built-in (statically linked) extensions */
static ExtensionModule staticExtensions[] = {
+#ifdef KASMVNC
+ {vncExtensionInit, "VNC-EXTENSION", NULL},
+#endif
{GEExtensionInit, "Generic Event Extension", &noGEExtension},
{ShapeExtensionInit, "SHAPE", NULL},
#ifdef MITSHM

View File

@ -1,137 +0,0 @@
diff -up xserver/configure.ac.vnc xserver/configure.ac
--- xserver/configure.ac.vnc 2013-04-09 16:35:38.000000000 +0200
+++ xserver/configure.ac 2013-04-09 18:16:31.000000000 +0200
@@ -72,6 +72,7 @@ dnl forcing an entire recompile.x
AC_CONFIG_HEADERS(include/version-config.h)
AM_PROG_AS
+AC_PROG_CXX
AC_PROG_LN_S
AC_LIBTOOL_WIN32_DLL
AC_DISABLE_STATIC
@@ -1573,6 +1574,10 @@ if test "x$XVFB" = xyes; then
AC_SUBST([XVFB_SYS_LIBS])
fi
+dnl Xvnc DDX
+AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XSERVER_CFLAGS"])
+AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"])
+AC_SUBST([XVNC_SYS_LIBS], ["$GLX_SYS_LIBS"])
dnl Xnest DDX
@@ -1608,6 +1613,8 @@ if test "x$XORG" = xauto; then
fi
AC_MSG_RESULT([$XORG])
+AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+
if test "x$XORG" = xyes; then
XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
@@ -1827,7 +1834,6 @@ if test "x$XORG" = xyes; then
AC_DEFINE(XORG_SERVER, 1, [Building Xorg server])
AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
- AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs])
AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions])
AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
@@ -2292,6 +2298,7 @@ hw/dmx/Makefile
hw/dmx/man/Makefile
hw/vfb/Makefile
hw/vfb/man/Makefile
+hw/vnc/Makefile
hw/xnest/Makefile
hw/xnest/man/Makefile
hw/xwin/Makefile
diff -up xserver/hw/Makefile.am.vnc xserver/hw/Makefile.am
--- xserver/hw/Makefile.am.vnc 2013-04-09 16:36:46.000000000 +0200
+++ xserver/hw/Makefile.am 2013-04-09 18:16:31.000000000 +0200
@@ -33,7 +33,8 @@ SUBDIRS = \
$(XNEST_SUBDIRS) \
$(DMX_SUBDIRS) \
$(KDRIVE_SUBDIRS) \
- $(XQUARTZ_SUBDIRS)
+ $(XQUARTZ_SUBDIRS) \
+ vnc
DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive
diff -up xserver/mi/miinitext.c.vnc xserver/mi/miinitext.c
--- xserver/mi/miinitext.c.vnc 2013-04-09 16:37:21.000000000 +0200
+++ xserver/mi/miinitext.c 2013-04-09 18:16:31.000000000 +0200
@@ -112,6 +112,10 @@ SOFTWARE.
#include "micmap.h"
#include "globals.h"
+#ifdef KASMVNC
+extern void vncExtensionInit(void);
+#endif
+
/* The following is only a small first step towards run-time
* configurable extensions.
*/
@@ -238,6 +242,9 @@ EnableDisableExtensionError(const char *
/* List of built-in (statically linked) extensions */
static ExtensionModule staticExtensions[] = {
+#ifdef KASMVNC
+ {vncExtensionInit, "VNC-EXTENSION", NULL},
+#endif
{GEExtensionInit, "Generic Event Extension", &noGEExtension},
{ShapeExtensionInit, "SHAPE", NULL},
#ifdef MITSHM
diff -up xserver/os/WaitFor.c.vnc xserver/os/WaitFor.c
--- xserver/os/WaitFor.c.vnc 2013-04-10 14:51:13.000000000 +0200
+++ xserver/os/WaitFor.c 2013-04-10 14:55:40.000000000 +0200
@@ -124,6 +124,9 @@ static void DoTimer(OsTimerPtr timer, CA
static void CheckAllTimers(void);
static OsTimerPtr timers = NULL;
+extern void vncWriteBlockHandler(fd_set *fds);
+extern void vncWriteWakeupHandler(int nfds, fd_set *fds);
+
/*****************
* WaitForSomething:
* Make the server suspend until there is
@@ -149,6 +152,7 @@ WaitForSomething(int *pClientsReady)
INT32 timeout = 0;
fd_set clientsReadable;
fd_set clientsWritable;
+ fd_set socketsWritable;
int curclient;
int selecterr;
static int nready;
@@ -207,6 +211,9 @@ WaitForSomething(int *pClientsReady)
XFD_COPYSET(&AllSockets, &LastSelectMask);
}
+ FD_ZERO(&socketsWritable);
+ vncWriteBlockHandler(&socketsWritable);
+
BlockHandler((pointer) &wt, (pointer) &LastSelectMask);
if (NewOutputPending)
FlushAllOutput();
@@ -218,10 +225,20 @@ WaitForSomething(int *pClientsReady)
i = Select(MaxClients, &LastSelectMask, &clientsWritable, NULL, wt);
}
else {
- i = Select(MaxClients, &LastSelectMask, NULL, NULL, wt);
+ if (AnyClientsWriteBlocked)
+ XFD_ORSET(&socketsWritable, &ClientsWriteBlocked, &socketsWritable);
+
+ if (XFD_ANYSET(&socketsWritable)) {
+ i = Select (MaxClients, &LastSelectMask, &socketsWritable, NULL, wt);
+ if (AnyClientsWriteBlocked)
+ XFD_ANDSET(&clientsWritable, &socketsWritable, &ClientsWriteBlocked);
+ } else {
+ i = Select (MaxClients, &LastSelectMask, NULL, NULL, wt);
+ }
}
selecterr = GetErrno();
WakeupHandler(i, (pointer) &LastSelectMask);
+ vncWriteWakeupHandler(i, &socketsWritable);
if (i <= 0) { /* An error or timeout occurred */
if (dispatchException)
return 0;

View File

@ -1,137 +0,0 @@
diff -up xserver/configure.ac.vnc xserver/configure.ac
--- xserver/configure.ac.vnc 2013-04-09 16:35:38.000000000 +0200
+++ xserver/configure.ac 2013-04-09 18:16:31.000000000 +0200
@@ -72,6 +72,7 @@ dnl forcing an entire recompile.x
AC_CONFIG_HEADERS(include/version-config.h)
AM_PROG_AS
+AC_PROG_CXX
AC_PROG_LN_S
AC_LIBTOOL_WIN32_DLL
AC_DISABLE_STATIC
@@ -1573,6 +1573,10 @@ if test "x$XVFB" = xyes; then
AC_SUBST([XVFB_SYS_LIBS])
fi
+dnl Xvnc DDX
+AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XSERVER_CFLAGS"])
+AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"])
+AC_SUBST([XVNC_SYS_LIBS], ["$GLX_SYS_LIBS"])
dnl Xnest DDX
@@ -1608,6 +1612,8 @@ if test "x$XORG" = xauto; then
fi
AC_MSG_RESULT([$XORG])
+AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+
if test "x$XORG" = xyes; then
XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
@@ -1827,7 +1833,6 @@ if test "x$XORG" = xyes; then
AC_DEFINE(XORG_SERVER, 1, [Building Xorg server])
AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
- AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs])
AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions])
AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
@@ -2292,6 +2297,7 @@ hw/dmx/Makefile
hw/dmx/man/Makefile
hw/vfb/Makefile
hw/vfb/man/Makefile
+hw/vnc/Makefile
hw/xnest/Makefile
hw/xnest/man/Makefile
hw/xwin/Makefile
diff -up xserver/hw/Makefile.am.vnc xserver/hw/Makefile.am
--- xserver/hw/Makefile.am.vnc 2013-04-09 16:36:46.000000000 +0200
+++ xserver/hw/Makefile.am 2013-04-09 18:16:31.000000000 +0200
@@ -33,7 +33,8 @@ SUBDIRS = \
$(XNEST_SUBDIRS) \
$(DMX_SUBDIRS) \
$(KDRIVE_SUBDIRS) \
- $(XQUARTZ_SUBDIRS)
+ $(XQUARTZ_SUBDIRS) \
+ vnc
DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive
diff -up xserver/mi/miinitext.c.vnc xserver/mi/miinitext.c
--- xserver/mi/miinitext.c.vnc 2013-04-09 16:37:21.000000000 +0200
+++ xserver/mi/miinitext.c 2013-04-09 18:16:31.000000000 +0200
@@ -112,6 +112,10 @@ SOFTWARE.
#include "micmap.h"
#include "globals.h"
+#ifdef KASMVNC
+extern void vncExtensionInit(void);
+#endif
+
/* The following is only a small first step towards run-time
* configurable extensions.
*/
@@ -238,6 +242,9 @@ EnableDisableExtensionError(const char *
/* List of built-in (statically linked) extensions */
static ExtensionModule staticExtensions[] = {
+#ifdef KASMVNC
+ {vncExtensionInit, "VNC-EXTENSION", NULL},
+#endif
{GEExtensionInit, "Generic Event Extension", &noGEExtension},
{ShapeExtensionInit, "SHAPE", NULL},
#ifdef MITSHM
diff -up xserver/os/WaitFor.c.vnc xserver/os/WaitFor.c
--- xserver/os/WaitFor.c.vnc 2013-04-10 14:51:13.000000000 +0200
+++ xserver/os/WaitFor.c 2013-04-10 14:55:40.000000000 +0200
@@ -124,6 +124,9 @@ static void DoTimer(OsTimerPtr timer, CA
static void CheckAllTimers(void);
static OsTimerPtr timers = NULL;
+extern void vncWriteBlockHandler(fd_set *fds);
+extern void vncWriteWakeupHandler(int nfds, fd_set *fds);
+
/*****************
* WaitForSomething:
* Make the server suspend until there is
@@ -149,6 +152,7 @@ WaitForSomething(int *pClientsReady)
INT32 timeout = 0;
fd_set clientsReadable;
fd_set clientsWritable;
+ fd_set socketsWritable;
int curclient;
int selecterr;
static int nready;
@@ -207,6 +211,9 @@ WaitForSomething(int *pClientsReady)
XFD_COPYSET(&AllSockets, &LastSelectMask);
}
+ FD_ZERO(&socketsWritable);
+ vncWriteBlockHandler(&socketsWritable);
+
BlockHandler((pointer) &wt, (pointer) &LastSelectMask);
if (NewOutputPending)
FlushAllOutput();
@@ -218,10 +225,20 @@ WaitForSomething(int *pClientsReady)
i = Select(MaxClients, &LastSelectMask, &clientsWritable, NULL, wt);
}
else {
- i = Select(MaxClients, &LastSelectMask, NULL, NULL, wt);
+ if (AnyClientsWriteBlocked)
+ XFD_ORSET(&socketsWritable, &ClientsWriteBlocked, &socketsWritable);
+
+ if (XFD_ANYSET(&socketsWritable)) {
+ i = Select (MaxClients, &LastSelectMask, &socketsWritable, NULL, wt);
+ if (AnyClientsWriteBlocked)
+ XFD_ANDSET(&clientsWritable, &socketsWritable, &ClientsWriteBlocked);
+ } else {
+ i = Select (MaxClients, &LastSelectMask, NULL, NULL, wt);
+ }
}
selecterr = GetErrno();
WakeupHandler(i, (pointer) &LastSelectMask);
+ vncWriteWakeupHandler(i, &socketsWritable);
if (i <= 0) { /* An error or timeout occurred */
if (dispatchException)
return 0;

View File

@ -1,90 +0,0 @@
diff -up xserver/configure.ac.vnc xserver/configure.ac
--- xserver/configure.ac.vnc 2011-05-11 11:09:24.923425002 +0200
+++ xserver/configure.ac 2011-05-11 11:09:32.512150522 +0200
@@ -30,7 +30,6 @@ AC_INIT([xorg-server], 1.7.7, [https://b
RELEASE_DATE="2010-05-04"
AC_CONFIG_SRCDIR([Makefile.am])
AM_INIT_AUTOMAKE([dist-bzip2 foreign])
-AM_MAINTAINER_MODE
AC_CONFIG_FILES([
shave
@@ -64,6 +63,7 @@ dnl forcing an entire recompile.x
AC_CONFIG_HEADERS(include/version-config.h)
AC_PROG_CC
+AC_PROG_CXX
AM_PROG_AS
AC_PROG_INSTALL
AC_PROG_LN_S
@@ -1383,6 +1383,9 @@ if test "x$XVFB" = xyes; then
AC_SUBST([XVFB_SYS_LIBS])
fi
+dnl Xvnc DDX
+AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XEXT_INC $FB_INC $MI_INC $RENDER_INC $RANDR_INC"])
+AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"])
dnl Xnest DDX
@@ -1421,6 +1424,8 @@ xorg_bus_linuxpci=no
xorg_bus_bsdpci=no
xorg_bus_sparc=no
+AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+
if test "x$XORG" = xyes; then
XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
@@ -1663,7 +1668,6 @@ if test "x$XORG" = xyes; then
AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
AC_DEFINE(XFree86LOADER, 1, [Building loadable XFree86 server])
- AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs])
AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions])
AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
@@ -2108,6 +2112,7 @@ hw/dmx/input/Makefile
hw/dmx/glxProxy/Makefile
hw/dmx/Makefile
hw/vfb/Makefile
+hw/vnc/Makefile
hw/xnest/Makefile
hw/xwin/Makefile
hw/xquartz/Makefile
diff -up xserver/hw/Makefile.am.vnc xserver/hw/Makefile.am
--- xserver/hw/Makefile.am.vnc 2011-05-11 11:09:24.989422617 +0200
+++ xserver/hw/Makefile.am 2011-05-11 11:09:32.512150522 +0200
@@ -33,7 +33,8 @@ SUBDIRS = \
$(XNEST_SUBDIRS) \
$(DMX_SUBDIRS) \
$(KDRIVE_SUBDIRS) \
- $(XQUARTZ_SUBDIRS)
+ $(XQUARTZ_SUBDIRS) \
+ vnc
DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive
diff -up xserver/mi/miinitext.c.vnc xserver/mi/miinitext.c
--- xserver/mi/miinitext.c.vnc 2011-05-11 11:09:25.089418999 +0200
+++ xserver/mi/miinitext.c 2011-05-11 11:09:50.102514343 +0200
@@ -274,6 +274,9 @@ extern void DamageExtensionInit(INITARGS
extern void CompositeExtensionInit(INITARGS);
#endif
extern void GEExtensionInit(INITARGS);
+#ifdef KASMVNC
+extern void vncExtensionInit(INITARGS);
+#endif
/* The following is only a small first step towards run-time
* configurable extensions.
@@ -454,6 +457,9 @@ InitExtensions(int argc, char *argv[])
#ifdef XF86BIGFONT
if (!noXFree86BigfontExtension) XFree86BigfontExtensionInit();
#endif
+#ifdef KASMVNC
+ vncExtensionInit();
+#endif
#if !defined(NO_HW_ONLY_EXTS)
#if defined(XF86VIDMODE)
if (!noXFree86VidModeExtension) XFree86VidModeExtensionInit();

View File

@ -1,90 +0,0 @@
diff -up xserver/configure.ac.vnc xserver/configure.ac
--- xserver/configure.ac.vnc 2011-05-11 11:11:33.803760465 +0200
+++ xserver/configure.ac 2011-05-11 11:11:40.998500216 +0200
@@ -30,7 +30,6 @@ AC_INIT([xorg-server], 1.8.2, [https://b
RELEASE_DATE="2010-07-01"
AC_CONFIG_SRCDIR([Makefile.am])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
-AM_MAINTAINER_MODE
# Require xorg-macros: XORG_DEFAULT_OPTIONS
m4_ifndef([XORG_MACROS_VERSION],
@@ -64,6 +63,7 @@ dnl forcing an entire recompile.x
AC_CONFIG_HEADERS(include/version-config.h)
AC_PROG_CC
+AC_PROG_CXX
AM_PROG_AS
AC_PROG_INSTALL
AC_PROG_LN_S
@@ -1505,6 +1505,9 @@ if test "x$XVFB" = xyes; then
AC_SUBST([XVFB_SYS_LIBS])
fi
+dnl Xvnc DDX
+AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XEXT_INC $FB_INC $MI_INC $RENDER_INC $RANDR_INC"])
+AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"])
dnl Xnest DDX
@@ -1543,6 +1546,8 @@ xorg_bus_linuxpci=no
xorg_bus_bsdpci=no
xorg_bus_sparc=no
+AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+
if test "x$XORG" = xyes; then
XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
@@ -1787,7 +1792,6 @@ if test "x$XORG" = xyes; then
AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
AC_DEFINE(XFree86LOADER, 1, [Building loadable XFree86 server])
- AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs])
AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions])
AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
@@ -2231,6 +2235,7 @@ hw/dmx/input/Makefile
hw/dmx/glxProxy/Makefile
hw/dmx/Makefile
hw/vfb/Makefile
+hw/vnc/Makefile
hw/xnest/Makefile
hw/xwin/Makefile
hw/xquartz/Makefile
diff -up xserver/hw/Makefile.am.vnc xserver/hw/Makefile.am
--- xserver/hw/Makefile.am.vnc 2011-05-11 11:11:33.867758149 +0200
+++ xserver/hw/Makefile.am 2011-05-11 11:11:40.998500216 +0200
@@ -33,7 +33,8 @@ SUBDIRS = \
$(XNEST_SUBDIRS) \
$(DMX_SUBDIRS) \
$(KDRIVE_SUBDIRS) \
- $(XQUARTZ_SUBDIRS)
+ $(XQUARTZ_SUBDIRS) \
+ vnc
DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive
diff -up xserver/mi/miinitext.c.vnc xserver/mi/miinitext.c
--- xserver/mi/miinitext.c.vnc 2011-05-11 11:11:33.941755471 +0200
+++ xserver/mi/miinitext.c 2011-05-11 11:12:04.454651752 +0200
@@ -274,6 +274,9 @@ extern void DamageExtensionInit(INITARGS
extern void CompositeExtensionInit(INITARGS);
#endif
extern void GEExtensionInit(INITARGS);
+#ifdef KASMVNC
+extern void vncExtensionInit(INITARGS);
+#endif
/* The following is only a small first step towards run-time
* configurable extensions.
@@ -454,6 +457,9 @@ InitExtensions(int argc, char *argv[])
#ifdef XF86BIGFONT
if (!noXFree86BigfontExtension) XFree86BigfontExtensionInit();
#endif
+#ifdef KASMVNC
+ vncExtensionInit();
+#endif
#if !defined(NO_HW_ONLY_EXTS)
#if defined(XF86VIDMODE)
if (!noXFree86VidModeExtension) XFree86VidModeExtensionInit();

View File

@ -1,90 +0,0 @@
diff -up xserver/configure.ac.vnc xserver/configure.ac
--- xserver/configure.ac.vnc 2011-05-11 11:16:50.764292985 +0200
+++ xserver/configure.ac 2011-05-11 11:16:55.675101840 +0200
@@ -30,7 +30,6 @@ AC_INIT([xorg-server], 1.9.5, [https://b
RELEASE_DATE="2011-03-17"
AC_CONFIG_SRCDIR([Makefile.am])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
-AM_MAINTAINER_MODE
# Require xorg-macros minimum of 1.10 for XORG_CHECK_SGML_DOCTOOLS
m4_ifndef([XORG_MACROS_VERSION],
@@ -65,6 +64,7 @@ dnl forcing an entire recompile.x
AC_CONFIG_HEADERS(include/version-config.h)
AC_PROG_CC
+AC_PROG_CXX
AM_PROG_AS
AC_PROG_INSTALL
AC_PROG_LN_S
@@ -1514,6 +1514,9 @@ if test "x$XVFB" = xyes; then
AC_SUBST([XVFB_SYS_LIBS])
fi
+dnl Xvnc DDX
+AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XEXT_INC $FB_INC $MI_INC $RENDER_INC $RANDR_INC"])
+AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"])
dnl Xnest DDX
@@ -1552,6 +1555,8 @@ xorg_bus_linuxpci=no
xorg_bus_bsdpci=no
xorg_bus_sparc=no
+AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+
if test "x$XORG" = xyes; then
XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
@@ -1798,7 +1803,6 @@ if test "x$XORG" = xyes; then
AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
AC_DEFINE(XFree86LOADER, 1, [Building loadable XFree86 server])
- AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs])
AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions])
AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
@@ -2252,6 +2256,7 @@ hw/dmx/input/Makefile
hw/dmx/glxProxy/Makefile
hw/dmx/Makefile
hw/vfb/Makefile
+hw/vnc/Makefile
hw/xnest/Makefile
hw/xwin/Makefile
hw/xwin/glx/Makefile
diff -up xserver/hw/Makefile.am.vnc xserver/hw/Makefile.am
--- xserver/hw/Makefile.am.vnc 2011-05-11 11:16:50.836290382 +0200
+++ xserver/hw/Makefile.am 2011-05-11 11:16:55.675101840 +0200
@@ -33,7 +33,8 @@ SUBDIRS = \
$(XNEST_SUBDIRS) \
$(DMX_SUBDIRS) \
$(KDRIVE_SUBDIRS) \
- $(XQUARTZ_SUBDIRS)
+ $(XQUARTZ_SUBDIRS) \
+ vnc
DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive
diff -up xserver/mi/miinitext.c.vnc xserver/mi/miinitext.c
--- xserver/mi/miinitext.c.vnc 2011-05-11 11:16:50.916287489 +0200
+++ xserver/mi/miinitext.c 2011-05-11 11:17:12.758477353 +0200
@@ -263,6 +263,9 @@ extern void DamageExtensionInit(INITARGS
extern void CompositeExtensionInit(INITARGS);
#endif
extern void GEExtensionInit(INITARGS);
+#ifdef KASMVNC
+extern void vncExtensionInit(INITARGS);
+#endif
/* The following is only a small first step towards run-time
* configurable extensions.
@@ -435,6 +438,9 @@ InitExtensions(int argc, char *argv[])
#ifdef XF86BIGFONT
if (!noXFree86BigfontExtension) XFree86BigfontExtensionInit();
#endif
+#ifdef KASMVNC
+ vncExtensionInit();
+#endif
#if !defined(NO_HW_ONLY_EXTS)
#if defined(XF86VIDMODE)
if (!noXFree86VidModeExtension) XFree86VidModeExtensionInit();

View File

@ -30,12 +30,10 @@ static LogWriter vlog("DIBSectionBuffer");
DIBSectionBuffer::DIBSectionBuffer(HWND window_) DIBSectionBuffer::DIBSectionBuffer(HWND window_)
: bitmap(0), window(window_), device(0) { : bitmap(0), window(window_), device(0) {
memset(&format, 0, sizeof(format));
} }
DIBSectionBuffer::DIBSectionBuffer(HDC device_) DIBSectionBuffer::DIBSectionBuffer(HDC device_)
: bitmap(0), window(0), device(device_) { : bitmap(0), window(0), device(device_) {
memset(&format, 0, sizeof(format));
} }
DIBSectionBuffer::~DIBSectionBuffer() { DIBSectionBuffer::~DIBSectionBuffer() {

Some files were not shown because too many files have changed in this diff Show More