mirror of
https://github.com/kasmtech/KasmVNC.git
synced 2024-11-25 01:24:04 +01:00
commit
e7016550fc
@ -103,9 +103,9 @@ if(NOT DEFINED BUILD_WINVNC)
|
||||
set(BUILD_WINVNC 1)
|
||||
endif()
|
||||
|
||||
# Minimum version is Windows Vista/2008 (6.0)
|
||||
# Minimum version is Windows 7
|
||||
if(WIN32)
|
||||
add_definitions(-D_WIN32_WINNT=0x0600)
|
||||
add_definitions(-D_WIN32_WINNT=0x0601)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P MATCHES 8)
|
||||
|
29
README.md
29
README.md
@ -26,11 +26,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
Future Goals:
|
||||
|
||||
- Support uploads and downloads
|
||||
- Json configuration file
|
||||
- Pre-build Packages for all major Linux distributions
|
||||
- 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.
|
||||
|
||||
```sh
|
||||
# use install script from builder/install/install.sh
|
||||
sudo ./install.sh
|
||||
# install dependencies
|
||||
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
|
||||
|
||||
# create required files
|
||||
touch ~/.Xresources
|
||||
# start kasmvnc to generate the required files and then kill it
|
||||
# it will prompt to set the vnc password
|
||||
# start kasmvnc and set password for remote access
|
||||
vncserver :1 -interface 0.0.0.0
|
||||
# stop kasmvnc to make config changes
|
||||
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
|
||||
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
|
||||
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:
|
||||
|
||||
| Argument | Description |
|
||||
| -------- | ----------- |
|
||||
| depth | Color depth, for jpeg/webp should be 24bit |
|
||||
| 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. |
|
||||
| cert | SSL cert to use for HTTPS |
|
||||
| sslOnly | Disable HTTP |
|
||||
|
@ -6,7 +6,7 @@ Docker CE
|
||||
sudo docker build -t kasmvncbuilder:18.04 -f builder/dockerfile.build .
|
||||
|
||||
# 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
|
||||
cp /tmp/kasmvnc*.tar.gz builder/
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
# Ubuntu applies a million patches, but here we use upstream to simplify matters
|
||||
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
|
||||
#cd kasmvnc
|
||||
@ -23,10 +23,10 @@ sed -i -e '/find_package(FLTK/s@^@#@' \
|
||||
cmake .
|
||||
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
|
||||
patch -Np1 -i ../xserver118.patch
|
||||
patch -Np1 -i ../xserver119.patch
|
||||
autoreconf -i
|
||||
# Configuring Xorg is long and has many distro-specific paths.
|
||||
# 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-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-pic --without-dtrace --disable-static --disable-dri \
|
||||
--with-pic --without-dtrace --disable-dri \
|
||||
--disable-static \
|
||||
--disable-xinerama --disable-xvfb --disable-xnest --disable-xorg \
|
||||
--disable-dmx --disable-xwin --disable-xephyr --disable-kdrive \
|
||||
--disable-config-hal --disable-config-udev \
|
||||
|
@ -5,20 +5,22 @@ RUN sed -i 's$# deb-src$deb-src$' /etc/apt/sources.list
|
||||
RUN apt-get update && \
|
||||
apt-get -y install sudo
|
||||
|
||||
RUN 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 -y install libjpeg-dev libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev
|
||||
RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev
|
||||
RUN apt-get update && apt-get -y install cmake git libjpeg-dev libgnutls28-dev vim wget tightvncserver
|
||||
RUN apt-get update && apt-get -y install libjpeg-dev libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev
|
||||
|
||||
# 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 && 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
|
||||
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 && \
|
||||
dpkg -i libxfont1_1.5.2-4ubuntu2_amd64.deb && \
|
||||
dpkg -i 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 && \
|
||||
# dpkg -i libxfont1_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
|
||||
|
||||
|
@ -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"
|
@ -62,11 +62,11 @@ configure_file(release/maketarball.in release/maketarball)
|
||||
|
||||
set(TARBALL_DEPENDS vncpasswd vncconfig)
|
||||
|
||||
add_custom_target(tarball sh release/maketarball
|
||||
add_custom_target(tarball bash release/maketarball
|
||||
DEPENDS ${TARBALL_DEPENDS}
|
||||
SOURCES release/maketarball)
|
||||
|
||||
add_custom_target(servertarball sh release/maketarball server
|
||||
add_custom_target(servertarball bash release/maketarball server
|
||||
DEPENDS ${TARBALL_DEPENDS}
|
||||
SOURCES release/maketarball)
|
||||
|
||||
|
@ -27,6 +27,9 @@ if(BUILD_STATIC)
|
||||
# gettext is included in libc on many unix systems
|
||||
if(NOT LIBC_HAS_DGETTEXT)
|
||||
set(GETTEXT_LIBRARIES "-Wl,-Bstatic -lintl -liconv -Wl,-Bdynamic")
|
||||
if(APPLE)
|
||||
set(GETTEXT_LIBRARIES "${GETTEXT_LIBRARIES} -framework Carbon")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(GNUTLS_FOUND)
|
||||
@ -44,7 +47,7 @@ if(BUILD_STATIC)
|
||||
set(GNUTLS_LIBRARIES "${GNUTLS_LIBRARIES} -ltasn1")
|
||||
endif()
|
||||
if(NETTLE_LIBRARY)
|
||||
set(GNUTLS_LIBRARIES "${GNUTLS_LIBRARIES} -lnettle -lhogweed -lgmp")
|
||||
set(GNUTLS_LIBRARIES "${GNUTLS_LIBRARIES} -lhogweed -lnettle -lgmp")
|
||||
endif()
|
||||
if(GCRYPT_LIBRARY)
|
||||
set(GNUTLS_LIBRARIES "${GNUTLS_LIBRARIES} -lgcrypt -lgpg-error")
|
||||
@ -118,7 +121,7 @@ endif()
|
||||
if(BUILD_STATIC_GCC)
|
||||
# This ensures that we don't depend on libstdc++ or libgcc_s
|
||||
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)
|
||||
set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -Wl,-Bstatic -lasan -Wl,-Bdynamic -ldl -lm -lpthread")
|
||||
endif()
|
||||
@ -136,7 +139,8 @@ if(BUILD_STATIC_GCC)
|
||||
# these things again
|
||||
set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -lmingw32 -lgcc_eh -lgcc -lmoldname -lmingwex -lmsvcrt")
|
||||
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()
|
||||
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()
|
||||
|
@ -38,11 +38,13 @@
|
||||
#include <sys/un.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <wordexp.h>
|
||||
#include "websocket.h"
|
||||
|
||||
#include <network/TcpSocket.h>
|
||||
#include <rfb/LogWriter.h>
|
||||
#include <rfb/Configuration.h>
|
||||
#include <rfb/ServerCore.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <os/winerrno.h>
|
||||
@ -151,8 +153,7 @@ TcpSocket::TcpSocket(const char *host, int port)
|
||||
hints.ai_next = NULL;
|
||||
|
||||
if ((result = getaddrinfo(host, NULL, &hints, &ai)) != 0) {
|
||||
throw Exception("unable to resolve host by name: %s",
|
||||
gai_strerror(result));
|
||||
throw GAIException("unable to resolve host by name", result);
|
||||
}
|
||||
|
||||
sock = -1;
|
||||
@ -220,7 +221,7 @@ TcpSocket::TcpSocket(const char *host, int port)
|
||||
if (err == 0)
|
||||
throw Exception("No useful address for host");
|
||||
else
|
||||
throw SocketException("unable connect to socket", err);
|
||||
throw SocketException("unable to connect to socket", err);
|
||||
}
|
||||
|
||||
// Take proper ownership of the socket
|
||||
@ -486,6 +487,13 @@ WebsocketListener::WebsocketListener(const struct sockaddr *listenaddr,
|
||||
|
||||
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.cert = cert;
|
||||
settings.key = "";
|
||||
@ -603,8 +611,7 @@ void network::createTcpListeners(std::list<SocketListener*> *listeners,
|
||||
snprintf (service, sizeof (service) - 1, "%d", port);
|
||||
service[sizeof (service) - 1] = '\0';
|
||||
if ((result = getaddrinfo(addr, service, &hints, &ai)) != 0)
|
||||
throw rdr::Exception("unable to resolve listening address: %s",
|
||||
gai_strerror(result));
|
||||
throw GAIException("unable to resolve listening address", result);
|
||||
|
||||
try {
|
||||
createTcpListeners(listeners, ai);
|
||||
@ -612,6 +619,8 @@ void network::createTcpListeners(std::list<SocketListener*> *listeners,
|
||||
freeaddrinfo(ai);
|
||||
throw;
|
||||
}
|
||||
|
||||
freeaddrinfo(ai);
|
||||
}
|
||||
|
||||
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) {
|
||||
throw Exception("unable to resolve host by name: %s",
|
||||
gai_strerror(result));
|
||||
throw GAIException("unable to resolve host by name", result);
|
||||
}
|
||||
|
||||
memcpy (&pattern.address.u.sa, ai->ai_addr, ai->ai_addrlen);
|
||||
|
@ -69,7 +69,7 @@ UnixSocket::UnixSocket(const char *path)
|
||||
}
|
||||
|
||||
if (result == -1)
|
||||
throw SocketException("unable connect to socket", err);
|
||||
throw SocketException("unable to connect to socket", err);
|
||||
|
||||
setFd(sock);
|
||||
}
|
||||
|
@ -878,9 +878,11 @@ ws_ctx_t *do_handshake(int sock) {
|
||||
usleep(10);
|
||||
}
|
||||
|
||||
if (strchr(settings.basicauth, ':')) {
|
||||
const char *colon;
|
||||
if ((colon = strchr(settings.basicauth, ':'))) {
|
||||
const char *hdr = strstr(handshake, "Authorization: Basic ");
|
||||
if (!hdr) {
|
||||
handler_emsg("BasicAuth required, but client didn't send any. 401 Unauth\n");
|
||||
sprintf(response, "HTTP/1.1 401 Unauthorized\r\n"
|
||||
"WWW-Authenticate: Basic realm=\"Websockify\"\r\n"
|
||||
"\r\n");
|
||||
@ -892,6 +894,7 @@ ws_ctx_t *do_handshake(int sock) {
|
||||
hdr += sizeof("Authorization: Basic ") - 1;
|
||||
const char *end = strchr(hdr, '\r');
|
||||
if (!end || end - hdr > 256) {
|
||||
handler_emsg("Client sent invalid BasicAuth, dropping connection\n");
|
||||
free_ws_ctx(ws_ctx);
|
||||
return NULL;
|
||||
}
|
||||
@ -901,13 +904,55 @@ ws_ctx_t *do_handshake(int sock) {
|
||||
tmp[len] = '\0';
|
||||
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"
|
||||
"\r\n");
|
||||
ws_send(ws_ctx, response, strlen(response));
|
||||
free_ws_ctx(ws_ctx);
|
||||
return NULL;
|
||||
}
|
||||
handler_emsg("BasicAuth matched\n");
|
||||
}
|
||||
|
||||
//handler_msg("handshake: %s\n", handshake);
|
||||
|
@ -67,6 +67,7 @@ typedef struct {
|
||||
const char *cert;
|
||||
const char *key;
|
||||
const char *basicauth;
|
||||
const char *passwdfile;
|
||||
int ssl_only;
|
||||
const char *httpdir;
|
||||
} settings_t;
|
||||
|
@ -31,6 +31,9 @@
|
||||
#include <tchar.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
@ -49,38 +52,46 @@ Exception::Exception(const char *format, ...) {
|
||||
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_)
|
||||
: Exception("%s", s), err(err_)
|
||||
{
|
||||
strncat(str_, ": ", len-1-strlen(str_));
|
||||
#ifdef _WIN32
|
||||
// Windows error messages are crap, so use unix ones for common errors.
|
||||
const char* msg = 0;
|
||||
switch (err) {
|
||||
case WSAECONNREFUSED: msg = "Connection refused"; break;
|
||||
case WSAETIMEDOUT: msg = "Connection timed out"; break;
|
||||
case WSAECONNRESET: msg = "Connection reset by peer"; break;
|
||||
case WSAECONNABORTED: msg = "Connection aborted"; break;
|
||||
}
|
||||
if (msg) {
|
||||
strncat(str_, msg, len-1-strlen(str_));
|
||||
} else {
|
||||
#ifdef UNICODE
|
||||
WCHAR* tmsg = new WCHAR[len-strlen(str_)];
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
0, err, 0, tmsg, len-1-strlen(str_), 0);
|
||||
WideCharToMultiByte(CP_ACP, 0, tmsg, wcslen(tmsg)+1,
|
||||
str_+strlen(str_), len-strlen(str_), 0, 0);
|
||||
delete [] tmsg;
|
||||
#else
|
||||
char* currStr = str_+strlen(str_);
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
0, err, 0, currStr, len-1-strlen(str_), 0);
|
||||
#endif
|
||||
int l = strlen(str_);
|
||||
if ((l >= 2) && (str_[l-2] == '\r') && (str_[l-1] == '\n'))
|
||||
wchar_t *currStr = new wchar_t[len-strlen(str_)];
|
||||
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
0, err, 0, currStr, len-1-strlen(str_), 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, currStr, -1, str_+strlen(str_),
|
||||
len-1-strlen(str_), 0, 0);
|
||||
delete [] currStr;
|
||||
|
||||
int l = strlen(str_);
|
||||
if ((l >= 2) && (str_[l-2] == '\r') && (str_[l-1] == '\n'))
|
||||
str_[l-2] = 0;
|
||||
}
|
||||
|
||||
#else
|
||||
strncat(str_, strerror(err), len-1-strlen(str_));
|
||||
|
@ -40,12 +40,17 @@ namespace rdr {
|
||||
struct SystemException : public Exception {
|
||||
int err;
|
||||
SystemException(const char* s, int err_);
|
||||
};
|
||||
};
|
||||
|
||||
struct GAIException : public Exception {
|
||||
int err;
|
||||
GAIException(const char* s, int err_);
|
||||
};
|
||||
|
||||
struct TimedOut : public Exception {
|
||||
TimedOut() : Exception("Timed out") {}
|
||||
};
|
||||
|
||||
|
||||
struct EndOfStream : public Exception {
|
||||
EndOfStream() : Exception("End of stream") {}
|
||||
};
|
||||
|
@ -56,7 +56,7 @@ using namespace rdr;
|
||||
enum { DEFAULT_BUF_SIZE = 8192,
|
||||
MIN_BULK_SIZE = 1024 };
|
||||
|
||||
FdInStream::FdInStream(int fd_, int timeoutms_, int bufSize_,
|
||||
FdInStream::FdInStream(int fd_, int timeoutms_, size_t bufSize_,
|
||||
bool closeWhenDone_)
|
||||
: fd(fd_), closeWhenDone(closeWhenDone_),
|
||||
timeoutms(timeoutms_), blockCallback(0),
|
||||
@ -67,7 +67,7 @@ FdInStream::FdInStream(int fd_, int timeoutms_, int bufSize_,
|
||||
}
|
||||
|
||||
FdInStream::FdInStream(int fd_, FdInStreamBlockCallback* blockCallback_,
|
||||
int bufSize_)
|
||||
size_t bufSize_)
|
||||
: fd(fd_), timeoutms(0), blockCallback(blockCallback_),
|
||||
timing(false), timeWaitedIn100us(5), timedKbits(0),
|
||||
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
|
||||
@ -92,12 +92,12 @@ void FdInStream::setBlockCallback(FdInStreamBlockCallback* blockCallback_)
|
||||
timeoutms = 0;
|
||||
}
|
||||
|
||||
int FdInStream::pos()
|
||||
size_t FdInStream::pos()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
void FdInStream::readBytes(void* data, int length)
|
||||
void FdInStream::readBytes(void* data, size_t length)
|
||||
{
|
||||
if (length < MIN_BULK_SIZE) {
|
||||
InStream::readBytes(data, length);
|
||||
@ -106,7 +106,7 @@ void FdInStream::readBytes(void* data, int length)
|
||||
|
||||
U8* dataPtr = (U8*)data;
|
||||
|
||||
int n = end - ptr;
|
||||
size_t n = end - ptr;
|
||||
if (n > length) n = length;
|
||||
|
||||
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)
|
||||
throw Exception("FdInStream overrun: max itemSize exceeded");
|
||||
@ -135,8 +135,8 @@ int FdInStream::overrun(int itemSize, int nItems, bool wait)
|
||||
end -= ptr - start;
|
||||
ptr = start;
|
||||
|
||||
int bytes_to_read;
|
||||
while (end < start + itemSize) {
|
||||
size_t bytes_to_read;
|
||||
while ((size_t)(end - start) < itemSize) {
|
||||
bytes_to_read = start + bufSize - end;
|
||||
if (!timing) {
|
||||
// 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_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;
|
||||
end += n;
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
size_t nAvail;
|
||||
nAvail = (end - ptr) / itemSize;
|
||||
if (nAvail < nItems)
|
||||
return nAvail;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
@ -171,7 +173,7 @@ int FdInStream::overrun(int itemSize, int nItems, bool wait)
|
||||
// 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;
|
||||
if (timing)
|
||||
|
@ -37,16 +37,17 @@ namespace rdr {
|
||||
|
||||
public:
|
||||
|
||||
FdInStream(int fd, int timeoutms=-1, int bufSize=0,
|
||||
FdInStream(int fd, int timeoutms=-1, size_t bufSize=0,
|
||||
bool closeWhenDone_=false);
|
||||
FdInStream(int fd, FdInStreamBlockCallback* blockCallback, int bufSize=0);
|
||||
FdInStream(int fd, FdInStreamBlockCallback* blockCallback,
|
||||
size_t bufSize=0);
|
||||
virtual ~FdInStream();
|
||||
|
||||
void setTimeout(int timeoutms);
|
||||
void setBlockCallback(FdInStreamBlockCallback* blockCallback);
|
||||
int getFd() { return fd; }
|
||||
int pos();
|
||||
void readBytes(void* data, int length);
|
||||
size_t pos();
|
||||
void readBytes(void* data, size_t length);
|
||||
|
||||
void startTiming();
|
||||
void stopTiming();
|
||||
@ -54,10 +55,10 @@ namespace rdr {
|
||||
unsigned int timeWaited() { return timeWaitedIn100us; }
|
||||
|
||||
protected:
|
||||
int overrun(int itemSize, int nItems, bool wait);
|
||||
size_t overrun(size_t itemSize, size_t nItems, bool wait);
|
||||
|
||||
private:
|
||||
int readWithTimeoutOrCallback(void* buf, int len, bool wait=true);
|
||||
size_t readWithTimeoutOrCallback(void* buf, size_t len, bool wait=true);
|
||||
|
||||
int fd;
|
||||
bool closeWhenDone;
|
||||
@ -68,8 +69,8 @@ namespace rdr {
|
||||
unsigned int timeWaitedIn100us;
|
||||
unsigned int timedKbits;
|
||||
|
||||
int bufSize;
|
||||
int offset;
|
||||
size_t bufSize;
|
||||
size_t offset;
|
||||
U8* start;
|
||||
};
|
||||
|
||||
|
@ -51,7 +51,7 @@ using namespace rdr;
|
||||
|
||||
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_),
|
||||
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
|
||||
{
|
||||
@ -79,7 +79,7 @@ void FdOutStream::setBlocking(bool blocking_) {
|
||||
blocking = blocking_;
|
||||
}
|
||||
|
||||
int FdOutStream::length()
|
||||
size_t FdOutStream::length()
|
||||
{
|
||||
return offset + ptr - sentUpTo;
|
||||
}
|
||||
@ -97,9 +97,9 @@ unsigned FdOutStream::getIdleTime()
|
||||
void FdOutStream::flush()
|
||||
{
|
||||
while (sentUpTo < ptr) {
|
||||
int n = writeWithTimeout((const void*) sentUpTo,
|
||||
ptr - sentUpTo,
|
||||
blocking? timeoutms : 0);
|
||||
size_t n = writeWithTimeout((const void*) sentUpTo,
|
||||
ptr - sentUpTo,
|
||||
blocking? timeoutms : 0);
|
||||
|
||||
// Timeout?
|
||||
if (n == 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)
|
||||
throw Exception("FdOutStream overrun: max itemSize exceeded");
|
||||
@ -129,10 +129,10 @@ int FdOutStream::overrun(int itemSize, int nItems)
|
||||
flush();
|
||||
|
||||
// Still not enough space?
|
||||
if (itemSize > end - ptr) {
|
||||
if (itemSize > (size_t)(end - ptr)) {
|
||||
// Can we shuffle things around?
|
||||
// (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))) {
|
||||
memmove(start, sentUpTo, 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?
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
size_t nAvail;
|
||||
nAvail = (end - ptr) / itemSize;
|
||||
if (nAvail < nItems)
|
||||
return nAvail;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
@ -166,7 +167,7 @@ int FdOutStream::overrun(int itemSize, int nItems)
|
||||
// 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;
|
||||
|
||||
|
@ -34,7 +34,7 @@ namespace rdr {
|
||||
|
||||
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();
|
||||
|
||||
void setTimeout(int timeoutms);
|
||||
@ -42,20 +42,20 @@ namespace rdr {
|
||||
int getFd() { return fd; }
|
||||
|
||||
void flush();
|
||||
int length();
|
||||
size_t length();
|
||||
|
||||
int bufferUsage();
|
||||
|
||||
unsigned getIdleTime();
|
||||
|
||||
private:
|
||||
int overrun(int itemSize, int nItems);
|
||||
int writeWithTimeout(const void* data, int length, int timeoutms);
|
||||
size_t overrun(size_t itemSize, size_t nItems);
|
||||
size_t writeWithTimeout(const void* data, size_t length, int timeoutms);
|
||||
int fd;
|
||||
bool blocking;
|
||||
int timeoutms;
|
||||
int bufSize;
|
||||
int offset;
|
||||
size_t bufSize;
|
||||
size_t offset;
|
||||
U8* start;
|
||||
U8* sentUpTo;
|
||||
struct timeval lastWrite;
|
||||
|
@ -48,7 +48,7 @@ void FileInStream::reset(void) {
|
||||
ptr = end = b;
|
||||
}
|
||||
|
||||
int FileInStream::pos()
|
||||
size_t FileInStream::pos()
|
||||
{
|
||||
if (!file)
|
||||
throw Exception("File is not open");
|
||||
@ -56,9 +56,9 @@ int FileInStream::pos()
|
||||
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");
|
||||
|
||||
if (end - ptr != 0)
|
||||
@ -68,7 +68,7 @@ int FileInStream::overrun(int itemSize, int nItems, bool wait)
|
||||
ptr = b;
|
||||
|
||||
|
||||
while (end < b + itemSize) {
|
||||
while ((size_t)(end - b) < itemSize) {
|
||||
size_t n = fread((U8 *)end, b + sizeof(b) - end, 1, file);
|
||||
if (n == 0) {
|
||||
if (ferror(file))
|
||||
@ -80,8 +80,10 @@ int FileInStream::overrun(int itemSize, int nItems, bool wait)
|
||||
end += b + sizeof(b) - end;
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
size_t nAvail;
|
||||
nAvail = (end - ptr) / itemSize;
|
||||
if (nAvail < nItems)
|
||||
return nAvail;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
@ -35,10 +35,10 @@ namespace rdr {
|
||||
|
||||
void reset(void);
|
||||
|
||||
int pos();
|
||||
size_t pos();
|
||||
|
||||
protected:
|
||||
int overrun(int itemSize, int nItems, bool wait = true);
|
||||
size_t overrun(size_t itemSize, size_t nItems, bool wait = true);
|
||||
|
||||
private:
|
||||
U8 b[131072];
|
||||
|
@ -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
|
@ -28,7 +28,7 @@ const int DEFAULT_BUF_LEN = 16384;
|
||||
|
||||
static inline int min(int a, int b) {return a<b ? a : b;}
|
||||
|
||||
HexInStream::HexInStream(InStream& is, int bufSize_)
|
||||
HexInStream::HexInStream(InStream& is, size_t bufSize_)
|
||||
: bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_LEN), offset(0), in_stream(is)
|
||||
{
|
||||
ptr = end = start = new U8[bufSize];
|
||||
@ -50,8 +50,8 @@ bool HexInStream::readHexAndShift(char c, int* v) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HexInStream::hexStrToBin(const char* s, char** data, int* length) {
|
||||
int l=strlen(s);
|
||||
bool HexInStream::hexStrToBin(const char* s, char** data, size_t* length) {
|
||||
size_t l=strlen(s);
|
||||
if ((l % 2) == 0) {
|
||||
delete [] *data;
|
||||
*data = 0; *length = 0;
|
||||
@ -59,7 +59,7 @@ bool HexInStream::hexStrToBin(const char* s, char** data, int* length) {
|
||||
return true;
|
||||
*data = new char[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;
|
||||
if (!readHexAndShift(s[i], &byte) ||
|
||||
!readHexAndShift(s[i+1], &byte))
|
||||
@ -76,11 +76,11 @@ decodeError:
|
||||
}
|
||||
|
||||
|
||||
int HexInStream::pos() {
|
||||
size_t HexInStream::pos() {
|
||||
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)
|
||||
throw Exception("HexInStream overrun: max itemSize exceeded");
|
||||
|
||||
@ -91,15 +91,15 @@ int HexInStream::overrun(int itemSize, int nItems, bool wait) {
|
||||
offset += ptr - start;
|
||||
ptr = start;
|
||||
|
||||
while (end < ptr + itemSize) {
|
||||
int n = in_stream.check(2, 1, wait);
|
||||
while ((size_t)(end - ptr) < itemSize) {
|
||||
size_t n = in_stream.check(2, 1, wait);
|
||||
if (n == 0) return 0;
|
||||
const U8* iptr = in_stream.getptr();
|
||||
const U8* eptr = in_stream.getend();
|
||||
int length = min((eptr - iptr)/2, start + bufSize - end);
|
||||
size_t length = min((eptr - iptr)/2, start + bufSize - end);
|
||||
|
||||
U8* optr = (U8*) end;
|
||||
for (int i=0; i<length; i++) {
|
||||
for (size_t i=0; i<length; i++) {
|
||||
int v = 0;
|
||||
readHexAndShift(iptr[i*2], &v);
|
||||
readHexAndShift(iptr[i*2+1], &v);
|
||||
@ -110,8 +110,10 @@ int HexInStream::overrun(int itemSize, int nItems, bool wait) {
|
||||
end += length;
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
size_t nAvail;
|
||||
nAvail = (end - ptr) / itemSize;
|
||||
if (nAvail < nItems)
|
||||
return nAvail;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
@ -26,21 +26,21 @@ namespace rdr {
|
||||
class HexInStream : public InStream {
|
||||
public:
|
||||
|
||||
HexInStream(InStream& is, int bufSize=0);
|
||||
HexInStream(InStream& is, size_t bufSize=0);
|
||||
virtual ~HexInStream();
|
||||
|
||||
int pos();
|
||||
size_t pos();
|
||||
|
||||
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:
|
||||
int overrun(int itemSize, int nItems, bool wait);
|
||||
size_t overrun(size_t itemSize, size_t nItems, bool wait);
|
||||
|
||||
private:
|
||||
int bufSize;
|
||||
size_t bufSize;
|
||||
U8* start;
|
||||
int offset;
|
||||
size_t offset;
|
||||
|
||||
InStream& in_stream;
|
||||
};
|
||||
|
@ -23,9 +23,9 @@ using namespace rdr;
|
||||
|
||||
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)
|
||||
{
|
||||
if (bufSize % 2)
|
||||
@ -48,9 +48,9 @@ char HexOutStream::intToHex(int i) {
|
||||
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];
|
||||
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+1] = intToHex((data[i] & 15));
|
||||
if (!buffer[i*2] || !buffer[i*2+1]) {
|
||||
@ -70,9 +70,9 @@ HexOutStream::writeBuffer() {
|
||||
out_stream.check(2);
|
||||
U8* optr = out_stream.getptr();
|
||||
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+1] = intToHex(pos[i] & 0xf);
|
||||
}
|
||||
@ -84,7 +84,7 @@ HexOutStream::writeBuffer() {
|
||||
ptr = start;
|
||||
}
|
||||
|
||||
int HexOutStream::length()
|
||||
size_t HexOutStream::length()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
@ -95,15 +95,17 @@ HexOutStream::flush() {
|
||||
out_stream.flush();
|
||||
}
|
||||
|
||||
int
|
||||
HexOutStream::overrun(int itemSize, int nItems) {
|
||||
size_t
|
||||
HexOutStream::overrun(size_t itemSize, size_t nItems) {
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("HexOutStream overrun: max itemSize exceeded");
|
||||
|
||||
writeBuffer();
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
size_t nAvail;
|
||||
nAvail = (end - ptr) / itemSize;
|
||||
if (nAvail < nItems)
|
||||
return nAvail;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
@ -26,24 +26,24 @@ namespace rdr {
|
||||
class HexOutStream : public OutStream {
|
||||
public:
|
||||
|
||||
HexOutStream(OutStream& os, int buflen=0);
|
||||
HexOutStream(OutStream& os, size_t buflen=0);
|
||||
virtual ~HexOutStream();
|
||||
|
||||
void flush();
|
||||
int length();
|
||||
size_t length();
|
||||
|
||||
static char intToHex(int i);
|
||||
static char* binToHexStr(const char* data, int length);
|
||||
static char* binToHexStr(const char* data, size_t length);
|
||||
|
||||
private:
|
||||
void writeBuffer();
|
||||
int overrun(int itemSize, int nItems);
|
||||
size_t overrun(size_t itemSize, size_t nItems);
|
||||
|
||||
OutStream& out_stream;
|
||||
|
||||
U8* start;
|
||||
int offset;
|
||||
int bufSize;
|
||||
size_t offset;
|
||||
size_t bufSize;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -39,24 +39,35 @@ namespace rdr {
|
||||
// itemSize bytes. Returns the number of items in the buffer (up to a
|
||||
// maximum of nItems). If wait is false, then instead of blocking to wait
|
||||
// for the bytes, zero is returned if the bytes are not immediately
|
||||
// available.
|
||||
// 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) {
|
||||
if (ptr + itemSize > end)
|
||||
return overrun(itemSize, nItems, wait);
|
||||
size_t nAvail;
|
||||
|
||||
if (itemSize == 0 || nItems == 0)
|
||||
return 0;
|
||||
|
||||
if (itemSize > (size_t)(end - ptr))
|
||||
return overrun(itemSize, nItems, wait);
|
||||
|
||||
// itemSize cannot be zero at this point
|
||||
nAvail = (end - ptr) / itemSize;
|
||||
if (nAvail < nItems)
|
||||
return nAvail;
|
||||
|
||||
nItems = (end - ptr) / itemSize;
|
||||
}
|
||||
return nItems;
|
||||
}
|
||||
|
||||
// checkNoWait() tries to make sure that the given number of bytes can
|
||||
// be read without blocking. It returns true if this is the case, false
|
||||
// otherwise. The length must be "small" (less than the buffer size).
|
||||
// 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.
|
||||
|
||||
@ -82,24 +93,24 @@ namespace rdr {
|
||||
|
||||
static U32 maxStringLength;
|
||||
|
||||
inline void skip(int bytes) {
|
||||
inline void skip(size_t bytes) {
|
||||
while (bytes > 0) {
|
||||
int n = check(1, bytes);
|
||||
size_t n = check(1, bytes);
|
||||
ptr += n;
|
||||
bytes -= n;
|
||||
}
|
||||
}
|
||||
|
||||
// readBytes() reads an exact number of bytes.
|
||||
// If length is zero, readBytes() will return immediately.
|
||||
|
||||
void readBytes(void* data, int length) {
|
||||
U8* dataPtr = (U8*)data;
|
||||
U8* dataEnd = dataPtr + length;
|
||||
while (dataPtr < dataEnd) {
|
||||
int n = check(1, dataEnd - dataPtr);
|
||||
memcpy(dataPtr, ptr, n);
|
||||
void readBytes(void* data, size_t length) {
|
||||
while (length > 0) {
|
||||
size_t n = check(1, length);
|
||||
memcpy(data, 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.
|
||||
|
||||
virtual int pos() = 0;
|
||||
virtual size_t pos() = 0;
|
||||
|
||||
// getptr(), getend() and setptr() are "dirty" methods which allow you to
|
||||
// manipulate the buffer directly. This is useful for a stream which is a
|
||||
@ -133,7 +144,7 @@ namespace rdr {
|
||||
// instead of blocking to wait for the bytes, zero is returned if the bytes
|
||||
// are not immediately available.
|
||||
|
||||
virtual int overrun(int itemSize, int nItems, bool wait=true) = 0;
|
||||
virtual size_t overrun(size_t itemSize, size_t nItems, bool wait=true) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -36,7 +36,7 @@ namespace rdr {
|
||||
|
||||
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_)
|
||||
{
|
||||
ptr = start;
|
||||
@ -48,12 +48,12 @@ namespace rdr {
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
int pos() { return ptr - start; }
|
||||
void reposition(int pos) { ptr = start + pos; }
|
||||
size_t pos() { return ptr - start; }
|
||||
void reposition(size_t pos) { ptr = start + pos; }
|
||||
|
||||
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;
|
||||
bool deleteWhenDone;
|
||||
};
|
||||
|
@ -23,6 +23,7 @@
|
||||
#ifndef __RDR_MEMOUTSTREAM_H__
|
||||
#define __RDR_MEMOUTSTREAM_H__
|
||||
|
||||
#include <rdr/Exception.h>
|
||||
#include <rdr/OutStream.h>
|
||||
|
||||
namespace rdr {
|
||||
@ -40,16 +41,16 @@ namespace rdr {
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
void writeBytes(const void* data, int length) {
|
||||
void writeBytes(const void* data, size_t length) {
|
||||
check(length);
|
||||
memcpy(ptr, data, length);
|
||||
ptr += length;
|
||||
}
|
||||
|
||||
int length() { return ptr - start; }
|
||||
size_t length() { return ptr - start; }
|
||||
void clear() { ptr = start; };
|
||||
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.
|
||||
|
||||
@ -60,11 +61,14 @@ namespace rdr {
|
||||
// overrun() either doubles the buffer or adds enough space for nItems of
|
||||
// size itemSize bytes.
|
||||
|
||||
int overrun(int itemSize, int nItems) {
|
||||
int len = ptr - start + itemSize * nItems;
|
||||
if (len < (end - start) * 2)
|
||||
size_t overrun(size_t itemSize, size_t nItems) {
|
||||
size_t len = ptr - start + itemSize * nItems;
|
||||
if (len < (size_t)(end - start) * 2)
|
||||
len = (end - start) * 2;
|
||||
|
||||
if (len < (size_t)(end - start))
|
||||
throw Exception("Overflow in MemOutStream::overrun()");
|
||||
|
||||
U8* newStart = new U8[len];
|
||||
memcpy(newStart, start, ptr - start);
|
||||
ptr = newStart + (ptr - start);
|
||||
|
@ -44,14 +44,17 @@ namespace rdr {
|
||||
// itemSize bytes. Returns the number of items which fit (up to a maximum
|
||||
// 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) {
|
||||
if (ptr + itemSize > end)
|
||||
return overrun(itemSize, nItems);
|
||||
size_t nAvail;
|
||||
|
||||
if (itemSize > (size_t)(end - ptr))
|
||||
return overrun(itemSize, nItems);
|
||||
|
||||
nAvail = (end - ptr) / itemSize;
|
||||
if (nAvail < nItems)
|
||||
return nAvail;
|
||||
|
||||
nItems = (end - ptr) / itemSize;
|
||||
}
|
||||
return nItems;
|
||||
}
|
||||
|
||||
@ -76,13 +79,13 @@ namespace rdr {
|
||||
writeBytes(str, len);
|
||||
}
|
||||
|
||||
inline void pad(int bytes) {
|
||||
inline void pad(size_t bytes) {
|
||||
while (bytes-- > 0) writeU8(0);
|
||||
}
|
||||
|
||||
inline void skip(int bytes) {
|
||||
inline void skip(size_t bytes) {
|
||||
while (bytes > 0) {
|
||||
int n = check(1, bytes);
|
||||
size_t n = check(1, bytes);
|
||||
ptr += n;
|
||||
bytes -= n;
|
||||
}
|
||||
@ -90,22 +93,21 @@ namespace rdr {
|
||||
|
||||
// writeBytes() writes an exact number of bytes.
|
||||
|
||||
void writeBytes(const void* data, int length) {
|
||||
const U8* dataPtr = (const U8*)data;
|
||||
const U8* dataEnd = dataPtr + length;
|
||||
while (dataPtr < dataEnd) {
|
||||
int n = check(1, dataEnd - dataPtr);
|
||||
memcpy(ptr, dataPtr, n);
|
||||
void writeBytes(const void* data, size_t length) {
|
||||
while (length > 0) {
|
||||
size_t n = check(1, length);
|
||||
memcpy(ptr, data, n);
|
||||
ptr += n;
|
||||
dataPtr += n;
|
||||
data = (U8*)data + n;
|
||||
length -= n;
|
||||
}
|
||||
}
|
||||
|
||||
// copyBytes() efficiently transfers data between streams
|
||||
|
||||
void copyBytes(InStream* is, int length) {
|
||||
void copyBytes(InStream* is, size_t length) {
|
||||
while (length > 0) {
|
||||
int n = check(1, length);
|
||||
size_t n = check(1, length);
|
||||
is->readBytes(ptr, n);
|
||||
ptr += n;
|
||||
length -= n;
|
||||
@ -124,7 +126,7 @@ namespace rdr {
|
||||
|
||||
// length() returns the length of the stream.
|
||||
|
||||
virtual int length() = 0;
|
||||
virtual size_t length() = 0;
|
||||
|
||||
// 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
|
||||
// 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:
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
const int DEFAULT_BUF_LEN = 256;
|
||||
const size_t DEFAULT_BUF_LEN = 256;
|
||||
|
||||
unsigned int RandomStream::seed;
|
||||
|
||||
@ -83,11 +83,11 @@ RandomStream::~RandomStream() {
|
||||
#endif
|
||||
}
|
||||
|
||||
int RandomStream::pos() {
|
||||
size_t RandomStream::pos() {
|
||||
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)
|
||||
throw Exception("RandomStream overrun: max itemSize exceeded");
|
||||
|
||||
@ -98,7 +98,7 @@ int RandomStream::overrun(int itemSize, int nItems, bool wait) {
|
||||
offset += ptr - start;
|
||||
ptr = start;
|
||||
|
||||
int length = start + DEFAULT_BUF_LEN - end;
|
||||
size_t length = start + DEFAULT_BUF_LEN - end;
|
||||
|
||||
#ifdef RFB_HAVE_WINCRYPT
|
||||
if (provider) {
|
||||
@ -109,7 +109,7 @@ int RandomStream::overrun(int itemSize, int nItems, bool wait) {
|
||||
#else
|
||||
#ifndef WIN32
|
||||
if (fp) {
|
||||
int n = fread((U8*)end, length, 1, fp);
|
||||
size_t n = fread((U8*)end, length, 1, fp);
|
||||
if (n != 1)
|
||||
throw rdr::SystemException("reading /dev/urandom or /dev/random failed",
|
||||
errno);
|
||||
@ -119,12 +119,14 @@ int RandomStream::overrun(int itemSize, int nItems, bool wait) {
|
||||
{
|
||||
#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));
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
size_t nAvail;
|
||||
nAvail = (end - ptr) / itemSize;
|
||||
if (nAvail < nItems)
|
||||
return nAvail;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
@ -39,14 +39,14 @@ namespace rdr {
|
||||
RandomStream();
|
||||
virtual ~RandomStream();
|
||||
|
||||
int pos();
|
||||
size_t pos();
|
||||
|
||||
protected:
|
||||
int overrun(int itemSize, int nItems, bool wait);
|
||||
size_t overrun(size_t itemSize, size_t nItems, bool wait);
|
||||
|
||||
private:
|
||||
U8* start;
|
||||
int offset;
|
||||
size_t offset;
|
||||
|
||||
static unsigned int seed;
|
||||
#ifdef RFB_HAVE_WINCRYPT
|
||||
|
@ -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
|
@ -43,7 +43,7 @@ ssize_t TLSInStream::pull(gnutls_transport_ptr_t str, void* data, size_t size)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (in->getend() - in->getptr() < (ptrdiff_t)size)
|
||||
if ((size_t)(in->getend() - in->getptr()) < size)
|
||||
size = in->getend() - in->getptr();
|
||||
|
||||
in->readBytes(data, size);
|
||||
@ -75,12 +75,12 @@ TLSInStream::~TLSInStream()
|
||||
delete[] start;
|
||||
}
|
||||
|
||||
int TLSInStream::pos()
|
||||
size_t TLSInStream::pos()
|
||||
{
|
||||
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)
|
||||
throw Exception("TLSInStream overrun: max itemSize exceeded");
|
||||
@ -92,26 +92,30 @@ int TLSInStream::overrun(int itemSize, int nItems, bool wait)
|
||||
end -= ptr - start;
|
||||
ptr = start;
|
||||
|
||||
while (end < start + itemSize) {
|
||||
int n = readTLS((U8*) end, start + bufSize - end, wait);
|
||||
while ((size_t)(end - start) < itemSize) {
|
||||
size_t n = readTLS((U8*) end, start + bufSize - end, wait);
|
||||
if (!wait && n == 0)
|
||||
return 0;
|
||||
end += n;
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
size_t nAvail;
|
||||
nAvail = (end - ptr) / itemSize;
|
||||
if (nAvail < nItems)
|
||||
return nAvail;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
int TLSInStream::readTLS(U8* buf, int len, bool wait)
|
||||
size_t TLSInStream::readTLS(U8* buf, size_t len, bool wait)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = in->check(1, 1, wait);
|
||||
if (n == 0)
|
||||
return 0;
|
||||
if (gnutls_record_check_pending(session) == 0) {
|
||||
n = in->check(1, 1, wait);
|
||||
if (n == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = gnutls_record_recv(session, (void *) buf, len);
|
||||
if (n == GNUTLS_E_INTERRUPTED || n == GNUTLS_E_AGAIN)
|
||||
|
@ -36,17 +36,17 @@ namespace rdr {
|
||||
TLSInStream(InStream* in, gnutls_session_t session);
|
||||
virtual ~TLSInStream();
|
||||
|
||||
int pos();
|
||||
size_t pos();
|
||||
|
||||
private:
|
||||
int overrun(int itemSize, int nItems, bool wait);
|
||||
int readTLS(U8* buf, int len, bool wait);
|
||||
size_t overrun(size_t itemSize, size_t nItems, 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);
|
||||
|
||||
gnutls_session_t session;
|
||||
InStream* in;
|
||||
int bufSize;
|
||||
int offset;
|
||||
size_t bufSize;
|
||||
size_t offset;
|
||||
U8* start;
|
||||
};
|
||||
};
|
||||
|
@ -75,7 +75,7 @@ TLSOutStream::~TLSOutStream()
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
int TLSOutStream::length()
|
||||
size_t TLSOutStream::length()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
@ -84,7 +84,7 @@ void TLSOutStream::flush()
|
||||
{
|
||||
U8* sentUpTo = start;
|
||||
while (sentUpTo < ptr) {
|
||||
int n = writeTLS(sentUpTo, ptr - sentUpTo);
|
||||
size_t n = writeTLS(sentUpTo, ptr - sentUpTo);
|
||||
sentUpTo += n;
|
||||
offset += n;
|
||||
}
|
||||
@ -93,20 +93,22 @@ void TLSOutStream::flush()
|
||||
out->flush();
|
||||
}
|
||||
|
||||
int TLSOutStream::overrun(int itemSize, int nItems)
|
||||
size_t TLSOutStream::overrun(size_t itemSize, size_t nItems)
|
||||
{
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("TLSOutStream overrun: max itemSize exceeded");
|
||||
|
||||
flush();
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
size_t nAvail;
|
||||
nAvail = (end - ptr) / itemSize;
|
||||
if (nAvail < nItems)
|
||||
return nAvail;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
int TLSOutStream::writeTLS(const U8* data, int length)
|
||||
size_t TLSOutStream::writeTLS(const U8* data, size_t length)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
@ -36,20 +36,20 @@ namespace rdr {
|
||||
virtual ~TLSOutStream();
|
||||
|
||||
void flush();
|
||||
int length();
|
||||
size_t length();
|
||||
|
||||
protected:
|
||||
int overrun(int itemSize, int nItems);
|
||||
size_t overrun(size_t itemSize, size_t nItems);
|
||||
|
||||
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);
|
||||
|
||||
gnutls_session_t session;
|
||||
OutStream* out;
|
||||
int bufSize;
|
||||
size_t bufSize;
|
||||
U8* start;
|
||||
int offset;
|
||||
size_t offset;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -26,7 +26,7 @@ using namespace rdr;
|
||||
|
||||
enum { DEFAULT_BUF_SIZE = 16384 };
|
||||
|
||||
ZlibInStream::ZlibInStream(int bufSize_)
|
||||
ZlibInStream::ZlibInStream(size_t bufSize_)
|
||||
: underlying(0), bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0),
|
||||
zs(NULL), bytesIn(0)
|
||||
{
|
||||
@ -40,28 +40,28 @@ ZlibInStream::~ZlibInStream()
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
void ZlibInStream::setUnderlying(InStream* is, int bytesIn_)
|
||||
void ZlibInStream::setUnderlying(InStream* is, size_t bytesIn_)
|
||||
{
|
||||
underlying = is;
|
||||
bytesIn = bytesIn_;
|
||||
ptr = end = start;
|
||||
}
|
||||
|
||||
int ZlibInStream::pos()
|
||||
size_t ZlibInStream::pos()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
void ZlibInStream::removeUnderlying()
|
||||
void ZlibInStream::flushUnderlying()
|
||||
{
|
||||
ptr = end = start;
|
||||
if (!underlying) return;
|
||||
|
||||
while (bytesIn > 0) {
|
||||
decompress(true);
|
||||
end = start; // throw away any data
|
||||
}
|
||||
underlying = 0;
|
||||
|
||||
setUnderlying(NULL, 0);
|
||||
}
|
||||
|
||||
void ZlibInStream::reset()
|
||||
@ -90,18 +90,16 @@ void ZlibInStream::init()
|
||||
void ZlibInStream::deinit()
|
||||
{
|
||||
assert(zs != NULL);
|
||||
removeUnderlying();
|
||||
setUnderlying(NULL, 0);
|
||||
inflateEnd(zs);
|
||||
delete zs;
|
||||
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)
|
||||
throw Exception("ZlibInStream overrun: max itemSize exceeded");
|
||||
if (!underlying)
|
||||
throw Exception("ZlibInStream overrun: no underlying stream");
|
||||
|
||||
if (end - ptr != 0)
|
||||
memmove(start, ptr, end - ptr);
|
||||
@ -110,13 +108,15 @@ int ZlibInStream::overrun(int itemSize, int nItems, bool wait)
|
||||
end -= ptr - start;
|
||||
ptr = start;
|
||||
|
||||
while (end - ptr < itemSize) {
|
||||
while ((size_t)(end - ptr) < itemSize) {
|
||||
if (!decompress(wait))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
size_t nAvail;
|
||||
nAvail = (end - ptr) / itemSize;
|
||||
if (nAvail < nItems)
|
||||
return nAvail;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
@ -127,18 +127,21 @@ int ZlibInStream::overrun(int itemSize, int nItems, bool wait)
|
||||
|
||||
bool ZlibInStream::decompress(bool wait)
|
||||
{
|
||||
if (!underlying)
|
||||
throw Exception("ZlibInStream overrun: no underlying stream");
|
||||
|
||||
zs->next_out = (U8*)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;
|
||||
zs->next_in = (U8*)underlying->getptr();
|
||||
zs->avail_in = underlying->getend() - underlying->getptr();
|
||||
if ((int)zs->avail_in > bytesIn)
|
||||
if (zs->avail_in > bytesIn)
|
||||
zs->avail_in = bytesIn;
|
||||
|
||||
int rc = inflate(zs, Z_SYNC_FLUSH);
|
||||
if (rc != Z_OK) {
|
||||
if (rc < 0) {
|
||||
throw Exception("ZlibInStream: inflate failed");
|
||||
}
|
||||
|
||||
|
@ -34,12 +34,12 @@ namespace rdr {
|
||||
|
||||
public:
|
||||
|
||||
ZlibInStream(int bufSize=0);
|
||||
ZlibInStream(size_t bufSize=0);
|
||||
virtual ~ZlibInStream();
|
||||
|
||||
void setUnderlying(InStream* is, int bytesIn);
|
||||
void removeUnderlying();
|
||||
int pos();
|
||||
void setUnderlying(InStream* is, size_t bytesIn);
|
||||
void flushUnderlying();
|
||||
size_t pos();
|
||||
void reset();
|
||||
|
||||
private:
|
||||
@ -47,14 +47,14 @@ namespace rdr {
|
||||
void init();
|
||||
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);
|
||||
|
||||
InStream* underlying;
|
||||
int bufSize;
|
||||
int offset;
|
||||
size_t bufSize;
|
||||
size_t offset;
|
||||
z_stream_s* zs;
|
||||
int bytesIn;
|
||||
size_t bytesIn;
|
||||
U8* start;
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,7 @@ using namespace rdr;
|
||||
|
||||
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),
|
||||
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
|
||||
{
|
||||
@ -72,7 +72,7 @@ void ZlibOutStream::setCompressionLevel(int level)
|
||||
newLevel = level;
|
||||
}
|
||||
|
||||
int ZlibOutStream::length()
|
||||
size_t ZlibOutStream::length()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
@ -95,7 +95,7 @@ void ZlibOutStream::flush()
|
||||
ptr = start;
|
||||
}
|
||||
|
||||
int ZlibOutStream::overrun(int itemSize, int nItems)
|
||||
size_t ZlibOutStream::overrun(size_t itemSize, size_t nItems)
|
||||
{
|
||||
#ifdef ZLIBOUT_DEBUG
|
||||
fprintf(stderr,"zos overrun\n");
|
||||
@ -106,7 +106,7 @@ int ZlibOutStream::overrun(int itemSize, int nItems)
|
||||
|
||||
checkCompressionLevel();
|
||||
|
||||
while (end - ptr < itemSize) {
|
||||
while ((size_t)(end - ptr) < itemSize) {
|
||||
zs->next_in = start;
|
||||
zs->avail_in = ptr - start;
|
||||
|
||||
@ -127,8 +127,10 @@ int ZlibOutStream::overrun(int itemSize, int nItems)
|
||||
}
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
size_t nAvail;
|
||||
nAvail = (end - ptr) / itemSize;
|
||||
if (nAvail < nItems)
|
||||
return nAvail;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
@ -154,7 +156,7 @@ void ZlibOutStream::deflate(int flush)
|
||||
#endif
|
||||
|
||||
rc = ::deflate(zs, flush);
|
||||
if (rc != Z_OK) {
|
||||
if (rc < 0) {
|
||||
// Silly zlib returns an error if you try to flush something twice
|
||||
if ((rc == Z_BUF_ERROR) && (flush != Z_NO_FLUSH))
|
||||
break;
|
||||
@ -188,7 +190,7 @@ void ZlibOutStream::checkCompressionLevel()
|
||||
deflate(Z_SYNC_FLUSH);
|
||||
|
||||
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
|
||||
// explicit flush we did above. It should be safe to ignore though
|
||||
// as the first flush should have left things in a stable state...
|
||||
|
@ -35,25 +35,25 @@ namespace rdr {
|
||||
|
||||
public:
|
||||
|
||||
ZlibOutStream(OutStream* os=0, int bufSize=0, int compressionLevel=-1);
|
||||
ZlibOutStream(OutStream* os=0, size_t bufSize=0, int compressionLevel=-1);
|
||||
virtual ~ZlibOutStream();
|
||||
|
||||
void setUnderlying(OutStream* os);
|
||||
void setCompressionLevel(int level=-1);
|
||||
void flush();
|
||||
int length();
|
||||
size_t length();
|
||||
|
||||
private:
|
||||
|
||||
int overrun(int itemSize, int nItems);
|
||||
size_t overrun(size_t itemSize, size_t nItems);
|
||||
void deflate(int flush);
|
||||
void checkCompressionLevel();
|
||||
|
||||
OutStream* underlying;
|
||||
int compressionLevel;
|
||||
int newLevel;
|
||||
int bufSize;
|
||||
int offset;
|
||||
size_t bufSize;
|
||||
size_t offset;
|
||||
z_stream_s* zs;
|
||||
U8* start;
|
||||
};
|
||||
|
@ -22,7 +22,6 @@ set(RFB_SOURCES
|
||||
EncCache.cxx
|
||||
EncodeManager.cxx
|
||||
Encoder.cxx
|
||||
HTTPServer.cxx
|
||||
HextileDecoder.cxx
|
||||
HextileEncoder.cxx
|
||||
JpegCompressor.cxx
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include <os/Mutex.h>
|
||||
|
||||
@ -432,7 +433,8 @@ bool StringParameter::setParam(const char* v) {
|
||||
if (immutable) return true;
|
||||
if (!v)
|
||||
throw rfb::Exception("setParam(<null>) not allowed");
|
||||
vlog.debug("set %s(String) to %s", getName(), v);
|
||||
if (strcasecmp(getName(), "BasicAuth")) // don't log the auth info
|
||||
vlog.debug("set %s(String) to %s", getName(), v);
|
||||
CharArray oldValue(value);
|
||||
value = strDup(v);
|
||||
return value != 0;
|
||||
@ -454,7 +456,7 @@ StringParameter::operator const char *() const {
|
||||
// -=- BinaryParameter
|
||||
|
||||
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) {
|
||||
if (l) {
|
||||
value = new char[l];
|
||||
@ -474,7 +476,7 @@ bool BinaryParameter::setParam(const char* v) {
|
||||
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;
|
||||
if (immutable) return;
|
||||
vlog.debug("set %s(Binary)", getName());
|
||||
@ -495,7 +497,7 @@ char* BinaryParameter::getValueStr() const {
|
||||
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;
|
||||
if (length_) *length_ = length;
|
||||
if (data_) {
|
||||
|
@ -268,24 +268,25 @@ namespace rfb {
|
||||
|
||||
class BinaryParameter : public VoidParameter {
|
||||
public:
|
||||
BinaryParameter(const char* name_, const char* desc_, const void* v, int l,
|
||||
ConfigurationObject co=ConfGlobal);
|
||||
BinaryParameter(const char* name_, const char* desc_,
|
||||
const void* v, size_t l,
|
||||
ConfigurationObject co=ConfGlobal);
|
||||
using VoidParameter::setParam;
|
||||
virtual ~BinaryParameter();
|
||||
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* getValueStr() const;
|
||||
|
||||
// getData() will return length zero if there is no data
|
||||
// NB: data may be set to zero, OR set to a zero-length buffer
|
||||
void getData(void** data, int* length) const;
|
||||
void getData(void** data, size_t* length) const;
|
||||
|
||||
protected:
|
||||
char* value;
|
||||
int length;
|
||||
size_t length;
|
||||
char* def_value;
|
||||
int def_length;
|
||||
size_t def_length;
|
||||
};
|
||||
|
||||
// -=- ParameterIterator
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <rfb/SMsgWriter.h>
|
||||
#include <rfb/UpdateTracker.h>
|
||||
#include <rfb/LogWriter.h>
|
||||
#include <rfb/Exception.h>
|
||||
|
||||
#include <rfb/RawEncoder.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_),
|
||||
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;
|
||||
|
||||
@ -355,9 +358,10 @@ void EncodeManager::doUpdate(bool allowLossy, const Region& changed_,
|
||||
|
||||
changed = changed_;
|
||||
|
||||
gettimeofday(&start, NULL);
|
||||
|
||||
if (allowLossy && activeEncoders[encoderFullColour] == encoderTightWEBP) {
|
||||
const unsigned rate = 1024 * 1000 / rfb::Server::frameRate;
|
||||
gettimeofday(&start, NULL);
|
||||
|
||||
screenArea = pb->getRect().width() * pb->getRect().height();
|
||||
screenArea *= 1024;
|
||||
@ -400,8 +404,7 @@ void EncodeManager::doUpdate(bool allowLossy, const Region& changed_,
|
||||
writeSolidRects(&changed, pb);
|
||||
|
||||
writeRects(changed, pb,
|
||||
allowLossy && activeEncoders[encoderFullColour] == encoderTightWEBP ?
|
||||
&start : NULL, true);
|
||||
&start, true);
|
||||
if (!videoDetected) // In case detection happened between the calls
|
||||
writeRects(cursorRegion, renderedCursor);
|
||||
|
||||
@ -1135,6 +1138,24 @@ void EncodeManager::writeRects(const Region& changed, const PixelBuffer* pb,
|
||||
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)
|
||||
activeEncoders[encoderFullColour] = encoderTightJPEG;
|
||||
|
||||
@ -1494,6 +1515,11 @@ void EncodeManager::OffsetPixelBuffer::update(const PixelFormat& pf,
|
||||
stride = stride_;
|
||||
}
|
||||
|
||||
rdr::U8* EncodeManager::OffsetPixelBuffer::getBufferRW(const Rect& r, int* stride)
|
||||
{
|
||||
throw rfb::Exception("Invalid write attempt to OffsetPixelBuffer");
|
||||
}
|
||||
|
||||
// Preprocessor generated, optimised methods
|
||||
|
||||
#define BPP 8
|
||||
|
@ -68,6 +68,10 @@ namespace rfb {
|
||||
const RenderedCursor* renderedCursor,
|
||||
size_t maxUpdateSize);
|
||||
|
||||
unsigned getEncodingTime() const {
|
||||
return encodingTime;
|
||||
};
|
||||
|
||||
protected:
|
||||
void doUpdate(bool allowLossy, const Region& changed,
|
||||
const Region& copied, const Point& copy_delta,
|
||||
@ -177,6 +181,8 @@ namespace rfb {
|
||||
unsigned webpFallbackUs;
|
||||
unsigned webpBenchResult;
|
||||
bool webpTookTooLong;
|
||||
unsigned encodingTime;
|
||||
unsigned maxEncodingTime, framesSinceEncPrint;
|
||||
|
||||
EncCache *encCache;
|
||||
|
||||
@ -187,6 +193,9 @@ namespace rfb {
|
||||
|
||||
void update(const PixelFormat& pf, int width, int height,
|
||||
const rdr::U8* data_, int stride);
|
||||
|
||||
private:
|
||||
virtual rdr::U8* getBufferRW(const Rect& r, int* stride);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
||||
|
@ -49,7 +49,7 @@ namespace rfb {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ PlainPasswd::PlainPasswd() {}
|
||||
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) {
|
||||
@ -63,11 +63,11 @@ void PlainPasswd::replaceBuf(char* b) {
|
||||
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) {
|
||||
int l = strlen(plainPwd.buf), i;
|
||||
size_t l = strlen(plainPwd.buf), i;
|
||||
for (i=0; i<8; i++)
|
||||
buf[i] = i<l ? plainPwd.buf[i] : 0;
|
||||
deskey(d3desObfuscationKey, EN0);
|
||||
|
@ -28,7 +28,7 @@ namespace rfb {
|
||||
public:
|
||||
PlainPasswd();
|
||||
PlainPasswd(char* pwd);
|
||||
PlainPasswd(int len);
|
||||
PlainPasswd(size_t len);
|
||||
PlainPasswd(const ObfuscatedPasswd& obfPwd);
|
||||
~PlainPasswd();
|
||||
void replaceBuf(char* b);
|
||||
@ -37,10 +37,10 @@ namespace rfb {
|
||||
class ObfuscatedPasswd : public CharArray {
|
||||
public:
|
||||
ObfuscatedPasswd();
|
||||
ObfuscatedPasswd(int l);
|
||||
ObfuscatedPasswd(size_t l);
|
||||
ObfuscatedPasswd(const PlainPasswd& plainPwd);
|
||||
~ObfuscatedPasswd();
|
||||
int length;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -205,6 +205,12 @@ bool PixelFormat::is888(void) const
|
||||
return false;
|
||||
if (blueMax != 255)
|
||||
return false;
|
||||
if ((redShift & 0x7) != 0)
|
||||
return false;
|
||||
if ((greenShift & 0x7) != 0)
|
||||
return false;
|
||||
if ((blueShift & 0x7) != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -678,7 +684,14 @@ bool PixelFormat::isSane(void)
|
||||
return false;
|
||||
|
||||
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;
|
||||
|
||||
if (((redMax << redShift) & (greenMax << greenShift)) != 0)
|
||||
|
@ -54,6 +54,8 @@ namespace rfb {
|
||||
virtual void enableContinuousUpdates(bool enable,
|
||||
int x, int y, int w, int h) = 0;
|
||||
|
||||
virtual void sendStats() = 0;
|
||||
|
||||
// InputHandler interface
|
||||
// The InputHandler methods will be called for the corresponding messages.
|
||||
|
||||
|
@ -74,6 +74,9 @@ void SMsgReader::readMsg()
|
||||
case msgTypeClientFence:
|
||||
readFence();
|
||||
break;
|
||||
case msgTypeRequestStats:
|
||||
readRequestStats();
|
||||
break;
|
||||
case msgTypeKeyEvent:
|
||||
readKeyEvent();
|
||||
break;
|
||||
@ -236,6 +239,12 @@ void SMsgReader::readClientCutText()
|
||||
handler->clientCutText(ca.buf, len);
|
||||
}
|
||||
|
||||
void SMsgReader::readRequestStats()
|
||||
{
|
||||
is->skip(3);
|
||||
handler->sendStats();
|
||||
}
|
||||
|
||||
void SMsgReader::readQEMUMessage()
|
||||
{
|
||||
int subType = is->readU8();
|
||||
|
@ -55,6 +55,7 @@ namespace rfb {
|
||||
void readKeyEvent();
|
||||
void readPointerEvent();
|
||||
void readClientCutText();
|
||||
void readRequestStats();
|
||||
|
||||
void readQEMUMessage();
|
||||
void readQEMUKeyEvent();
|
||||
|
@ -88,6 +88,15 @@ void SMsgWriter::writeServerCutText(const char* str, int len)
|
||||
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[])
|
||||
{
|
||||
if (!cp->supportsFence)
|
||||
|
@ -55,6 +55,7 @@ namespace rfb {
|
||||
// writeBell() and writeServerCutText() do the obvious thing.
|
||||
void writeBell();
|
||||
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.
|
||||
void writeFence(rdr::U32 flags, unsigned len, const char data[]);
|
||||
|
@ -191,6 +191,11 @@ rfb::BoolParameter rfb::Server::printVideoArea
|
||||
"Print the detected video area % value.",
|
||||
false);
|
||||
|
||||
rfb::StringParameter rfb::Server::kasmPasswordFile
|
||||
("KasmPasswordFile",
|
||||
"Password file for BasicAuth, created with the kasmvncpasswd utility.",
|
||||
"~/.kasmpasswd");
|
||||
|
||||
static void bandwidthPreset() {
|
||||
rfb::Server::dynamicQualityMin.setParam(2);
|
||||
rfb::Server::dynamicQualityMax.setParam(9);
|
||||
|
@ -56,6 +56,7 @@ namespace rfb {
|
||||
static IntParameter videoOutTime;
|
||||
static IntParameter videoArea;
|
||||
static IntParameter videoScaling;
|
||||
static StringParameter kasmPasswordFile;
|
||||
static BoolParameter printVideoArea;
|
||||
static BoolParameter protocol3_3;
|
||||
static BoolParameter alwaysShared;
|
||||
|
@ -340,7 +340,8 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,
|
||||
|
||||
zis[streamId].readBytes(netbuf, dataSize);
|
||||
|
||||
zis[streamId].removeUnderlying();
|
||||
zis[streamId].flushUnderlying();
|
||||
zis[streamId].setUnderlying(NULL, 0);
|
||||
delete ms;
|
||||
|
||||
bufptr = netbuf;
|
||||
|
@ -21,11 +21,7 @@
|
||||
#define __RFB_TIMER_H__
|
||||
|
||||
#include <list>
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
namespace rfb {
|
||||
|
||||
|
@ -53,7 +53,8 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
|
||||
fenceDataLen(0), fenceData(NULL), congestionTimer(this),
|
||||
losslessTimer(this), kbdLogTimer(this), server(server_), updates(false),
|
||||
updateRenderedCursor(false), removeRenderedCursor(false),
|
||||
continuousUpdates(false), encodeManager(this, &server_->encCache), pointerEventTime(0),
|
||||
continuousUpdates(false), encodeManager(this, &server_->encCache),
|
||||
pointerEventTime(0),
|
||||
clientHasCursor(false),
|
||||
accessRights(AccessDefault), startTime(time(0))
|
||||
{
|
||||
@ -61,6 +62,9 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
|
||||
peerEndpoint.buf = sock->getPeerEndpoint();
|
||||
VNCServerST::connectionsLog.write(1,"accepted: %s", peerEndpoint.buf);
|
||||
|
||||
memset(bstats_total, 0, sizeof(bstats_total));
|
||||
gettimeofday(&connStart, NULL);
|
||||
|
||||
// Configure the socket
|
||||
setSocketTimeouts();
|
||||
lastEventTime = time(0);
|
||||
@ -1037,6 +1041,14 @@ bool VNCSConnectionST::isCongested()
|
||||
if (eta >= 0)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1083,6 +1095,11 @@ void VNCSConnectionST::writeFramebufferUpdate()
|
||||
sock->cork(false);
|
||||
|
||||
congestion.updatePosition(sock->outStream().length());
|
||||
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
bstats[BS_FRAME].push_back(now);
|
||||
bstats_total[BS_FRAME]++;
|
||||
}
|
||||
|
||||
void VNCSConnectionST::writeNoDataUpdate()
|
||||
@ -1236,6 +1253,27 @@ void VNCSConnectionST::writeDataUpdate()
|
||||
copypassed.clear();
|
||||
gettimeofday(&lastRealUpdate, NULL);
|
||||
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 {
|
||||
encodeManager.writeLosslessRefresh(req, server->getPixelBuffer(),
|
||||
cursor, maxUpdateSize);
|
||||
@ -1265,6 +1303,60 @@ void VNCSConnectionST::screenLayoutChange(rdr::U16 reason)
|
||||
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.
|
||||
// If the client supports local cursor then it will arrange for the cursor to
|
||||
|
@ -178,6 +178,8 @@ namespace rfb {
|
||||
virtual void supportsContinuousUpdates();
|
||||
virtual void supportsLEDState();
|
||||
|
||||
virtual void sendStats();
|
||||
|
||||
// setAccessRights() allows a security package to limit the access rights
|
||||
// of a VNCSConnectioST to the server. These access rights are applied
|
||||
// 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;
|
||||
|
||||
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 pointerEventTime;
|
||||
Point pointerEventPos;
|
||||
|
@ -28,6 +28,9 @@ namespace rfb {
|
||||
|
||||
const int msgTypeEndOfContinuousUpdates = 150;
|
||||
|
||||
// kasm
|
||||
const int msgTypeStats = 178;
|
||||
|
||||
const int msgTypeServerFence = 248;
|
||||
|
||||
// client to server
|
||||
@ -42,6 +45,9 @@ namespace rfb {
|
||||
|
||||
const int msgTypeEnableContinuousUpdates = 150;
|
||||
|
||||
// kasm
|
||||
const int msgTypeRequestStats = 178;
|
||||
|
||||
const int msgTypeClientFence = 248;
|
||||
|
||||
const int msgTypeSetDesktopSize = 251;
|
||||
|
@ -56,15 +56,17 @@ TightDecoder::FilterGradient24(const rdr::U8 *inbuf,
|
||||
int rectWidth = r.width();
|
||||
|
||||
for (y = 0; y < rectHeight; y++) {
|
||||
/* First pixel in a row */
|
||||
for (c = 0; c < 3; c++) {
|
||||
pix[c] = inbuf[y*rectWidth*3+c] + prevRow[c];
|
||||
thisRow[c] = pix[c];
|
||||
}
|
||||
pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride], pix, 1);
|
||||
for (x = 0; x < rectWidth; x++) {
|
||||
/* First pixel in a row */
|
||||
if (x == 0) {
|
||||
for (c = 0; c < 3; c++) {
|
||||
pix[c] = inbuf[y*rectWidth*3+c] + prevRow[c];
|
||||
thisRow[c] = pix[c];
|
||||
}
|
||||
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++) {
|
||||
est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c];
|
||||
if (est[c] > 0xff) {
|
||||
@ -103,17 +105,20 @@ void TightDecoder::FilterGradient(const rdr::U8* inbuf,
|
||||
int rectWidth = r.width();
|
||||
|
||||
for (y = 0; y < rectHeight; y++) {
|
||||
/* First pixel in a row */
|
||||
pf.rgbFromBuffer(pix, &inbuf[y*rectWidth], 1);
|
||||
for (c = 0; c < 3; c++)
|
||||
pix[c] += prevRow[c];
|
||||
for (x = 0; x < rectWidth; x++) {
|
||||
/* First pixel in a row */
|
||||
if (x == 0) {
|
||||
pf.rgbFromBuffer(pix, &inbuf[y*rectWidth], 1);
|
||||
for (c = 0; c < 3; c++)
|
||||
pix[c] += prevRow[c];
|
||||
|
||||
memcpy(thisRow, pix, sizeof(pix));
|
||||
memcpy(thisRow, pix, sizeof(pix));
|
||||
|
||||
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++) {
|
||||
est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c];
|
||||
if (est[c] > 255) {
|
||||
|
@ -49,8 +49,8 @@ namespace rfb {
|
||||
public:
|
||||
CharArray() : buf(0) {}
|
||||
CharArray(char* str) : buf(str) {} // note: assumes ownership
|
||||
CharArray(int len) {
|
||||
buf = new char[len];
|
||||
CharArray(size_t len) {
|
||||
buf = new char[len]();
|
||||
}
|
||||
~CharArray() {
|
||||
delete [] buf;
|
||||
|
@ -174,7 +174,8 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is,
|
||||
}
|
||||
}
|
||||
|
||||
zis->removeUnderlying();
|
||||
zis->flushUnderlying();
|
||||
zis->setUnderlying(NULL, 0);
|
||||
}
|
||||
|
||||
#undef ZRLE_DECODE
|
||||
|
@ -17,3 +17,8 @@
|
||||
typedef long ssize_t;
|
||||
#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
|
||||
|
@ -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
|
@ -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()
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -274,6 +274,20 @@ select:active {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* ----------------------------------------
|
||||
* Connection Stats
|
||||
* ----------------------------------------
|
||||
*/
|
||||
#noVNC_connection_stats {
|
||||
top: 0;
|
||||
left: auto;
|
||||
right: 0;
|
||||
position: fixed;
|
||||
background: #9fa5a2d4;
|
||||
color: #00ffa2d4;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/* ----------------------------------------
|
||||
* Control Bar
|
||||
* ----------------------------------------
|
||||
|
@ -174,6 +174,7 @@ const UI = {
|
||||
UI.initSetting('prefer_local_cursor', true);
|
||||
UI.initSetting('enable_webp', true);
|
||||
UI.initSetting('toggle_control_panel', false);
|
||||
UI.initSetting('enable_perf_stats', false);
|
||||
|
||||
UI.setupSettingLabels();
|
||||
},
|
||||
@ -349,6 +350,8 @@ const UI = {
|
||||
document.getElementById("noVNC_settings_button")
|
||||
.addEventListener('click', UI.toggleSettingsPanel);
|
||||
|
||||
document.getElementById("noVNC_setting_enable_perf_stats").addEventListener('click', UI.showStats);
|
||||
|
||||
UI.addSettingChangeHandler('encrypt');
|
||||
UI.addSettingChangeHandler('resize');
|
||||
UI.addSettingChangeHandler('resize', UI.applyResizeMode);
|
||||
@ -368,6 +371,10 @@ const UI = {
|
||||
UI.addSettingChangeHandler('logging', UI.updateLogging);
|
||||
UI.addSettingChangeHandler('reconnect');
|
||||
UI.addSettingChangeHandler('reconnect_delay');
|
||||
UI.addSettingChangeHandler('enable_webp');
|
||||
UI.addSettingChangeHandler('clipboard_seamless');
|
||||
UI.addSettingChangeHandler('clipboard_up');
|
||||
UI.addSettingChangeHandler('clipboard_down');
|
||||
},
|
||||
|
||||
addFullscreenHandlers() {
|
||||
@ -450,6 +457,24 @@ const UI = {
|
||||
.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) {
|
||||
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) {
|
||||
if (!secs){
|
||||
secs = 500;
|
||||
@ -1208,6 +1240,7 @@ const UI = {
|
||||
UI.rfb.addEventListener("securityfailure", UI.securityFailed);
|
||||
UI.rfb.addEventListener("capabilities", UI.updatePowerButton);
|
||||
UI.rfb.addEventListener("clipboard", UI.clipboardReceive);
|
||||
UI.rfb.addEventListener("bottleneck_stats", UI.bottleneckStatsRecieve);
|
||||
|
||||
document.addEventListener('mouseenter', UI.enterVNC);
|
||||
document.addEventListener('mouseleave', UI.leaveVNC);
|
||||
@ -1346,6 +1379,7 @@ const UI = {
|
||||
msg = _("Connected (unencrypted) to ") + UI.desktopName;
|
||||
}
|
||||
UI.showStatus(msg);
|
||||
UI.showStats();
|
||||
UI.updateVisualState('connected');
|
||||
|
||||
// Do this last because it can only be used on rendered elements
|
||||
@ -1965,4 +1999,4 @@ if (l10n.language !== "en" && l10n.dictionary === undefined) {
|
||||
UI.prime();
|
||||
}
|
||||
|
||||
export default UI;
|
||||
export default UI;
|
||||
|
@ -457,6 +457,10 @@ export default class RFB extends EventTargetMixin {
|
||||
RFB.messages.clientCutText(this._sock, text);
|
||||
}
|
||||
|
||||
requestBottleneckStats() {
|
||||
RFB.messages.requestStats(this._sock);
|
||||
}
|
||||
|
||||
// ===== PRIVATE METHODS =====
|
||||
|
||||
_connect() {
|
||||
@ -1495,6 +1499,22 @@ export default class RFB extends EventTargetMixin {
|
||||
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() {
|
||||
if (this._sock.rQwait("ServerFence header", 8, 1)) { return false; }
|
||||
this._sock.rQskipBytes(3); // Padding
|
||||
@ -1605,6 +1625,9 @@ export default class RFB extends EventTargetMixin {
|
||||
}
|
||||
return true;
|
||||
|
||||
case 178: // KASM bottleneck stats
|
||||
return this._handle_server_stats_msg();
|
||||
|
||||
case 248: // ServerFence
|
||||
return this._handle_server_fence_msg();
|
||||
|
||||
@ -2108,6 +2131,22 @@ RFB.messages = {
|
||||
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) {
|
||||
const buff = sock._sQ;
|
||||
const offset = sock._sQlen;
|
||||
|
@ -90,6 +90,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="noVNC_connection_stats">
|
||||
Loading statistics...
|
||||
</div>
|
||||
|
||||
<!-- noVNC Control Bar -->
|
||||
<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>
|
||||
<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>
|
||||
<label><input id="noVNC_setting_toggle_control_panel" type="checkbox" /> Toggle Control Panel via Keystrokes</label></li>
|
||||
<li>
|
||||
|
@ -2,6 +2,7 @@ add_subdirectory(tx)
|
||||
add_subdirectory(common)
|
||||
add_subdirectory(vncconfig)
|
||||
add_subdirectory(vncpasswd)
|
||||
add_subdirectory(kasmvncpasswd)
|
||||
|
||||
install(PROGRAMS vncserver DESTINATION ${BIN_DIR})
|
||||
install(FILES vncserver.man DESTINATION ${MAN_DIR}/man1 RENAME vncserver.1)
|
||||
|
1
unix/kasmvncpasswd/.gitignore
vendored
Normal file
1
unix/kasmvncpasswd/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
kasmvncpasswd
|
8
unix/kasmvncpasswd/CMakeLists.txt
Normal file
8
unix/kasmvncpasswd/CMakeLists.txt
Normal 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})
|
155
unix/kasmvncpasswd/kasmvncpasswd.c
Normal file
155
unix/kasmvncpasswd/kasmvncpasswd.c
Normal 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;
|
||||
}
|
||||
}
|
105
unix/vncserver
Executable file → Normal file
105
unix/vncserver
Executable file → Normal file
@ -33,8 +33,6 @@ if($slashndx>=0) {
|
||||
$exedir = substr($0, 0, $slashndx+1);
|
||||
}
|
||||
|
||||
$vncClasses = "";
|
||||
|
||||
&SanityCheck();
|
||||
|
||||
#
|
||||
@ -44,12 +42,11 @@ $vncClasses = "";
|
||||
|
||||
$geometry = "1024x768";
|
||||
#$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";
|
||||
$vncUserConfig = "$vncUserDir/config";
|
||||
$vncUserName = `id -u -n`;
|
||||
$vncUserName =~ s/^\s+|\s+$//g;
|
||||
|
||||
$vncSystemConfigDir = "/etc/kasmvnc";
|
||||
$vncSystemConfigDefaultsFile = "$vncSystemConfigDir/vncserver-config-defaults";
|
||||
@ -83,7 +80,7 @@ $defaultXStartup
|
||||
"[ -r \$HOME/.Xresources ] && xrdb \$HOME/.Xresources\n".
|
||||
"xsetroot -solid grey\n".
|
||||
"xterm -geometry 80x24+10+10 -ls -title \"\$VNCDESKTOP Desktop\" &\n".
|
||||
"twm &\n");
|
||||
"twm\n");
|
||||
|
||||
$defaultConfig
|
||||
= ("## Supported server options to pass to vncserver upon invocation can be listed\n".
|
||||
@ -94,7 +91,8 @@ $defaultConfig
|
||||
"# desktop=sandbox\n".
|
||||
"# geometry=2000x1200\n".
|
||||
"# localhost\n".
|
||||
"# alwaysshared\n");
|
||||
"# alwaysshared\n".
|
||||
"username=$vncUserName");
|
||||
|
||||
chop($host = `uname -n`);
|
||||
|
||||
@ -206,7 +204,6 @@ my %config;
|
||||
# We set some reasonable defaults. Config file settings
|
||||
# override these where present.
|
||||
$default_opts{desktop} = "edString($desktopName);
|
||||
$default_opts{httpd} = $vncJavaFiles if ($vncJavaFiles);
|
||||
$default_opts{auth} = "edString($xauthorityFile);
|
||||
$default_opts{geometry} = $geometry if ($geometry);
|
||||
$default_opts{depth} = $depth if ($depth);
|
||||
@ -243,46 +240,50 @@ $passwordArgSpecified = 0;
|
||||
@vncAuthStrings = ("vncauth", "tlsvnc", "x509vnc");
|
||||
|
||||
# ...first we check our configuration files' settings
|
||||
if ($config{'securitytypes'}) {
|
||||
$securityTypeArgSpecified = 1;
|
||||
foreach $arg2 (split(',', $config{'securitytypes'})) {
|
||||
if (grep {$_ eq lc($arg2)} @vncAuthStrings) {
|
||||
$vncAuthEnabled = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if ($config{'securitytypes'}) {
|
||||
# $securityTypeArgSpecified = 1;
|
||||
# foreach $arg2 (split(',', $config{'securitytypes'})) {
|
||||
# if (grep {$_ eq lc($arg2)} @vncAuthStrings) {
|
||||
# $vncAuthEnabled = 1;
|
||||
# }
|
||||
# }
|
||||
#}
|
||||
|
||||
# ...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
|
||||
# (even so-called "mandatory" settings).
|
||||
for ($i = 0; $i < @ARGV; ++$i) {
|
||||
# -SecurityTypes can be followed by a space or "="
|
||||
my @splitargs = split('=', $ARGV[$i]);
|
||||
if (@splitargs <= 1 && $i < @ARGV - 1) {
|
||||
push(@splitargs, $ARGV[$i + 1]);
|
||||
}
|
||||
if (lc(@splitargs[0]) eq "-securitytypes") {
|
||||
if (@splitargs > 1) {
|
||||
$securityTypeArgSpecified = 1;
|
||||
}
|
||||
foreach $arg2 (split(',', @splitargs[1])) {
|
||||
if (grep {$_ eq lc($arg2)} @vncAuthStrings) {
|
||||
$vncAuthEnabled = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((lc(@splitargs[0]) eq "-password")
|
||||
|| (lc(@splitargs[0]) eq "-passwordfile"
|
||||
|| (lc(@splitargs[0]) eq "-rfbauth"))) {
|
||||
$passwordArgSpecified = 1;
|
||||
}
|
||||
}
|
||||
#for ($i = 0; $i < @ARGV; ++$i) {
|
||||
# # -SecurityTypes can be followed by a space or "="
|
||||
# my @splitargs = split('=', $ARGV[$i]);
|
||||
# if (@splitargs <= 1 && $i < @ARGV - 1) {
|
||||
# push(@splitargs, $ARGV[$i + 1]);
|
||||
# }
|
||||
# if (lc(@splitargs[0]) eq "-securitytypes") {
|
||||
# if (@splitargs > 1) {
|
||||
# $securityTypeArgSpecified = 1;
|
||||
# }
|
||||
# foreach $arg2 (split(',', @splitargs[1])) {
|
||||
# if (grep {$_ eq lc($arg2)} @vncAuthStrings) {
|
||||
# $vncAuthEnabled = 1;
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# if ((lc(@splitargs[0]) eq "-password")
|
||||
# || (lc(@splitargs[0]) eq "-passwordfile"
|
||||
# || (lc(@splitargs[0]) eq "-rfbauth"))) {
|
||||
# $passwordArgSpecified = 1;
|
||||
# }
|
||||
#}
|
||||
|
||||
if ((!$securityTypeArgSpecified || $vncAuthEnabled) && !$passwordArgSpecified) {
|
||||
($z,$z,$mode) = stat("$vncUserDir/passwd");
|
||||
if (!(-e "$vncUserDir/passwd") || ($mode & 077)) {
|
||||
# Disable vnc auth, kasmvnc uses https basic auth
|
||||
system("echo '' | ".$exedir."vncpasswd -f > $vncUserDir/passwd");
|
||||
|
||||
$kasmAuthEnabled = 1;
|
||||
|
||||
if ($kasmAuthEnabled) {
|
||||
if (!(-e "$ENV{HOME}/.kasmpasswd")) {
|
||||
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) {
|
||||
exit 1;
|
||||
}
|
||||
@ -373,7 +374,8 @@ unless (kill 0, `cat $pidFile`) {
|
||||
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.
|
||||
if (! $skipxstartup) {
|
||||
@ -462,7 +464,13 @@ sub LoadConfig {
|
||||
if ($warnoverride && $config{$k}) {
|
||||
print("Warning: $configFile is overriding previously defined '$k' to be '$v'\n");
|
||||
}
|
||||
$config{$k} = $v;
|
||||
# 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;
|
||||
}
|
||||
} elsif ($_ =~ m/^\s*(\S+)/) {
|
||||
# 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
|
||||
@ -558,13 +566,6 @@ sub CheckDisplayNumber
|
||||
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;
|
||||
}
|
||||
|
||||
@ -848,7 +849,6 @@ sub SanityCheck
|
||||
foreach $cmd ("Xvnc","vncpasswd") {
|
||||
for (split(/:/,$ENV{PATH})) {
|
||||
if (-x "$_/$cmd") {
|
||||
$vncClasses = "$_/../vnc/classes";
|
||||
next cmd2;
|
||||
}
|
||||
}
|
||||
@ -860,7 +860,6 @@ sub SanityCheck
|
||||
foreach $cmd ($exedir."Xvnc",$exedir."vncpasswd") {
|
||||
for (split(/:/,$ENV{PATH})) {
|
||||
if (-x "$cmd") {
|
||||
$vncClasses = $exedir."../vnc/classes";
|
||||
next cmd3;
|
||||
}
|
||||
}
|
||||
|
@ -687,3 +687,12 @@ static void vncKeysymKeyboardEvent(KeySym keysym, int down)
|
||||
*/
|
||||
mieqProcessInputEvents();
|
||||
}
|
||||
|
||||
#if INPUTTHREAD
|
||||
/** This function is called in Xserver/os/inputthread.c when starting
|
||||
the input thread. */
|
||||
void
|
||||
ddxInputThreadInit(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
@ -46,7 +46,7 @@ Xvnc_CPPFLAGS = $(XVNC_CPPFLAGS) -DKASMVNC -DNO_MODULE_EXTS \
|
||||
-I$(top_srcdir)/include ${XSERVERLIBS_CFLAGS} -I$(includedir)
|
||||
|
||||
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
|
||||
|
||||
|
@ -143,6 +143,22 @@ const char* vncGetParamDesc(const char *name)
|
||||
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 count;
|
||||
|
@ -41,6 +41,7 @@ int vncSetParam(const char *name, const char *value);
|
||||
int vncSetParamSimple(const char *nameAndValue);
|
||||
char* vncGetParam(const char *name);
|
||||
const char* vncGetParamDesc(const char *name);
|
||||
int vncIsParamBool(const char *name);
|
||||
|
||||
int vncGetParamCount(void);
|
||||
char *vncGetParamList(void);
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include <network/Socket.h>
|
||||
#include <rfb/Exception.h>
|
||||
#include <rfb/VNCServerST.h>
|
||||
#include <rfb/HTTPServer.h>
|
||||
#include <rfb/LogWriter.h>
|
||||
#include <rfb/Configuration.h>
|
||||
#include <rfb/ServerCore.h>
|
||||
@ -67,54 +66,13 @@ IntParameter queryConnectTimeout("QueryConnectTimeout",
|
||||
"rejecting the connection",
|
||||
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_,
|
||||
std::list<network::SocketListener*> listeners_,
|
||||
std::list<network::SocketListener*> httpListeners_,
|
||||
const char* name, const rfb::PixelFormat &pf,
|
||||
int width, int height,
|
||||
void* fbptr, int stride)
|
||||
: screenIndex(screenIndex_),
|
||||
server(0), httpServer(0),
|
||||
listeners(listeners_), httpListeners(httpListeners_),
|
||||
server(0), listeners(listeners_),
|
||||
directFbptr(true),
|
||||
queryConnectId(0), queryConnectTimer(this)
|
||||
{
|
||||
@ -124,20 +82,11 @@ XserverDesktop::XserverDesktop(int screenIndex_,
|
||||
setFramebuffer(width, height, fbptr, stride);
|
||||
server->setQueryConnectionHandler(this);
|
||||
|
||||
if (!httpListeners.empty ())
|
||||
httpServer = new FileHTTPServer(this);
|
||||
|
||||
for (std::list<SocketListener*>::iterator i = listeners.begin();
|
||||
i != listeners.end();
|
||||
i++) {
|
||||
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()
|
||||
@ -147,14 +96,8 @@ XserverDesktop::~XserverDesktop()
|
||||
delete listeners.back();
|
||||
listeners.pop_back();
|
||||
}
|
||||
while (!httpListeners.empty()) {
|
||||
vncRemoveNotifyFd(listeners.back()->getFd());
|
||||
delete httpListeners.back();
|
||||
httpListeners.pop_back();
|
||||
}
|
||||
if (!directFbptr)
|
||||
delete [] data;
|
||||
delete httpServer;
|
||||
delete server;
|
||||
}
|
||||
|
||||
@ -201,56 +144,6 @@ void XserverDesktop::refreshScreenLayout()
|
||||
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
|
||||
XserverDesktop::queryConnection(network::Socket* sock,
|
||||
const char* userName,
|
||||
@ -370,14 +263,10 @@ void XserverDesktop::handleSocketEvent(int fd, bool read, bool write)
|
||||
if (read) {
|
||||
if (handleListenerEvent(fd, &listeners, server))
|
||||
return;
|
||||
if (handleListenerEvent(fd, &httpListeners, httpServer))
|
||||
return;
|
||||
}
|
||||
|
||||
if (handleSocketEvent(fd, server, read, write))
|
||||
return;
|
||||
if (handleSocketEvent(fd, httpServer, read, write))
|
||||
return;
|
||||
|
||||
vlog.error("Cannot find file descriptor for socket event");
|
||||
} catch (rdr::Exception& e) {
|
||||
@ -458,21 +347,6 @@ void XserverDesktop::blockHandler(int* timeout)
|
||||
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
|
||||
int cursorX, cursorY;
|
||||
|
@ -32,11 +32,9 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <rfb/SDesktop.h>
|
||||
#include <rfb/HTTPServer.h>
|
||||
#include <rfb/PixelBuffer.h>
|
||||
#include <rfb/Configuration.h>
|
||||
#include <rfb/VNCServerST.h>
|
||||
#include <rdr/SubstitutingInStream.h>
|
||||
#include <unixcommon.h>
|
||||
#include "Input.h"
|
||||
|
||||
@ -47,14 +45,12 @@ namespace rfb {
|
||||
namespace network { class SocketListener; class Socket; class SocketServer; }
|
||||
|
||||
class XserverDesktop : public rfb::SDesktop, public rfb::FullFramePixelBuffer,
|
||||
public rdr::Substitutor,
|
||||
public rfb::VNCServerST::QueryConnectionHandler,
|
||||
public rfb::Timer::Callback {
|
||||
public:
|
||||
|
||||
XserverDesktop(int screenIndex,
|
||||
std::list<network::SocketListener*> listeners_,
|
||||
std::list<network::SocketListener*> httpListeners_,
|
||||
const char* name, const rfb::PixelFormat &pf,
|
||||
int width, int height, void* fbptr, int stride);
|
||||
virtual ~XserverDesktop();
|
||||
@ -99,9 +95,6 @@ public:
|
||||
// rfb::PixelBuffer callbacks
|
||||
virtual void grabRegion(const rfb::Region& r);
|
||||
|
||||
// rdr::Substitutor callback
|
||||
virtual char* substitute(const char* varName);
|
||||
|
||||
// rfb::VNCServerST::QueryConnectionHandler callback
|
||||
virtual rfb::VNCServerST::queryResult queryConnection(network::Socket* sock,
|
||||
const char* userName,
|
||||
@ -121,9 +114,7 @@ private:
|
||||
|
||||
int screenIndex;
|
||||
rfb::VNCServerST* server;
|
||||
rfb::HTTPServer* httpServer;
|
||||
std::list<network::SocketListener*> listeners;
|
||||
std::list<network::SocketListener*> httpListeners;
|
||||
bool directFbptr;
|
||||
|
||||
uint32_t queryConnectId;
|
||||
|
@ -37,15 +37,13 @@ Specify the size of the desktop to be created. Default is 1024x768.
|
||||
.TP
|
||||
.B \-depth \fIdepth\fP
|
||||
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
|
||||
strange behaviour by applications.
|
||||
other possible values are 16 and 32. Anything else is likely to cause strange
|
||||
behaviour by applications and may prevent the server from starting at all.
|
||||
.
|
||||
.TP
|
||||
.B \-pixelformat \fIformat\fP
|
||||
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
|
||||
next three green, and the least significant three represent red), the default
|
||||
for depth 16 is RGB565 and for depth 24 is RGB888.
|
||||
Specify pixel format for server to use (BGRnnn or RGBnnn). The default for
|
||||
depth 16 is RGB565 and for depth 24 and 32 is RGB888.
|
||||
.
|
||||
.TP
|
||||
.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.
|
||||
.
|
||||
.TP
|
||||
.B \-KasmPasswordFile \fIpasswd-file\fP
|
||||
Password file for BasicAuth, created with the \fBkasmvncpasswd\fP utility.
|
||||
Default \fI~/.kasmpasswd\fP.
|
||||
.
|
||||
.TP
|
||||
.B \-AcceptCutText
|
||||
Accept clipboard updates from clients. Default is on.
|
||||
.
|
||||
@ -318,6 +321,7 @@ Require SSL for websocket connections. Default off, non-SSL allowed.
|
||||
.TP
|
||||
.B \-basicAuth \fIuser:pass\fP
|
||||
Username and password for websocket connections. Default empty, no authentication required.
|
||||
If the password is empty, read it from the \fB-KasmPasswordFile\fP.
|
||||
.
|
||||
.TP
|
||||
.B \-SecurityTypes \fIsec-types\fP
|
||||
|
@ -155,10 +155,10 @@ void vncExtensionInit(void)
|
||||
vncExtGeneration = vncGetServerGeneration();
|
||||
|
||||
if (vncGetScreenCount() > MAXSCREENS)
|
||||
vncFatalError("vncExtensionInit: too many screens");
|
||||
vncFatalError("vncExtensionInit: too many screens\n");
|
||||
|
||||
if (sizeof(ShortRect) != sizeof(struct UpdateRect))
|
||||
vncFatalError("vncExtensionInit: Incompatible ShortRect size");
|
||||
vncFatalError("vncExtensionInit: Incompatible ShortRect size\n");
|
||||
|
||||
vncAddExtension();
|
||||
|
||||
@ -193,7 +193,6 @@ void vncExtensionInit(void)
|
||||
|
||||
if (!desktop[scr]) {
|
||||
std::list<network::SocketListener*> listeners;
|
||||
std::list<network::SocketListener*> httpListeners;
|
||||
if (scr == 0 && vncInetdSock != -1) {
|
||||
if (network::isSocketListening(vncInetdSock))
|
||||
{
|
||||
@ -247,7 +246,6 @@ void vncExtensionInit(void)
|
||||
vncSetGlueContext(scr);
|
||||
desktop[scr] = new XserverDesktop(scr,
|
||||
listeners,
|
||||
httpListeners,
|
||||
desktopNameStr.buf,
|
||||
pf,
|
||||
vncGetScreenWidth(),
|
||||
@ -266,7 +264,7 @@ void vncExtensionInit(void)
|
||||
vncHooksInit(scr);
|
||||
}
|
||||
} catch (rdr::Exception& e) {
|
||||
vncFatalError("vncExtInit: %s",e.str());
|
||||
vncFatalError("vncExtInit: %s\n",e.str());
|
||||
}
|
||||
|
||||
vncRegisterBlockHandlers();
|
||||
@ -280,7 +278,7 @@ void vncExtensionClose(void)
|
||||
desktop[scr] = NULL;
|
||||
}
|
||||
} 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) {
|
||||
// Let the RFB core know of the new dimensions and framebuffer
|
||||
desktop[scrIdx]->setFramebuffer(width, height,
|
||||
vncFbptr[scrIdx], vncFbstride[scrIdx]);
|
||||
try {
|
||||
desktop[scrIdx]->setFramebuffer(width, height,
|
||||
vncFbptr[scrIdx],
|
||||
vncFbstride[scrIdx]);
|
||||
} catch (rdr::Exception& e) {
|
||||
vncFatalError("vncPostScreenResize: %s\n", e.str());
|
||||
}
|
||||
}
|
||||
|
||||
desktop[scrIdx]->unblockUpdates();
|
||||
@ -449,7 +452,7 @@ void vncRefreshScreenLayout(int scrIdx)
|
||||
try {
|
||||
desktop[scrIdx]->refreshScreenLayout();
|
||||
} catch (rdr::Exception& e) {
|
||||
vncFatalError("%s", e.str());
|
||||
vncFatalError("vncRefreshScreenLayout: %s\n", e.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -388,10 +388,12 @@ static inline void add_changed(ScreenPtr pScreen, RegionPtr reg)
|
||||
vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen);
|
||||
if (vncHooksScreen->ignoreHooks)
|
||||
return;
|
||||
if (RegionNil(reg))
|
||||
return;
|
||||
vncAddChanged(pScreen->myNum,
|
||||
(const struct UpdateRect*)REGION_EXTENTS(pScreen, reg),
|
||||
REGION_NUM_RECTS(reg),
|
||||
(const struct UpdateRect*)REGION_RECTS(reg));
|
||||
(const struct UpdateRect*)RegionExtents(reg),
|
||||
RegionNumRects(reg),
|
||||
(const struct UpdateRect*)RegionRects(reg));
|
||||
}
|
||||
|
||||
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);
|
||||
if (vncHooksScreen->ignoreHooks)
|
||||
return;
|
||||
if (RegionNil(dst))
|
||||
return;
|
||||
vncAddCopied(pScreen->myNum,
|
||||
(const struct UpdateRect*)REGION_EXTENTS(pScreen, dst),
|
||||
REGION_NUM_RECTS(dst),
|
||||
(const struct UpdateRect*)REGION_RECTS(dst), dx, dy);
|
||||
(const struct UpdateRect*)RegionExtents(dst),
|
||||
RegionNumRects(dst),
|
||||
(const struct UpdateRect*)RegionRects(dst), dx, dy);
|
||||
}
|
||||
|
||||
static inline Bool is_visible(DrawablePtr drawable)
|
||||
@ -538,15 +542,15 @@ static void vncHooksCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
|
||||
|
||||
SCREEN_PROLOGUE(pWin->drawable.pScreen, CopyWindow);
|
||||
|
||||
REGION_NULL(pScreen, &copied);
|
||||
REGION_COPY(pScreen, &copied, pOldRegion);
|
||||
RegionNull(&copied);
|
||||
RegionCopy(&copied, pOldRegion);
|
||||
|
||||
screen_box.x1 = 0;
|
||||
screen_box.y1 = 0;
|
||||
screen_box.x2 = pScreen->width;
|
||||
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;
|
||||
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.
|
||||
// Finally, make sure we don't get copies to or from regions outside
|
||||
// the framebuffer.
|
||||
REGION_INTERSECT(pScreen, &copied, &copied, &screen_rgn);
|
||||
REGION_TRANSLATE(pScreen, &copied, dx, dy);
|
||||
REGION_INTERSECT(pScreen, &copied, &copied, &screen_rgn);
|
||||
REGION_INTERSECT(pScreen, &copied, &copied, &pWin->borderClip);
|
||||
RegionIntersect(&copied, &copied, &screen_rgn);
|
||||
RegionTranslate(&copied, dx, dy);
|
||||
RegionIntersect(&copied, &copied, &screen_rgn);
|
||||
RegionIntersect(&copied, &copied, &pWin->borderClip);
|
||||
|
||||
(*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);
|
||||
REGION_UNINIT(pScreen, &screen_rgn);
|
||||
RegionUninit(&copied);
|
||||
RegionUninit(&screen_rgn);
|
||||
|
||||
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.y2 = h ? (box.y1 + h) : (pWin->drawable.y + pWin->drawable.height);
|
||||
|
||||
REGION_INIT(pScreen, ®, &box, 0);
|
||||
REGION_INTERSECT(pScreen, ®, ®, &pWin->clipList);
|
||||
RegionInitBoxes(®, &box, 1);
|
||||
RegionIntersect(®, ®, &pWin->clipList);
|
||||
|
||||
(*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, ®);
|
||||
}
|
||||
|
||||
REGION_UNINIT(pScreen, ®);
|
||||
RegionUninit(®);
|
||||
|
||||
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.x2 = box.x1 + width;
|
||||
box.y2 = box.y1 + height;
|
||||
REGION_INIT(pScreen, &changed, &box, 0);
|
||||
RegionInitBoxes(&changed, &box, 1);
|
||||
|
||||
box.x1 = 0;
|
||||
box.y1 = 0;
|
||||
box.x2 = pScreen->width;
|
||||
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 {
|
||||
REGION_NULL(pScreen, &changed);
|
||||
RegionNull(&changed);
|
||||
}
|
||||
|
||||
|
||||
(*ps->Composite)(op, pSrc, pMask, pDst, xSrc, ySrc,
|
||||
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);
|
||||
}
|
||||
@ -878,28 +880,27 @@ static void vncHooksGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
|
||||
RegionRec fbreg;
|
||||
|
||||
changed = GlyphsToRegion(pScreen, nlists, lists, glyphs);
|
||||
REGION_TRANSLATE(pScreen, changed,
|
||||
RegionTranslate(changed,
|
||||
pDst->pDrawable->x, pDst->pDrawable->y);
|
||||
|
||||
fbbox.x1 = 0;
|
||||
fbbox.y1 = 0;
|
||||
fbbox.x2 = pScreen->width;
|
||||
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 {
|
||||
changed = REGION_CREATE(pScreen, NullBox, 0);
|
||||
changed = RegionCreate(NullBox, 0);
|
||||
}
|
||||
|
||||
(*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);
|
||||
}
|
||||
@ -914,15 +915,14 @@ static void vncHooksCompositeRects(CARD8 op, PicturePtr pDst,
|
||||
if (is_visible(pDst->pDrawable)) {
|
||||
changed = RECTS_TO_REGION(pScreen, nRect, rects, CT_NONE);
|
||||
} else {
|
||||
changed = REGION_CREATE(pScreen, NullBox, 0);
|
||||
changed = RegionCreate(NullBox, 0);
|
||||
}
|
||||
|
||||
(*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);
|
||||
}
|
||||
@ -970,27 +970,26 @@ static void vncHooksTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
|
||||
box.y1 += pDst->pDrawable->y;
|
||||
box.x2 += pDst->pDrawable->x;
|
||||
box.y2 += pDst->pDrawable->y;
|
||||
REGION_INIT(pScreen, &changed, &box, 0);
|
||||
RegionInitBoxes(&changed, &box, 1);
|
||||
|
||||
box.x1 = 0;
|
||||
box.y1 = 0;
|
||||
box.x2 = pScreen->width;
|
||||
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 {
|
||||
REGION_NULL(pScreen, &changed);
|
||||
RegionNull(&changed);
|
||||
}
|
||||
|
||||
(*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);
|
||||
}
|
||||
@ -1036,27 +1035,26 @@ static void vncHooksTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
|
||||
box.y1 += pDst->pDrawable->y;
|
||||
box.x2 += pDst->pDrawable->x;
|
||||
box.y2 += pDst->pDrawable->y;
|
||||
REGION_INIT(pScreen, &changed, &box, 0);
|
||||
RegionInitBoxes(&changed, &box, 1);
|
||||
|
||||
box.x1 = 0;
|
||||
box.y1 = 0;
|
||||
box.x2 = pScreen->width;
|
||||
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 {
|
||||
REGION_NULL(pScreen, &changed);
|
||||
RegionNull(&changed);
|
||||
}
|
||||
|
||||
(*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);
|
||||
}
|
||||
@ -1097,27 +1095,26 @@ static void vncHooksTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
|
||||
box.y1 += pDst->pDrawable->y;
|
||||
box.x2 += pDst->pDrawable->x;
|
||||
box.y2 += pDst->pDrawable->y;
|
||||
REGION_INIT(pScreen, &changed, &box, 0);
|
||||
RegionInitBoxes(&changed, &box, 1);
|
||||
|
||||
box.x1 = 0;
|
||||
box.y1 = 0;
|
||||
box.x2 = pScreen->width;
|
||||
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 {
|
||||
REGION_NULL(pScreen, &changed);
|
||||
RegionNull(&changed);
|
||||
}
|
||||
|
||||
(*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);
|
||||
}
|
||||
@ -1156,27 +1153,26 @@ static void vncHooksTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
|
||||
box.y1 += pDst->pDrawable->y;
|
||||
box.x2 += pDst->pDrawable->x;
|
||||
box.y2 += pDst->pDrawable->y;
|
||||
REGION_INIT(pScreen, &changed, &box, 0);
|
||||
RegionInitBoxes(&changed, &box, 1);
|
||||
|
||||
box.x1 = 0;
|
||||
box.y1 = 0;
|
||||
box.x2 = pScreen->width;
|
||||
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 {
|
||||
REGION_NULL(pScreen, &changed);
|
||||
RegionNull(&changed);
|
||||
}
|
||||
|
||||
(*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);
|
||||
}
|
||||
@ -1365,17 +1361,17 @@ static void vncHooksFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit,
|
||||
|
||||
GC_OP_PROLOGUE(pGC, FillSpans);
|
||||
|
||||
REGION_NULL(pGC->pScreen, ®);
|
||||
REGION_COPY(pGC->pScreen, ®, pGC->pCompositeClip);
|
||||
RegionNull(®);
|
||||
RegionCopy(®, pGC->pCompositeClip);
|
||||
|
||||
if (pDrawable->type == DRAWABLE_WINDOW)
|
||||
REGION_INTERSECT(pScreen, ®, ®, &((WindowPtr)pDrawable)->borderClip);
|
||||
RegionIntersect(®, ®, &((WindowPtr)pDrawable)->borderClip);
|
||||
|
||||
(*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
|
||||
|
||||
add_changed(pGC->pScreen, ®);
|
||||
|
||||
REGION_UNINIT(pGC->pScreen, ®);
|
||||
RegionUninit(®);
|
||||
|
||||
GC_OP_EPILOGUE(pGC);
|
||||
}
|
||||
@ -1391,17 +1387,17 @@ static void vncHooksSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
|
||||
|
||||
GC_OP_PROLOGUE(pGC, SetSpans);
|
||||
|
||||
REGION_NULL(pGC->pScreen, ®);
|
||||
REGION_COPY(pGC->pScreen, ®, pGC->pCompositeClip);
|
||||
RegionNull(®);
|
||||
RegionCopy(®, pGC->pCompositeClip);
|
||||
|
||||
if (pDrawable->type == DRAWABLE_WINDOW)
|
||||
REGION_INTERSECT(pScreen, ®, ®, &((WindowPtr)pDrawable)->borderClip);
|
||||
RegionIntersect(®, ®, &((WindowPtr)pDrawable)->borderClip);
|
||||
|
||||
(*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
|
||||
|
||||
add_changed(pGC->pScreen, ®);
|
||||
|
||||
REGION_UNINIT(pGC->pScreen, ®);
|
||||
RegionUninit(®);
|
||||
|
||||
GC_OP_EPILOGUE(pGC);
|
||||
}
|
||||
@ -1422,15 +1418,15 @@ static void vncHooksPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
|
||||
box.x2 = box.x1 + w;
|
||||
box.y2 = box.y1 + h;
|
||||
|
||||
REGION_INIT(pGC->pScreen, ®, &box, 0);
|
||||
REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip);
|
||||
RegionInitBoxes(®, &box, 1);
|
||||
RegionIntersect(®, ®, pGC->pCompositeClip);
|
||||
|
||||
(*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, leftPad, format,
|
||||
pBits);
|
||||
|
||||
add_changed(pGC->pScreen, ®);
|
||||
|
||||
REGION_UNINIT(pGC->pScreen, ®);
|
||||
RegionUninit(®);
|
||||
|
||||
GC_OP_EPILOGUE(pGC);
|
||||
}
|
||||
@ -1451,7 +1447,7 @@ static RegionPtr vncHooksCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
|
||||
|
||||
// Apparently this happens now and then...
|
||||
if ((w == 0) || (h == 0))
|
||||
REGION_NULL(pGC->pScreen, &dst);
|
||||
RegionNull(&dst);
|
||||
else {
|
||||
BoxRec box;
|
||||
|
||||
@ -1460,10 +1456,10 @@ static RegionPtr vncHooksCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
|
||||
box.x2 = box.x1 + w;
|
||||
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.
|
||||
if (is_visible(pSrc)) {
|
||||
@ -1474,38 +1470,36 @@ static RegionPtr vncHooksCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
|
||||
box.x2 = box.x1 + w;
|
||||
box.y2 = box.y1 + h;
|
||||
|
||||
REGION_INIT(pGC->pScreen, &src, &box, 0);
|
||||
RegionInitBoxes(&src, &box, 1);
|
||||
|
||||
if ((pSrc->type == DRAWABLE_WINDOW) &&
|
||||
REGION_NOTEMPTY(pScreen, &((WindowPtr)pSrc)->clipList)) {
|
||||
REGION_INTERSECT(pScreen, &src, &src, &((WindowPtr)pSrc)->clipList);
|
||||
RegionNotEmpty(&((WindowPtr)pSrc)->clipList)) {
|
||||
RegionIntersect(&src, &src, &((WindowPtr)pSrc)->clipList);
|
||||
}
|
||||
|
||||
REGION_TRANSLATE(pScreen, &src,
|
||||
RegionTranslate(&src,
|
||||
dstx + pDst->x - srcx - pSrc->x,
|
||||
dsty + pDst->y - srcy - pSrc->y);
|
||||
} else {
|
||||
REGION_NULL(pGC->pScreen, &src);
|
||||
RegionNull(&src);
|
||||
}
|
||||
|
||||
REGION_NULL(pGC->pScreen, &changed);
|
||||
RegionNull(&changed);
|
||||
|
||||
REGION_SUBTRACT(pScreen, &changed, &dst, &src);
|
||||
REGION_INTERSECT(pScreen, &dst, &dst, &src);
|
||||
RegionSubtract(&changed, &dst, &src);
|
||||
RegionIntersect(&dst, &dst, &src);
|
||||
|
||||
ret = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
|
||||
|
||||
if (REGION_NOTEMPTY(pScreen, &dst))
|
||||
add_copied(pGC->pScreen, &dst,
|
||||
dstx + pDst->x - srcx - pSrc->x,
|
||||
dsty + pDst->y - srcy - pSrc->y);
|
||||
add_copied(pGC->pScreen, &dst,
|
||||
dstx + pDst->x - srcx - pSrc->x,
|
||||
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);
|
||||
REGION_UNINIT(pGC->pScreen, &src);
|
||||
REGION_UNINIT(pGC->pScreen, &changed);
|
||||
RegionUninit(&dst);
|
||||
RegionUninit(&src);
|
||||
RegionUninit(&changed);
|
||||
|
||||
GC_OP_EPILOGUE(pGC);
|
||||
|
||||
@ -1532,15 +1526,15 @@ static RegionPtr vncHooksCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
|
||||
box.x2 = box.x1 + w;
|
||||
box.y2 = box.y1 + h;
|
||||
|
||||
REGION_INIT(pGC->pScreen, ®, &box, 0);
|
||||
REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip);
|
||||
RegionInitBoxes(®, &box, 1);
|
||||
RegionIntersect(®, ®, pGC->pCompositeClip);
|
||||
|
||||
ret = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h,
|
||||
dstx, dsty, plane);
|
||||
|
||||
add_changed(pGC->pScreen, ®);
|
||||
|
||||
REGION_UNINIT(pGC->pScreen, ®);
|
||||
RegionUninit(®);
|
||||
|
||||
GC_OP_EPILOGUE(pGC);
|
||||
|
||||
@ -1596,14 +1590,14 @@ static void vncHooksPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
|
||||
box.x2 = maxX + 1 + pDrawable->x;
|
||||
box.y2 = maxY + 1 + pDrawable->y;
|
||||
|
||||
REGION_INIT(pGC->pScreen, ®, &box, 0);
|
||||
REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip);
|
||||
RegionInitBoxes(®, &box, 1);
|
||||
RegionIntersect(®, ®, pGC->pCompositeClip);
|
||||
|
||||
(*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pts);
|
||||
|
||||
add_changed(pGC->pScreen, ®);
|
||||
|
||||
REGION_UNINIT(pGC->pScreen, ®);
|
||||
RegionUninit(®);
|
||||
|
||||
out:
|
||||
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);
|
||||
REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip);
|
||||
RegionIntersect(reg, reg, pGC->pCompositeClip);
|
||||
|
||||
(*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, ppts);
|
||||
|
||||
add_changed(pGC->pScreen, reg);
|
||||
|
||||
REGION_DESTROY(pGC->pScreen, reg);
|
||||
RegionDestroy(reg);
|
||||
|
||||
out:
|
||||
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);
|
||||
REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip);
|
||||
RegionIntersect(reg, reg, pGC->pCompositeClip);
|
||||
|
||||
(*pGC->ops->PolySegment) (pDrawable, pGC, nseg, segs);
|
||||
|
||||
add_changed(pGC->pScreen, reg);
|
||||
|
||||
REGION_DESTROY(pGC->pScreen, reg);
|
||||
RegionDestroy(reg);
|
||||
|
||||
out:
|
||||
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);
|
||||
REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip);
|
||||
RegionIntersect(reg, reg, pGC->pCompositeClip);
|
||||
|
||||
(*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, rects);
|
||||
|
||||
add_changed(pGC->pScreen, reg);
|
||||
|
||||
REGION_DESTROY(pGC->pScreen, reg);
|
||||
RegionDestroy(reg);
|
||||
|
||||
out:
|
||||
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);
|
||||
REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip);
|
||||
RegionIntersect(reg, reg, pGC->pCompositeClip);
|
||||
|
||||
(*pGC->ops->PolyArc) (pDrawable, pGC, narcs, arcs);
|
||||
|
||||
add_changed(pGC->pScreen, reg);
|
||||
|
||||
REGION_DESTROY(pGC->pScreen, reg);
|
||||
RegionDestroy(reg);
|
||||
|
||||
out:
|
||||
GC_OP_EPILOGUE(pGC);
|
||||
@ -2035,14 +2029,14 @@ static void vncHooksFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape,
|
||||
box.x2 = maxX + 1 + pDrawable->x;
|
||||
box.y2 = maxY + 1 + pDrawable->y;
|
||||
|
||||
REGION_INIT(pGC->pScreen, ®, &box, 0);
|
||||
REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip);
|
||||
RegionInitBoxes(®, &box, 1);
|
||||
RegionIntersect(®, ®, pGC->pCompositeClip);
|
||||
|
||||
(*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pts);
|
||||
|
||||
add_changed(pGC->pScreen, ®);
|
||||
|
||||
REGION_UNINIT(pGC->pScreen, ®);
|
||||
RegionUninit(®);
|
||||
|
||||
out:
|
||||
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);
|
||||
REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip);
|
||||
RegionIntersect(reg, reg, pGC->pCompositeClip);
|
||||
|
||||
(*pGC->ops->PolyFillRect) (pDrawable, pGC, nrects, rects);
|
||||
|
||||
add_changed(pGC->pScreen, reg);
|
||||
|
||||
REGION_DESTROY(pGC->pScreen, reg);
|
||||
RegionDestroy(reg);
|
||||
|
||||
out:
|
||||
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);
|
||||
REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip);
|
||||
RegionIntersect(reg, reg, pGC->pCompositeClip);
|
||||
|
||||
(*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, arcs);
|
||||
|
||||
add_changed(pGC->pScreen, reg);
|
||||
|
||||
REGION_DESTROY(pGC->pScreen, reg);
|
||||
RegionDestroy(reg);
|
||||
|
||||
out:
|
||||
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);
|
||||
|
||||
REGION_INIT(pGC->pScreen, ®, &box, 0);
|
||||
REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip);
|
||||
RegionInitBoxes(®, &box, 1);
|
||||
RegionIntersect(®, ®, pGC->pCompositeClip);
|
||||
|
||||
ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars);
|
||||
|
||||
add_changed(pGC->pScreen, ®);
|
||||
|
||||
REGION_UNINIT(pGC->pScreen, ®);
|
||||
RegionUninit(®);
|
||||
|
||||
out:
|
||||
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);
|
||||
|
||||
REGION_INIT(pGC->pScreen, ®, &box, 0);
|
||||
REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip);
|
||||
RegionInitBoxes(®, &box, 1);
|
||||
RegionIntersect(®, ®, pGC->pCompositeClip);
|
||||
|
||||
ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars);
|
||||
|
||||
add_changed(pGC->pScreen, ®);
|
||||
|
||||
REGION_UNINIT(pGC->pScreen, ®);
|
||||
RegionUninit(®);
|
||||
|
||||
out:
|
||||
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);
|
||||
|
||||
REGION_INIT(pGC->pScreen, ®, &box, 0);
|
||||
REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip);
|
||||
RegionInitBoxes(®, &box, 1);
|
||||
RegionIntersect(®, ®, pGC->pCompositeClip);
|
||||
|
||||
(*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars);
|
||||
|
||||
add_changed(pGC->pScreen, ®);
|
||||
|
||||
REGION_UNINIT(pGC->pScreen, ®);
|
||||
RegionUninit(®);
|
||||
|
||||
out:
|
||||
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);
|
||||
|
||||
REGION_INIT(pGC->pScreen, ®, &box, 0);
|
||||
REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip);
|
||||
RegionInitBoxes(®, &box, 1);
|
||||
RegionIntersect(®, ®, pGC->pCompositeClip);
|
||||
|
||||
(*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars);
|
||||
|
||||
add_changed(pGC->pScreen, ®);
|
||||
|
||||
REGION_UNINIT(pGC->pScreen, ®);
|
||||
RegionUninit(®);
|
||||
|
||||
out:
|
||||
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);
|
||||
|
||||
REGION_INIT(pGC->pScreen, ®, &box, 0);
|
||||
REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip);
|
||||
RegionInitBoxes(®, &box, 1);
|
||||
RegionIntersect(®, ®, pGC->pCompositeClip);
|
||||
|
||||
(*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
||||
|
||||
add_changed(pGC->pScreen, ®);
|
||||
|
||||
REGION_UNINIT(pGC->pScreen, ®);
|
||||
RegionUninit(®);
|
||||
|
||||
out:
|
||||
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);
|
||||
|
||||
REGION_INIT(pGC->pScreen, ®, &box, 0);
|
||||
REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip);
|
||||
RegionInitBoxes(®, &box, 1);
|
||||
RegionIntersect(®, ®, pGC->pCompositeClip);
|
||||
|
||||
(*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
||||
|
||||
add_changed(pGC->pScreen, ®);
|
||||
|
||||
REGION_UNINIT(pGC->pScreen, ®);
|
||||
RegionUninit(®);
|
||||
|
||||
out:
|
||||
GC_OP_EPILOGUE(pGC);
|
||||
@ -2419,14 +2413,14 @@ static void vncHooksPushPixels(GCPtr pGC, PixmapPtr pBitMap,
|
||||
box.x2 = box.x1 + w;
|
||||
box.y2 = box.y1 + h;
|
||||
|
||||
REGION_INIT(pGC->pScreen, ®, &box, 0);
|
||||
REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip);
|
||||
RegionInitBoxes(®, &box, 1);
|
||||
RegionIntersect(®, ®, pGC->pCompositeClip);
|
||||
|
||||
(*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y);
|
||||
|
||||
add_changed(pGC->pScreen, ®);
|
||||
|
||||
REGION_UNINIT(pGC->pScreen, ®);
|
||||
RegionUninit(®);
|
||||
|
||||
GC_OP_EPILOGUE(pGC);
|
||||
}
|
||||
|
@ -596,7 +596,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
||||
if (displayNumFree(displayNum)) break;
|
||||
|
||||
if (displayNum == 100)
|
||||
FatalError("Xvnc error: no free display number for -inetd");
|
||||
FatalError("Xvnc error: no free display number for -inetd\n");
|
||||
}
|
||||
|
||||
display = displayNumStr;
|
||||
@ -639,6 +639,20 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
||||
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]))
|
||||
return 1;
|
||||
|
||||
@ -1003,8 +1017,8 @@ xf86SetRootClip (ScreenPtr pScreen, Bool enable)
|
||||
{
|
||||
RegionPtr borderVisible;
|
||||
|
||||
borderVisible = REGION_CREATE(pScreen, NullBox, 1);
|
||||
REGION_SUBTRACT(pScreen, borderVisible,
|
||||
borderVisible = RegionCreate(NullBox, 1);
|
||||
RegionSubtract(borderVisible,
|
||||
&pWin->borderClip, &pWin->winSize);
|
||||
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
|
||||
* it doesn't...)
|
||||
*/
|
||||
@ -1023,18 +1037,18 @@ xf86SetRootClip (ScreenPtr pScreen, Bool enable)
|
||||
box.y1 = 0;
|
||||
box.x2 = pScreen->width;
|
||||
box.y2 = pScreen->height;
|
||||
REGION_INIT (pScreen, &pWin->winSize, &box, 1);
|
||||
REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
|
||||
RegionInit(&pWin->winSize, &box, 1);
|
||||
RegionInit(&pWin->borderSize, &box, 1);
|
||||
if (WasViewable)
|
||||
REGION_RESET(pScreen, &pWin->borderClip, &box);
|
||||
RegionReset(&pWin->borderClip, &box);
|
||||
pWin->drawable.width = pScreen->width;
|
||||
pWin->drawable.height = pScreen->height;
|
||||
REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
|
||||
RegionBreak(&pWin->clipList);
|
||||
}
|
||||
else
|
||||
{
|
||||
REGION_EMPTY(pScreen, &pWin->borderClip);
|
||||
REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
|
||||
RegionEmpty(&pWin->borderClip);
|
||||
RegionBreak(&pWin->clipList);
|
||||
}
|
||||
|
||||
ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
|
||||
@ -1577,16 +1591,6 @@ vfbScreenInit(ScreenPtr pScreen, int argc, char **argv)
|
||||
miSetPixmapDepths();
|
||||
|
||||
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:
|
||||
miSetVisualTypesAndMasks (16,
|
||||
((1 << TrueColor) |
|
||||
@ -1804,7 +1808,7 @@ InitOutput(ScreenInfo *scrInfo, int argc, char **argv)
|
||||
{
|
||||
if (-1 == AddScreen(vfbScreenInit, argc, argv))
|
||||
{
|
||||
FatalError("Couldn't add screen %d", i);
|
||||
FatalError("Couldn't add screen %d\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
@ -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();
|
@ -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)
|
@ -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
|
@ -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;
|
@ -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;
|
@ -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();
|
@ -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();
|
@ -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();
|
@ -30,12 +30,10 @@ static LogWriter vlog("DIBSectionBuffer");
|
||||
|
||||
DIBSectionBuffer::DIBSectionBuffer(HWND window_)
|
||||
: bitmap(0), window(window_), device(0) {
|
||||
memset(&format, 0, sizeof(format));
|
||||
}
|
||||
|
||||
DIBSectionBuffer::DIBSectionBuffer(HDC device_)
|
||||
: bitmap(0), window(0), device(device_) {
|
||||
memset(&format, 0, sizeof(format));
|
||||
}
|
||||
|
||||
DIBSectionBuffer::~DIBSectionBuffer() {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user