diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d0c2e4..179c278 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/README.md b/README.md index 9c40b8b..47d26df 100644 --- a/README.md +++ b/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 + +# 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 / -# change owner of pre-installed cert to your user +# 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 | diff --git a/builder/README.md b/builder/README.md index d6f5a45..41af2d8 100644 --- a/builder/README.md +++ b/builder/README.md @@ -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/ diff --git a/builder/build.sh b/builder/build.sh index 53fb9f8..87e8a02 100755 --- a/builder/build.sh +++ b/builder/build.sh @@ -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 \ diff --git a/builder/dockerfile.build b/builder/dockerfile.build index b922361..7ee1a42 100644 --- a/builder/dockerfile.build +++ b/builder/dockerfile.build @@ -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 diff --git a/builder/install/install.sh b/builder/install/install.sh deleted file mode 100755 index e027c07..0000000 --- a/builder/install/install.sh +++ /dev/null @@ -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" diff --git a/cmake/BuildPackages.cmake b/cmake/BuildPackages.cmake index 5033e49..33eb50b 100644 --- a/cmake/BuildPackages.cmake +++ b/cmake/BuildPackages.cmake @@ -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) diff --git a/cmake/StaticBuild.cmake b/cmake/StaticBuild.cmake index 4b58b1d..9c3203f 100644 --- a/cmake/StaticBuild.cmake +++ b/cmake/StaticBuild.cmake @@ -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() diff --git a/common/network/TcpSocket.cxx b/common/network/TcpSocket.cxx index ce0267c..f5476e8 100644 --- a/common/network/TcpSocket.cxx +++ b/common/network/TcpSocket.cxx @@ -38,11 +38,13 @@ #include #include #include +#include #include "websocket.h" #include #include #include +#include #ifdef WIN32 #include @@ -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 *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 *listeners, freeaddrinfo(ai); throw; } + + freeaddrinfo(ai); } void network::createTcpListeners(std::list *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); diff --git a/common/network/UnixSocket.cxx b/common/network/UnixSocket.cxx index bfabc14..f8b8618 100644 --- a/common/network/UnixSocket.cxx +++ b/common/network/UnixSocket.cxx @@ -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); } diff --git a/common/network/websocket.c b/common/network/websocket.c index 3ff90d3..3bc3b7f 100644 --- a/common/network/websocket.c +++ b/common/network/websocket.c @@ -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); diff --git a/common/network/websocket.h b/common/network/websocket.h index ca9c578..18a9b0d 100644 --- a/common/network/websocket.h +++ b/common/network/websocket.h @@ -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; diff --git a/common/rdr/Exception.cxx b/common/rdr/Exception.cxx index 964bc33..382fea3 100644 --- a/common/rdr/Exception.cxx +++ b/common/rdr/Exception.cxx @@ -31,6 +31,9 @@ #include #include #include +#include +#else +#include #endif #include @@ -49,38 +52,46 @@ Exception::Exception(const char *format, ...) { va_end(ap); } -SystemException::SystemException(const char* s, int err_) - : Exception("%s", s), err(err_) +GAIException::GAIException(const char* s, int err) + : Exception("%s", s) { 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; + 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 - char* currStr = str_+strlen(str_); - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - 0, err, 0, currStr, len-1-strlen(str_), 0); + strncat(str_, gai_strerror(err), len-1-strlen(str_)); #endif - int l = strlen(str_); - if ((l >= 2) && (str_[l-2] == '\r') && (str_[l-1] == '\n')) + 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 + 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_)); diff --git a/common/rdr/Exception.h b/common/rdr/Exception.h index 69abbed..eb3c8a9 100644 --- a/common/rdr/Exception.h +++ b/common/rdr/Exception.h @@ -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") {} }; diff --git a/common/rdr/FdInStream.cxx b/common/rdr/FdInStream.cxx index 1b9a322..1730d6d 100644 --- a/common/rdr/FdInStream.cxx +++ b/common/rdr/FdInStream.cxx @@ -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) diff --git a/common/rdr/FdInStream.h b/common/rdr/FdInStream.h index b4c8765..d99ad3c 100644 --- a/common/rdr/FdInStream.h +++ b/common/rdr/FdInStream.h @@ -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; }; diff --git a/common/rdr/FdOutStream.cxx b/common/rdr/FdOutStream.cxx index cf857f8..f5d07e4 100644 --- a/common/rdr/FdOutStream.cxx +++ b/common/rdr/FdOutStream.cxx @@ -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; diff --git a/common/rdr/FdOutStream.h b/common/rdr/FdOutStream.h index b7f6cb0..ed84fdb 100644 --- a/common/rdr/FdOutStream.h +++ b/common/rdr/FdOutStream.h @@ -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; diff --git a/common/rdr/FileInStream.cxx b/common/rdr/FileInStream.cxx index 3acdfd4..bdb05a3 100644 --- a/common/rdr/FileInStream.cxx +++ b/common/rdr/FileInStream.cxx @@ -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; } diff --git a/common/rdr/FileInStream.h b/common/rdr/FileInStream.h index ace04f3..a33c765 100644 --- a/common/rdr/FileInStream.h +++ b/common/rdr/FileInStream.h @@ -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]; diff --git a/common/rdr/FixedMemOutStream.h b/common/rdr/FixedMemOutStream.h deleted file mode 100644 index e4ec52c..0000000 --- a/common/rdr/FixedMemOutStream.h +++ /dev/null @@ -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 -#include - -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 diff --git a/common/rdr/HexInStream.cxx b/common/rdr/HexInStream.cxx index 80f8a79..a6bc92c 100644 --- a/common/rdr/HexInStream.cxx +++ b/common/rdr/HexInStream.cxx @@ -28,7 +28,7 @@ const int DEFAULT_BUF_LEN = 16384; static inline int min(int a, int b) {return a 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 end - ptr) - nItems = (end - ptr) / itemSize; + size_t nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } diff --git a/common/rdr/HexInStream.h b/common/rdr/HexInStream.h index 6bfb843..8e495fb 100644 --- a/common/rdr/HexInStream.h +++ b/common/rdr/HexInStream.h @@ -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; }; diff --git a/common/rdr/HexOutStream.cxx b/common/rdr/HexOutStream.cxx index 9b0b6c4..eac2eff 100644 --- a/common/rdr/HexOutStream.cxx +++ b/common/rdr/HexOutStream.cxx @@ -23,9 +23,9 @@ using namespace rdr; const int DEFAULT_BUF_LEN = 16384; -static inline int min(int a, int b) {return a> 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> 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; } diff --git a/common/rdr/HexOutStream.h b/common/rdr/HexOutStream.h index 10247e6..92442a7 100644 --- a/common/rdr/HexOutStream.h +++ b/common/rdr/HexOutStream.h @@ -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; }; } diff --git a/common/rdr/InStream.h b/common/rdr/InStream.h index 212a2ec..a8e515d 100644 --- a/common/rdr/InStream.h +++ b/common/rdr/InStream.h @@ -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: diff --git a/common/rdr/MemInStream.h b/common/rdr/MemInStream.h index 1a6a798..3e9e77b 100644 --- a/common/rdr/MemInStream.h +++ b/common/rdr/MemInStream.h @@ -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; }; diff --git a/common/rdr/MemOutStream.h b/common/rdr/MemOutStream.h index 3b17e55..b56bac3 100644 --- a/common/rdr/MemOutStream.h +++ b/common/rdr/MemOutStream.h @@ -23,6 +23,7 @@ #ifndef __RDR_MEMOUTSTREAM_H__ #define __RDR_MEMOUTSTREAM_H__ +#include #include 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); diff --git a/common/rdr/OutStream.h b/common/rdr/OutStream.h index a749a20..0f60ccc 100644 --- a/common/rdr/OutStream.h +++ b/common/rdr/OutStream.h @@ -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: diff --git a/common/rdr/RandomStream.cxx b/common/rdr/RandomStream.cxx index 3fde18d..6c64ac5 100644 --- a/common/rdr/RandomStream.cxx +++ b/common/rdr/RandomStream.cxx @@ -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 end - ptr) - nItems = (end - ptr) / itemSize; + size_t nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } diff --git a/common/rdr/RandomStream.h b/common/rdr/RandomStream.h index c33360d..80b389b 100644 --- a/common/rdr/RandomStream.h +++ b/common/rdr/RandomStream.h @@ -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 diff --git a/common/rdr/SubstitutingInStream.h b/common/rdr/SubstitutingInStream.h deleted file mode 100644 index 325b01c..0000000 --- a/common/rdr/SubstitutingInStream.h +++ /dev/null @@ -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 -#include - -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 diff --git a/common/rdr/TLSInStream.cxx b/common/rdr/TLSInStream.cxx index 77b1672..cd81f22 100644 --- a/common/rdr/TLSInStream.cxx +++ b/common/rdr/TLSInStream.cxx @@ -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) diff --git a/common/rdr/TLSInStream.h b/common/rdr/TLSInStream.h index b16d9f5..5f9dee7 100644 --- a/common/rdr/TLSInStream.h +++ b/common/rdr/TLSInStream.h @@ -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; }; }; diff --git a/common/rdr/TLSOutStream.cxx b/common/rdr/TLSOutStream.cxx index 44d2d9f..7d7c3b5 100644 --- a/common/rdr/TLSOutStream.cxx +++ b/common/rdr/TLSOutStream.cxx @@ -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; diff --git a/common/rdr/TLSOutStream.h b/common/rdr/TLSOutStream.h index 81dd237..71a7f3b 100644 --- a/common/rdr/TLSOutStream.h +++ b/common/rdr/TLSOutStream.h @@ -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; }; }; diff --git a/common/rdr/ZlibInStream.cxx b/common/rdr/ZlibInStream.cxx index 4053bd1..0fb3ad1 100644 --- a/common/rdr/ZlibInStream.cxx +++ b/common/rdr/ZlibInStream.cxx @@ -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"); } diff --git a/common/rdr/ZlibInStream.h b/common/rdr/ZlibInStream.h index 6bd4da4..08784b0 100644 --- a/common/rdr/ZlibInStream.h +++ b/common/rdr/ZlibInStream.h @@ -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; }; diff --git a/common/rdr/ZlibOutStream.cxx b/common/rdr/ZlibOutStream.cxx index 9d9f8ba..1cccb2b 100644 --- a/common/rdr/ZlibOutStream.cxx +++ b/common/rdr/ZlibOutStream.cxx @@ -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... diff --git a/common/rdr/ZlibOutStream.h b/common/rdr/ZlibOutStream.h index 2d82a13..11bb046 100644 --- a/common/rdr/ZlibOutStream.h +++ b/common/rdr/ZlibOutStream.h @@ -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; }; diff --git a/common/rfb/CMakeLists.txt b/common/rfb/CMakeLists.txt index d426859..67adcf9 100644 --- a/common/rfb/CMakeLists.txt +++ b/common/rfb/CMakeLists.txt @@ -22,7 +22,6 @@ set(RFB_SOURCES EncCache.cxx EncodeManager.cxx Encoder.cxx - HTTPServer.cxx HextileDecoder.cxx HextileEncoder.cxx JpegCompressor.cxx diff --git a/common/rfb/Configuration.cxx b/common/rfb/Configuration.cxx index 16b7b60..ff03a6f 100644 --- a/common/rfb/Configuration.cxx +++ b/common/rfb/Configuration.cxx @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -432,7 +433,8 @@ bool StringParameter::setParam(const char* v) { if (immutable) return true; if (!v) throw rfb::Exception("setParam() 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_) { diff --git a/common/rfb/Configuration.h b/common/rfb/Configuration.h index 96dc4ef..e5c8d62 100644 --- a/common/rfb/Configuration.h +++ b/common/rfb/Configuration.h @@ -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 diff --git a/common/rfb/EncodeManager.cxx b/common/rfb/EncodeManager.cxx index fba3b33..a32e08c 100644 --- a/common/rfb/EncodeManager.cxx +++ b/common/rfb/EncodeManager.cxx @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -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 diff --git a/common/rfb/EncodeManager.h b/common/rfb/EncodeManager.h index 97dff6e..9ed5b65 100644 --- a/common/rfb/EncodeManager.h +++ b/common/rfb/EncodeManager.h @@ -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); }; }; } diff --git a/common/rfb/HTTPServer.cxx b/common/rfb/HTTPServer.cxx deleted file mode 100644 index 8119ec4..0000000 --- a/common/rfb/HTTPServer.cxx +++ /dev/null @@ -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 -#include -#include -#include - - -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, ""); - writeLine(os, ""); - sprintf(buffer, "%d %s", result, text); - writeLine(os, buffer); - writeLine(os, "

"); - writeLine(os, text); - writeLine(os, "

"); - 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::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::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::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::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* sockets) -{ - sockets->clear(); - std::list::iterator ci; - for (ci = sessions.begin(); ci != sessions.end(); ci++) { - sockets->push_back((*ci)->getSock()); - } -} - -int HTTPServer::checkTimeouts() { - std::list::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; -} diff --git a/common/rfb/HTTPServer.h b/common/rfb/HTTPServer.h deleted file mode 100644 index 04ef499..0000000 --- a/common/rfb/HTTPServer.h +++ /dev/null @@ -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 -#include -#include -#include -#include - -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* 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 sessions; - }; -} - -#endif - diff --git a/common/rfb/JpegCompressor.h b/common/rfb/JpegCompressor.h index 8fbb7a9..9c6332b 100644 --- a/common/rfb/JpegCompressor.h +++ b/common/rfb/JpegCompressor.h @@ -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); } diff --git a/common/rfb/Password.cxx b/common/rfb/Password.cxx index 240c9d4..e4a508c 100644 --- a/common/rfb/Password.cxx +++ b/common/rfb/Password.cxx @@ -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 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) diff --git a/common/rfb/SMsgHandler.h b/common/rfb/SMsgHandler.h index 749f056..6d5f5a1 100644 --- a/common/rfb/SMsgHandler.h +++ b/common/rfb/SMsgHandler.h @@ -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. diff --git a/common/rfb/SMsgReader.cxx b/common/rfb/SMsgReader.cxx index fab28c5..7550331 100644 --- a/common/rfb/SMsgReader.cxx +++ b/common/rfb/SMsgReader.cxx @@ -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(); diff --git a/common/rfb/SMsgReader.h b/common/rfb/SMsgReader.h index b7acf79..ebeee84 100644 --- a/common/rfb/SMsgReader.h +++ b/common/rfb/SMsgReader.h @@ -55,6 +55,7 @@ namespace rfb { void readKeyEvent(); void readPointerEvent(); void readClientCutText(); + void readRequestStats(); void readQEMUMessage(); void readQEMUKeyEvent(); diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx index 3da9413..07622fd 100644 --- a/common/rfb/SMsgWriter.cxx +++ b/common/rfb/SMsgWriter.cxx @@ -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) diff --git a/common/rfb/SMsgWriter.h b/common/rfb/SMsgWriter.h index e985941..6945ba4 100644 --- a/common/rfb/SMsgWriter.h +++ b/common/rfb/SMsgWriter.h @@ -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[]); diff --git a/common/rfb/ServerCore.cxx b/common/rfb/ServerCore.cxx index d165601..900a21f 100644 --- a/common/rfb/ServerCore.cxx +++ b/common/rfb/ServerCore.cxx @@ -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); diff --git a/common/rfb/ServerCore.h b/common/rfb/ServerCore.h index 37d2a07..bd97265 100644 --- a/common/rfb/ServerCore.h +++ b/common/rfb/ServerCore.h @@ -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; diff --git a/common/rfb/TightDecoder.cxx b/common/rfb/TightDecoder.cxx index cc786f5..e2a99da 100644 --- a/common/rfb/TightDecoder.cxx +++ b/common/rfb/TightDecoder.cxx @@ -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; diff --git a/common/rfb/Timer.h b/common/rfb/Timer.h index 15b5d03..ef50972 100644 --- a/common/rfb/Timer.h +++ b/common/rfb/Timer.h @@ -21,11 +21,7 @@ #define __RFB_TIMER_H__ #include -#ifdef WIN32 -#include -#else #include -#endif namespace rfb { diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index f0e5b21..18779a5 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -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 &list, const struct timeval &now) { + std::list::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 diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h index 76e00bb..76350ef 100644 --- a/common/rfb/VNCSConnectionST.h +++ b/common/rfb/VNCSConnectionST.h @@ -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 pressedKeys; + enum { + BS_CPU_CLOSE, + BS_CPU_SLOW, + BS_NET_SLOW, + BS_FRAME, + + BS_NUM + }; + std::list bstats[BS_NUM]; // Bottleneck stats + rdr::U64 bstats_total[BS_NUM]; + struct timeval connStart; + time_t lastEventTime; time_t pointerEventTime; Point pointerEventPos; diff --git a/common/rfb/msgTypes.h b/common/rfb/msgTypes.h index 2240ce0..4bb4ddf 100644 --- a/common/rfb/msgTypes.h +++ b/common/rfb/msgTypes.h @@ -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; diff --git a/common/rfb/tightDecode.h b/common/rfb/tightDecode.h index b6e86ed..8f77aeb 100644 --- a/common/rfb/tightDecode.h +++ b/common/rfb/tightDecode.h @@ -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) { diff --git a/common/rfb/util.h b/common/rfb/util.h index b678b89..8f90ec4 100644 --- a/common/rfb/util.h +++ b/common/rfb/util.h @@ -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; diff --git a/common/rfb/zrleDecode.h b/common/rfb/zrleDecode.h index 32b5c92..f432538 100644 --- a/common/rfb/zrleDecode.h +++ b/common/rfb/zrleDecode.h @@ -174,7 +174,8 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is, } } - zis->removeUnderlying(); + zis->flushUnderlying(); + zis->setUnderlying(NULL, 0); } #undef ZRLE_DECODE diff --git a/config.h.in b/config.h.in index 2d6db9c..62622db 100644 --- a/config.h.in +++ b/config.h.in @@ -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 diff --git a/contrib/xorg/build-xorg b/contrib/xorg/build-xorg deleted file mode 100755 index d01cf03..0000000 --- a/contrib/xorg/build-xorg +++ /dev/null @@ -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 diff --git a/contrib/xorg/download-xorg-7.5 b/contrib/xorg/download-xorg-7.5 deleted file mode 100755 index 65967d2..0000000 --- a/contrib/xorg/download-xorg-7.5 +++ /dev/null @@ -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() diff --git a/contrib/xorg/xorg-7.5-patches/0001-Add-dridir-param.patch b/contrib/xorg/xorg-7.5-patches/0001-Add-dridir-param.patch deleted file mode 100644 index c72078f..0000000 --- a/contrib/xorg/xorg-7.5-patches/0001-Add-dridir-param.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 0acffdd6f443198378012405e7f814f5abf278b3 Mon Sep 17 00:00:00 2001 -From: Adam Tkac -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 ---- - 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 - diff --git a/contrib/xorg/xorg-7.5-patches/0001-Add-xkbcompdir-param.patch b/contrib/xorg/xorg-7.5-patches/0001-Add-xkbcompdir-param.patch deleted file mode 100644 index f7f358b..0000000 --- a/contrib/xorg/xorg-7.5-patches/0001-Add-xkbcompdir-param.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 5e6e99eaef3ca346c78a3e520ed58ec8b8100b41 Mon Sep 17 00:00:00 2001 -From: Adam Tkac -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 ---- - 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 - diff --git a/kasmweb/app/styles/base.css b/kasmweb/app/styles/base.css index ac51385..78e8fd4 100644 --- a/kasmweb/app/styles/base.css +++ b/kasmweb/app/styles/base.css @@ -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 * ---------------------------------------- diff --git a/kasmweb/app/ui.js b/kasmweb/app/ui.js index bedee34..3f42a24 100644 --- a/kasmweb/app/ui.js +++ b/kasmweb/app/ui.js @@ -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; \ No newline at end of file +export default UI; diff --git a/kasmweb/core/rfb.js b/kasmweb/core/rfb.js index 48764c3..74c13ae 100644 --- a/kasmweb/core/rfb.js +++ b/kasmweb/core/rfb.js @@ -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; diff --git a/kasmweb/vnc.html b/kasmweb/vnc.html index 3d4892c..676c447 100644 --- a/kasmweb/vnc.html +++ b/kasmweb/vnc.html @@ -90,6 +90,10 @@ +
+ Loading statistics... +
+
@@ -214,6 +218,8 @@
  • +
  • +
  • diff --git a/unix/CMakeLists.txt b/unix/CMakeLists.txt index 9c5f0f9..4c1009c 100644 --- a/unix/CMakeLists.txt +++ b/unix/CMakeLists.txt @@ -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) diff --git a/unix/kasmvncpasswd/.gitignore b/unix/kasmvncpasswd/.gitignore new file mode 100644 index 0000000..93285aa --- /dev/null +++ b/unix/kasmvncpasswd/.gitignore @@ -0,0 +1 @@ +kasmvncpasswd diff --git a/unix/kasmvncpasswd/CMakeLists.txt b/unix/kasmvncpasswd/CMakeLists.txt new file mode 100644 index 0000000..2edb0d7 --- /dev/null +++ b/unix/kasmvncpasswd/CMakeLists.txt @@ -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}) diff --git a/unix/kasmvncpasswd/kasmvncpasswd.c b/unix/kasmvncpasswd/kasmvncpasswd.c new file mode 100644 index 0000000..6c41da4 --- /dev/null +++ b/unix/kasmvncpasswd/kasmvncpasswd.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include + +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; + } +} diff --git a/unix/vncserver b/unix/vncserver old mode 100755 new mode 100644 index 9f3d97f..c56ea7e --- a/unix/vncserver +++ b/unix/vncserver @@ -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; - } -} - -if ((!$securityTypeArgSpecified || $vncAuthEnabled) && !$passwordArgSpecified) { - ($z,$z,$mode) = stat("$vncUserDir/passwd"); - if (!(-e "$vncUserDir/passwd") || ($mode & 077)) { +#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; +# } +#} + +# 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; } } diff --git a/unix/xserver/hw/vnc/Input.c b/unix/xserver/hw/vnc/Input.c index 8e47d74..2519ad3 100644 --- a/unix/xserver/hw/vnc/Input.c +++ b/unix/xserver/hw/vnc/Input.c @@ -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 diff --git a/unix/xserver/hw/vnc/Makefile.am b/unix/xserver/hw/vnc/Makefile.am index 3e4165f..3692555 100644 --- a/unix/xserver/hw/vnc/Makefile.am +++ b/unix/xserver/hw/vnc/Makefile.am @@ -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 diff --git a/unix/xserver/hw/vnc/RFBGlue.cc b/unix/xserver/hw/vnc/RFBGlue.cc index 160177b..6086025 100644 --- a/unix/xserver/hw/vnc/RFBGlue.cc +++ b/unix/xserver/hw/vnc/RFBGlue.cc @@ -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(param); + if (bparam == NULL) + return false; + + return true; +} + int vncGetParamCount(void) { int count; diff --git a/unix/xserver/hw/vnc/RFBGlue.h b/unix/xserver/hw/vnc/RFBGlue.h index a63afd0..d62236a 100644 --- a/unix/xserver/hw/vnc/RFBGlue.h +++ b/unix/xserver/hw/vnc/RFBGlue.h @@ -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); diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index 4aac765..de8bb78 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -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 listeners_, - std::list 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::iterator i = listeners.begin(); i != listeners.end(); i++) { vncSetNotifyFd((*i)->getFd(), screenIndex, true, false); } - - for (std::list::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; diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h index f866a4c..014fcb5 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.h +++ b/unix/xserver/hw/vnc/XserverDesktop.h @@ -32,11 +32,9 @@ #include #include -#include #include #include #include -#include #include #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 listeners_, - std::list 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 listeners; - std::list httpListeners; bool directFbptr; uint32_t queryConnectId; diff --git a/unix/xserver/hw/vnc/Xvnc.man b/unix/xserver/hw/vnc/Xvnc.man index a3b20e0..f2af360 100644 --- a/unix/xserver/hw/vnc/Xvnc.man +++ b/unix/xserver/hw/vnc/Xvnc.man @@ -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 diff --git a/unix/xserver/hw/vnc/vncExtInit.cc b/unix/xserver/hw/vnc/vncExtInit.cc index 0741d49..7e1accd 100644 --- a/unix/xserver/hw/vnc/vncExtInit.cc +++ b/unix/xserver/hw/vnc/vncExtInit.cc @@ -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 listeners; - std::list 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()); } } diff --git a/unix/xserver/hw/vnc/vncHooks.c b/unix/xserver/hw/vnc/vncHooks.c index f3c2520..e2be124 100644 --- a/unix/xserver/hw/vnc/vncHooks.c +++ b/unix/xserver/hw/vnc/vncHooks.c @@ -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); } diff --git a/unix/xserver/hw/vnc/xvnc.c b/unix/xserver/hw/vnc/xvnc.c index 96437aa..2971290 100644 --- a/unix/xserver/hw/vnc/xvnc.c +++ b/unix/xserver/hw/vnc/xvnc.c @@ -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); } } diff --git a/unix/xserver110.patch b/unix/xserver110.patch deleted file mode 100644 index 14ff206..0000000 --- a/unix/xserver110.patch +++ /dev/null @@ -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(); diff --git a/unix/xserver111.patch b/unix/xserver111.patch deleted file mode 100644 index 02d22e5..0000000 --- a/unix/xserver111.patch +++ /dev/null @@ -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(); diff --git a/unix/xserver112.patch b/unix/xserver112.patch deleted file mode 100644 index 8670d3c..0000000 --- a/unix/xserver112.patch +++ /dev/null @@ -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) diff --git a/unix/xserver113.patch b/unix/xserver113.patch deleted file mode 100644 index 733fa1b..0000000 --- a/unix/xserver113.patch +++ /dev/null @@ -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 diff --git a/unix/xserver114.patch b/unix/xserver114.patch deleted file mode 100644 index e0d6995..0000000 --- a/unix/xserver114.patch +++ /dev/null @@ -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; diff --git a/unix/xserver115.patch b/unix/xserver115.patch deleted file mode 100644 index 1771092..0000000 --- a/unix/xserver115.patch +++ /dev/null @@ -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; diff --git a/unix/xserver17.patch b/unix/xserver17.patch deleted file mode 100644 index 81349a1..0000000 --- a/unix/xserver17.patch +++ /dev/null @@ -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(); diff --git a/unix/xserver18.patch b/unix/xserver18.patch deleted file mode 100644 index 290f7b7..0000000 --- a/unix/xserver18.patch +++ /dev/null @@ -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(); diff --git a/unix/xserver19.patch b/unix/xserver19.patch deleted file mode 100644 index 6616f49..0000000 --- a/unix/xserver19.patch +++ /dev/null @@ -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(); diff --git a/win/rfb_win32/DIBSectionBuffer.cxx b/win/rfb_win32/DIBSectionBuffer.cxx index e2b0d64..ebb9b9b 100644 --- a/win/rfb_win32/DIBSectionBuffer.cxx +++ b/win/rfb_win32/DIBSectionBuffer.cxx @@ -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() { diff --git a/win/rfb_win32/MonitorInfo.cxx b/win/rfb_win32/MonitorInfo.cxx index 551017b..0a949ab 100644 --- a/win/rfb_win32/MonitorInfo.cxx +++ b/win/rfb_win32/MonitorInfo.cxx @@ -36,7 +36,7 @@ using namespace win32; static LogWriter vlog("MonitorInfo"); -static void fillMonitorInfo(HMONITOR monitor, MonitorInfo* mi) { +static void fillMonitorInfo(HMONITOR monitor, MONITORINFOEXA* mi) { vlog.debug("monitor=%p", monitor); memset(mi, 0, sizeof(MONITORINFOEXA)); mi->cbSize = sizeof(MONITORINFOEXA); @@ -70,7 +70,7 @@ MonitorInfo::MonitorInfo(const RECT& r) { struct monitorByNameData { - MonitorInfo* info; + MONITORINFOEXA* info; const char* monitorName; }; diff --git a/win/rfb_win32/Registry.cxx b/win/rfb_win32/Registry.cxx index 963a36a..87086ad 100644 --- a/win/rfb_win32/Registry.cxx +++ b/win/rfb_win32/Registry.cxx @@ -146,7 +146,7 @@ void RegKey::setString(const TCHAR* valname, const TCHAR* value) const { if (result != ERROR_SUCCESS) throw rdr::SystemException("setString", result); } -void RegKey::setBinary(const TCHAR* valname, const void* value, int length) const { +void RegKey::setBinary(const TCHAR* valname, const void* value, size_t length) const { LONG result = RegSetValueEx(key, valname, 0, REG_BINARY, (const BYTE*)value, length); if (result != ERROR_SUCCESS) throw rdr::SystemException("setBinary", result); } @@ -169,12 +169,12 @@ TCHAR* RegKey::getString(const TCHAR* valname, const TCHAR* def) const { } } -void RegKey::getBinary(const TCHAR* valname, void** data, int* length) const { +void RegKey::getBinary(const TCHAR* valname, void** data, size_t* length) const { TCharArray hex(getRepresentation(valname)); if (!rdr::HexInStream::hexStrToBin(CStr(hex.buf), (char**)data, length)) throw rdr::Exception("getBinary failed"); } -void RegKey::getBinary(const TCHAR* valname, void** data, int* length, void* def, int deflen) const { +void RegKey::getBinary(const TCHAR* valname, void** data, size_t* length, void* def, size_t deflen) const { try { getBinary(valname, data, length); } catch(rdr::Exception&) { diff --git a/win/rfb_win32/Registry.h b/win/rfb_win32/Registry.h index 68d535c..2bb1691 100644 --- a/win/rfb_win32/Registry.h +++ b/win/rfb_win32/Registry.h @@ -71,15 +71,15 @@ namespace rfb { void setExpandString(const TCHAR* valname, const TCHAR* s) const; void setString(const TCHAR* valname, const TCHAR* s) const; - void setBinary(const TCHAR* valname, const void* data, int length) const; + void setBinary(const TCHAR* valname, const void* data, size_t length) const; void setInt(const TCHAR* valname, int i) const; void setBool(const TCHAR* valname, bool b) const; TCHAR* getString(const TCHAR* valname) const; TCHAR* getString(const TCHAR* valname, const TCHAR* def) const; - void getBinary(const TCHAR* valname, void** data, int* length) const; - void getBinary(const TCHAR* valname, void** data, int* length, void* def, int deflength) const; + void getBinary(const TCHAR* valname, void** data, size_t* length) const; + void getBinary(const TCHAR* valname, void** data, size_t* length, void* def, size_t deflength) const; int getInt(const TCHAR* valname) const; int getInt(const TCHAR* valname, int def) const; diff --git a/win/rfb_win32/SDisplay.cxx b/win/rfb_win32/SDisplay.cxx index ad55d49..9b2cbb0 100644 --- a/win/rfb_win32/SDisplay.cxx +++ b/win/rfb_win32/SDisplay.cxx @@ -314,21 +314,6 @@ void SDisplay::clientCutText(const char* text, int len) { } -Point SDisplay::getFbSize() { - bool startAndStop = !core; - - // If not started, do minimal initialisation to get desktop size. - if (startAndStop) - recreatePixelBuffer(); - Point result = Point(pb->width(), pb->height()); - - // Destroy the initialised structures. - if (startAndStop) - stopCore(); - return result; -} - - void SDisplay::notifyClipboardChanged(const char* text, int len) { vlog.debug("clipboard text changed"); diff --git a/win/rfb_win32/SDisplay.h b/win/rfb_win32/SDisplay.h index f36b2b7..c1d5c1e 100644 --- a/win/rfb_win32/SDisplay.h +++ b/win/rfb_win32/SDisplay.h @@ -86,12 +86,6 @@ namespace rfb { void setStatusLocation(bool* status) {statusLocation = status;} - // -=- Used (indirectly) by JavaViewer to get desktop size - - Point getFbSize(); - - friend class SDisplayCore; - static IntParameter updateMethod; static BoolParameter disableLocalInputs; static StringParameter disconnectAction;