aboutsummaryrefslogtreecommitdiff
path: root/net/tigervnc
diff options
context:
space:
mode:
authorSteve Wills <swills@FreeBSD.org>2013-05-29 16:29:40 +0000
committerSteve Wills <swills@FreeBSD.org>2013-05-29 16:29:40 +0000
commit863d70a0517d160bd8607a5175c50f537b89def0 (patch)
treee6bdde55254231c23845543ff1e8bb74159943f5 /net/tigervnc
parent7324889637956b06137824641e60773425fb1e53 (diff)
downloadports-863d70a0517d160bd8607a5175c50f537b89def0.tar.gz
ports-863d70a0517d160bd8607a5175c50f537b89def0.zip
Notes
Diffstat (limited to 'net/tigervnc')
-rw-r--r--net/tigervnc/Makefile16
-rw-r--r--net/tigervnc/files/extra-patch-common_rdr.patch214
-rw-r--r--net/tigervnc/files/extra-patch-common_rfb.patch259
-rw-r--r--net/tigervnc/files/extra-patch-unix_hw_vnc.patch1806
-rw-r--r--net/tigervnc/files/xserver112.patch91
5 files changed, 2378 insertions, 8 deletions
diff --git a/net/tigervnc/Makefile b/net/tigervnc/Makefile
index 8860dcd2f1aa..a52e96f27c21 100644
--- a/net/tigervnc/Makefile
+++ b/net/tigervnc/Makefile
@@ -3,7 +3,7 @@
PORTNAME= tigervnc
PORTVERSION= 1.2.0
-PORTREVISION= 2
+PORTREVISION= 3
CATEGORIES= net x11-servers
MASTER_SITES= SF:tigervnc
MASTER_SITE_SUBDIR= ${PORTNAME}/${PORTNAME}/${PORTVERSION}/:tigervnc
@@ -12,12 +12,8 @@ DISTFILES= ${PORTNAME}-${PORTVERSION}.tar.gz:tigervnc
MAINTAINER= meta+ports@vmeta.jp
COMMENT= TigerVNC is an advanced VNC implementation
-LISENCE= GPLv2
-LISENCE_FILE= ${WRKSRC}/LICENCE.TXT
-
-.if defined(WITH_NEW_XORG)
-BROKEN= Does not build
-.endif
+LICENSE= GPLv2
+LICENSE_FILE= ${WRKSRC}/LICENCE.TXT
PATCH_DEPENDS= ${NONEXISTENT}:${PORTSDIR}/x11-servers/xorg-server:patch
BUILD_DEPENDS= ${LOCALBASE}/include/GL/internal/dri_interface.h:${PORTSDIR}/graphics/dri
@@ -127,7 +123,10 @@ CONFIGURE_ARGS+= \
.include <bsd.port.pre.mk>
.ifdef WITH_NEW_XORG
-TIGERVNC_XORG_PATCH_VER= 110
+TIGERVNC_XORG_PATCH_VER= 112
+EXTRA_PATCHES+= ${FILESDIR}/extra-patch-unix_hw_vnc.patch \
+ ${FILESDIR}/extra-patch-common_rdr.patch \
+ ${FILESDIR}/extra-patch-common_rfb.patch
.else
TIGERVNC_XORG_PATCH_VER= 17
.endif
@@ -146,6 +145,7 @@ pre-patch:
@${CP} -R `${XORG_WRKDIR}`/ ${WRKSRC}/unix/xserver/
post-patch:
+ @${CP} ${FILESDIR}/xserver*.patch ${WRKSRC}/unix/
@cd ${WRKSRC}/unix/xserver/ && ${PATCH} -p1 < ${WRKSRC}/unix/xserver${TIGERVNC_XORG_PATCH_VER}.patch
post-configure:
diff --git a/net/tigervnc/files/extra-patch-common_rdr.patch b/net/tigervnc/files/extra-patch-common_rdr.patch
new file mode 100644
index 000000000000..8c5226e076ad
--- /dev/null
+++ b/net/tigervnc/files/extra-patch-common_rdr.patch
@@ -0,0 +1,214 @@
+
+--- common/rdr/TLSErrno.h 1970-01-01 09:00:00.000000000 +0900
++++ common/rdr/TLSErrno.h 2013-05-27 19:09:50.115573000 +0900
+@@ -0,0 +1,46 @@
++/* Copyright (C) 2012 Pierre Ossman for Cendio AB
++ *
++ * 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_TLSERRNO_H__
++#define __RDR_TLSERRNO_H__
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#ifdef HAVE_GNUTLS
++
++#include <errno.h>
++
++namespace rdr {
++
++ static inline void gnutls_errno_helper(gnutls_session session, int _errno)
++ {
++#if defined(HAVE_GNUTLS_SET_ERRNO)
++ gnutls_transport_set_errno(session, _errno);
++#elif defined(HAVE_GNUTLS_SET_GLOBAL_ERRNO)
++ gnutls_transport_set_global_errno(_errno);
++#else
++ errno = _errno;
++#endif
++ }
++};
++
++#endif
++
++#endif
+
+--- common/rdr/TLSInStream.cxx 2010-09-30 15:25:28.000000000 +0900
++++ common/rdr/TLSInStream.cxx 2013-05-27 19:09:50.124573000 +0900
+@@ -25,25 +25,22 @@
+ #include <rdr/Exception.h>
+ #include <rdr/TLSException.h>
+ #include <rdr/TLSInStream.h>
++#include <rdr/TLSErrno.h>
+ #include <errno.h>
+
+-#ifdef HAVE_OLD_GNUTLS
+-#define gnutls_transport_set_global_errno(A) do { errno = (A); } while(0)
+-#endif
+-
+ #ifdef HAVE_GNUTLS
+ using namespace rdr;
+
+ enum { DEFAULT_BUF_SIZE = 16384 };
+
+-ssize_t rdr::gnutls_InStream_pull(gnutls_transport_ptr str, void* data,
+- size_t size)
++ssize_t TLSInStream::pull(gnutls_transport_ptr str, void* data, size_t size)
+ {
+- InStream* in= (InStream*) str;
++ TLSInStream* self= (TLSInStream*) str;
++ InStream *in = self->in;
+
+ try {
+ if (!in->check(1, 1, false)) {
+- gnutls_transport_set_global_errno(EAGAIN);
++ gnutls_errno_helper(self->session, EAGAIN);
+ return -1;
+ }
+
+@@ -53,7 +50,7 @@
+ in->readBytes(data, size);
+
+ } catch (Exception& e) {
+- gnutls_transport_set_global_errno(EINVAL);
++ gnutls_errno_helper(self->session, EINVAL);
+ return -1;
+ }
+
+@@ -63,11 +60,19 @@
+ TLSInStream::TLSInStream(InStream* _in, gnutls_session _session)
+ : session(_session), in(_in), bufSize(DEFAULT_BUF_SIZE), offset(0)
+ {
++ gnutls_transport_ptr recv, send;
++
+ ptr = end = start = new U8[bufSize];
++
++ gnutls_transport_set_pull_function(session, pull);
++ gnutls_transport_get_ptr2(session, &recv, &send);
++ gnutls_transport_set_ptr2(session, this, send);
+ }
+
+ TLSInStream::~TLSInStream()
+ {
++ gnutls_transport_set_pull_function(session, NULL);
++
+ delete[] start;
+ }
+
+
+--- common/rdr/TLSInStream.h 2010-04-23 23:12:18.000000000 +0900
++++ common/rdr/TLSInStream.h 2013-05-27 19:09:50.086573000 +0900
+@@ -41,6 +41,7 @@
+ private:
+ int overrun(int itemSize, int nItems, bool wait);
+ int readTLS(U8* buf, int len, bool wait);
++ static ssize_t pull(gnutls_transport_ptr str, void* data, size_t size);
+
+ gnutls_session session;
+ InStream* in;
+@@ -48,9 +49,6 @@
+ int offset;
+ U8* start;
+ };
+-
+- ssize_t gnutls_InStream_pull(gnutls_transport_ptr,void*, size_t);
+-
+ };
+
+ #endif
+
+--- common/rdr/TLSOutStream.cxx 2010-09-30 15:25:28.000000000 +0900
++++ common/rdr/TLSOutStream.cxx 2013-05-27 19:09:50.094576000 +0900
+@@ -25,27 +25,25 @@
+ #include <rdr/Exception.h>
+ #include <rdr/TLSException.h>
+ #include <rdr/TLSOutStream.h>
++#include <rdr/TLSErrno.h>
+ #include <errno.h>
+
+-#ifdef HAVE_OLD_GNUTLS
+-#define gnutls_transport_set_global_errno(A) do { errno = (A); } while(0)
+-#endif
+-
+ #ifdef HAVE_GNUTLS
+ using namespace rdr;
+
+ enum { DEFAULT_BUF_SIZE = 16384 };
+
+-ssize_t rdr::gnutls_OutStream_push(gnutls_transport_ptr str, const void* data,
++ssize_t TLSOutStream::push(gnutls_transport_ptr str, const void* data,
+ size_t size)
+ {
+- OutStream* out = (OutStream*) str;
++ TLSOutStream* self= (TLSOutStream*) str;
++ OutStream *out = self->out;
+
+ try {
+ out->writeBytes(data, size);
+ out->flush();
+ } catch (Exception& e) {
+- gnutls_transport_set_global_errno(EINVAL);
++ gnutls_errno_helper(self->session, EINVAL);
+ return -1;
+ }
+
+@@ -55,8 +53,14 @@
+ TLSOutStream::TLSOutStream(OutStream* _out, gnutls_session _session)
+ : session(_session), out(_out), bufSize(DEFAULT_BUF_SIZE), offset(0)
+ {
++ gnutls_transport_ptr recv, send;
++
+ ptr = start = new U8[bufSize];
+ end = start + bufSize;
++
++ gnutls_transport_set_push_function(session, push);
++ gnutls_transport_get_ptr2(session, &recv, &send);
++ gnutls_transport_set_ptr2(session, recv, this);
+ }
+
+ TLSOutStream::~TLSOutStream()
+@@ -67,6 +71,8 @@
+ } catch (Exception&) {
+ }
+ #endif
++ gnutls_transport_set_push_function(session, NULL);
++
+ delete [] start;
+ }
+
+
+--- common/rdr/TLSOutStream.h 2010-04-23 23:12:18.000000000 +0900
++++ common/rdr/TLSOutStream.h 2013-05-27 19:09:50.101573000 +0900
+@@ -43,6 +43,7 @@
+
+ private:
+ int writeTLS(const U8* data, int length);
++ static ssize_t push(gnutls_transport_ptr str, const void* data, size_t size);
+
+ gnutls_session session;
+ OutStream* out;
+@@ -50,8 +51,6 @@
+ U8* start;
+ int offset;
+ };
+-
+- ssize_t gnutls_OutStream_push(gnutls_transport_ptr, const void*, size_t);
+ };
+
+ #endif
diff --git a/net/tigervnc/files/extra-patch-common_rfb.patch b/net/tigervnc/files/extra-patch-common_rfb.patch
new file mode 100644
index 000000000000..80306b9649a6
--- /dev/null
+++ b/net/tigervnc/files/extra-patch-common_rfb.patch
@@ -0,0 +1,259 @@
+
+--- common/rfb/CConnection.cxx 2011-11-15 00:44:11.000000000 +0900
++++ common/rfb/CConnection.cxx 2013-05-27 19:09:50.167574000 +0900
+@@ -100,7 +100,7 @@
+ char msg[256];
+ sprintf(msg,"Server gave unsupported RFB protocol version %d.%d",
+ cp.majorVersion, cp.minorVersion);
+- vlog.error(msg);
++ vlog.error("%s", msg);
+ state_ = RFBSTATE_INVALID;
+ throw Exception(msg);
+ } else if (useProtocol3_3 || cp.beforeVersion(3,7)) {
+
+--- common/rfb/CMsgReader.cxx 2010-02-10 16:43:02.000000000 +0900
++++ common/rfb/CMsgReader.cxx 2013-05-27 19:09:50.274574000 +0900
+@@ -100,7 +100,7 @@
+ readCopyRect(r);
+ } else {
+
+- if (encoding > encodingMax) {
++ if (!Decoder::supported(encoding)) {
+ fprintf(stderr, "Unknown rect encoding %d\n", encoding);
+ throw Exception("Unknown rect encoding");
+ }
+
+--- common/rfb/CSecurityTLS.cxx 2011-05-10 17:54:57.000000000 +0900
++++ common/rfb/CSecurityTLS.cxx 2013-05-27 19:09:50.329576000 +0900
+@@ -72,7 +72,7 @@
+
+ static void debug_log(int level, const char* str)
+ {
+- vlog_raw.debug(str);
++ vlog_raw.debug("[%d]: %s", level, str);
+ }
+
+ void CSecurityTLS::initGlobal()
+@@ -188,20 +188,20 @@
+ throw AuthFailureException("gnutls_set_default_priority failed");
+
+ setParam();
+-
+- gnutls_transport_set_pull_function(session, rdr::gnutls_InStream_pull);
+- gnutls_transport_set_push_function(session, rdr::gnutls_OutStream_push);
+- gnutls_transport_set_ptr2(session,
+- (gnutls_transport_ptr) is,
+- (gnutls_transport_ptr) os);
+ }
+
++ rdr::TLSInStream *tlsis = new rdr::TLSInStream(is, session);
++ rdr::TLSOutStream *tlsos = new rdr::TLSOutStream(os, session);
++
+ int err;
+ err = gnutls_handshake(session);
+- if (err != GNUTLS_E_SUCCESS && !gnutls_error_is_fatal(err))
+- return false;
+-
+ if (err != GNUTLS_E_SUCCESS) {
++ delete tlsis;
++ delete tlsos;
++
++ if (!gnutls_error_is_fatal(err))
++ return false;
++
+ vlog.error("TLS Handshake failed: %s\n", gnutls_strerror (err));
+ shutdown(false);
+ throw AuthFailureException("TLS Handshake failed");
+@@ -209,8 +209,7 @@
+
+ checkSession();
+
+- cc->setStreams(fis = new rdr::TLSInStream(is, session),
+- fos = new rdr::TLSOutStream(os, session));
++ cc->setStreams(fis = tlsis, fos = tlsos);
+
+ return true;
+ }
+
+--- common/rfb/Decoder.cxx 2010-02-10 16:43:02.000000000 +0900
++++ common/rfb/Decoder.cxx 2013-05-27 19:09:50.186575000 +0900
+@@ -34,12 +34,12 @@
+
+ bool Decoder::supported(int encoding)
+ {
+- return encoding <= encodingMax && createFns[encoding];
++ return encoding >= 0 && encoding <= encodingMax && createFns[encoding];
+ }
+
+ Decoder* Decoder::createDecoder(int encoding, CMsgReader* reader)
+ {
+- if (encoding <= encodingMax && createFns[encoding])
++ if (supported(encoding))
+ return (*createFns[encoding])(reader);
+ return 0;
+ }
+
+--- common/rfb/LogWriter.h 2011-02-18 19:54:11.000000000 +0900
++++ common/rfb/LogWriter.h 2013-05-27 19:09:50.170575000 +0900
+@@ -25,12 +25,18 @@
+ #include <rfb/Logger.h>
+ #include <rfb/Configuration.h>
+
++#ifdef __GNUC__
++# define __printf_attr(a, b) __attribute__((__format__ (__printf__, a, b)))
++#else
++# define __printf_attr(a, b)
++#endif // __GNUC__
++
+ // Each log writer instance has a unique textual name,
+ // and is attached to a particular Log instance and
+ // is assigned a particular log level.
+
+ #define DEF_LOGFUNCTION(name, level) \
+- inline void name(const char* fmt, ...) { \
++ inline void name(const char* fmt, ...) __printf_attr(2, 3) { \
+ if (m_log && (level <= m_level)) { \
+ va_list ap; va_start(ap, fmt); \
+ m_log->write(level, m_name, fmt, ap);\
+@@ -53,7 +59,7 @@
+ void setLevel(int level);
+ int getLevel(void) { return m_level; }
+
+- inline void write(int level, const char* format, ...) {
++ inline void write(int level, const char* format, ...) __printf_attr(3, 4) {
+ if (m_log && (level <= m_level)) {
+ va_list ap;
+ va_start(ap, format);
+
+--- common/rfb/SConnection.cxx 2011-11-15 01:22:23.000000000 +0900
++++ common/rfb/SConnection.cxx 2013-05-27 19:09:50.208576000 +0900
+@@ -239,7 +239,7 @@
+
+ void SConnection::throwConnFailedException(const char* msg)
+ {
+- vlog.info(msg);
++ vlog.info("%s", msg);
+ if (state_ == RFBSTATE_PROTOCOL_VERSION) {
+ if (cp.majorVersion == 3 && cp.minorVersion == 3) {
+ os->writeU32(0);
+
+--- common/rfb/SSecurityTLS.cxx 2011-02-18 19:54:11.000000000 +0900
++++ common/rfb/SSecurityTLS.cxx 2013-05-27 19:09:50.354575000 +0900
+@@ -49,7 +49,7 @@
+
+ static void debug_log(int level, const char* str)
+ {
+- vlog.debug(str);
++ vlog.debug("[%d]: %s", level, str);
+ }
+
+ void SSecurityTLS::initGlobal()
+@@ -148,17 +148,19 @@
+ throw;
+ }
+
+- gnutls_transport_set_pull_function(session,rdr::gnutls_InStream_pull);
+- gnutls_transport_set_push_function(session,rdr::gnutls_OutStream_push);
+- gnutls_transport_set_ptr2(session,
+- (gnutls_transport_ptr)is,
+- (gnutls_transport_ptr)os);
+ os->writeU8(1);
+ os->flush();
+ }
+
++ rdr::TLSInStream *tlsis = new rdr::TLSInStream(is, session);
++ rdr::TLSOutStream *tlsos = new rdr::TLSOutStream(os, session);
++
+ int err;
+- if ((err = gnutls_handshake(session)) != GNUTLS_E_SUCCESS) {
++ err = gnutls_handshake(session);
++ if (err != GNUTLS_E_SUCCESS) {
++ delete tlsis;
++ delete tlsos;
++
+ if (!gnutls_error_is_fatal(err)) {
+ vlog.debug("Deferring completion of TLS handshake: %s", gnutls_strerror(err));
+ return false;
+@@ -170,8 +172,7 @@
+
+ vlog.debug("Handshake completed");
+
+- sc->setStreams(fis=new rdr::TLSInStream(is,session),
+- fos=new rdr::TLSOutStream(os,session));
++ sc->setStreams(fis = tlsis, fos = tlsos);
+
+ return true;
+ }
+
+--- common/rfb/ScreenSet.h 2010-12-01 19:11:20.000000000 +0900
++++ common/rfb/ScreenSet.h 2013-05-27 19:09:50.103575000 +0900
+@@ -23,6 +23,7 @@
+
+ #include <stdio.h>
+
++#include <rdr/types.h>
+ #include <rfb/Rect.h>
+ #include <list>
+ #include <set>
+
+--- common/rfb/VNCSConnectionST.cxx 2011-12-21 22:17:54.000000000 +0900
++++ common/rfb/VNCSConnectionST.cxx 2013-05-27 19:09:50.296574000 +0900
+@@ -66,7 +66,8 @@
+ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
+ bool reverse)
+ : SConnection(reverse), sock(s), inProcessMessages(false),
+- syncFence(false), fenceFlags(0), fenceDataLen(0), fenceData(NULL),
++ pendingSyncFence(false), syncFence(false), fenceFlags(0),
++ fenceDataLen(0), fenceData(NULL),
+ baseRTT(-1), minRTT(-1), seenCongestion(false), pingCounter(0),
+ ackedOffset(0), sentOffset(0), congWindow(0), congestionTimer(this),
+ server(server_),
+@@ -156,7 +157,13 @@
+ network::TcpSocket::cork(sock->getFd(), true);
+
+ while (getInStream()->checkNoWait(1)) {
++ if (pendingSyncFence) {
++ syncFence = true;
++ pendingSyncFence = false;
++ }
++
+ processMsg();
++
+ if (syncFence) {
+ writer()->writeFence(fenceFlags, fenceDataLen, fenceData);
+ syncFence = false;
+@@ -627,10 +634,7 @@
+ {
+ if (flags & fenceFlagRequest) {
+ if (flags & fenceFlagSyncNext) {
+- if (syncFence)
+- vlog.error("Fence trying to synchronise another fence");
+-
+- syncFence = true;
++ pendingSyncFence = true;
+
+ fenceFlags = flags & (fenceFlagBlockBefore | fenceFlagBlockAfter | fenceFlagSyncNext);
+ fenceDataLen = len;
+@@ -1083,6 +1087,10 @@
+ if (i->width() && i->height()) {
+ int nUpdateRects = writer()->getNumRects(*i);
+ if (nUpdateRects == 0 && cp.currentEncoding() == encodingTight) {
++ // With Tight encoding and LastRect support, the client does not
++ // care about the number of rectangles in the update - it will
++ // stop parsing when it encounters a LastRect "rectangle".
++ // In this case, pretend to send 65535 rectangles.
+ nRects = 0xFFFF; break;
+ }
+ else
+
+--- common/rfb/VNCSConnectionST.h 2011-11-21 00:36:11.000000000 +0900
++++ common/rfb/VNCSConnectionST.h 2013-05-27 19:09:50.156574000 +0900
+@@ -183,7 +183,7 @@
+
+ bool inProcessMessages;
+
+- bool syncFence;
++ bool pendingSyncFence, syncFence;
+ rdr::U32 fenceFlags;
+ unsigned fenceDataLen;
+ char *fenceData;
diff --git a/net/tigervnc/files/extra-patch-unix_hw_vnc.patch b/net/tigervnc/files/extra-patch-unix_hw_vnc.patch
new file mode 100644
index 000000000000..547ea69dc1e7
--- /dev/null
+++ b/net/tigervnc/files/extra-patch-unix_hw_vnc.patch
@@ -0,0 +1,1806 @@
+
+--- unix/xserver/hw/vnc/Input.cc 2011-11-08 21:44:10.000000000 +0900
++++ unix/xserver/hw/vnc/Input.cc 2013-05-27 18:54:41.184574000 +0900
+@@ -82,10 +82,11 @@
+ /* Event queue is shared between all devices. */
+ #if XORG == 15
+ static xEvent *eventq = NULL;
+-#else
++#elif XORG < 111
+ static EventList *eventq = NULL;
+ #endif
+
++#if XORG < 111
+ static void initEventq(void)
+ {
+ /* eventq is never free()-ed because it exists during server life. */
+@@ -100,7 +101,9 @@
+ #endif
+ }
+ }
++#endif /* XORG < 111 */
+
++#if XORG < 111
+ static void enqueueEvents(DeviceIntPtr dev, int n)
+ {
+ int i;
+@@ -122,6 +125,7 @@
+ );
+ }
+ }
++#endif /* XORG < 111 */
+
+ InputDevice::InputDevice(rfb::VNCServerST *_server)
+ : server(_server), oldButtonMask(0)
+@@ -141,12 +145,17 @@
+ keyboardProc, TRUE);
+ RegisterKeyboardDevice(keyboardDev);
+ #endif
++#if XORG < 111
+ initEventq();
++#endif
+ }
+
+ void InputDevice::PointerButtonAction(int buttonMask)
+ {
+- int i, n;
++ int i;
++#if XORG < 111
++ int n;
++#endif
+ #if XORG >= 110
+ ValuatorMask mask;
+ #endif
+@@ -160,13 +169,17 @@
+ #if XORG < 110
+ n = GetPointerEvents(eventq, pointerDev, action, i + 1,
+ POINTER_RELATIVE, 0, 0, NULL);
+-#else
++ enqueueEvents(pointerDev, n);
++#elif XORG < 111
+ valuator_mask_set_range(&mask, 0, 0, NULL);
+ n = GetPointerEvents(eventq, pointerDev, action, i + 1,
+ POINTER_RELATIVE, &mask);
+-#endif
+ enqueueEvents(pointerDev, n);
+-
++#else
++ valuator_mask_set_range(&mask, 0, 0, NULL);
++ QueuePointerEvents(pointerDev, action, i + 1,
++ POINTER_RELATIVE, &mask);
++#endif
+ }
+ }
+
+@@ -175,7 +188,10 @@
+
+ void InputDevice::PointerMove(const rfb::Point &pos)
+ {
+- int n, valuators[2];
++ int valuators[2];
++#if XORG < 111
++ int n;
++#endif
+ #if XORG >= 110
+ ValuatorMask mask;
+ #endif
+@@ -190,12 +206,16 @@
+ #if XORG < 110
+ n = GetPointerEvents(eventq, pointerDev, MotionNotify, 0, POINTER_ABSOLUTE, 0,
+ 2, valuators);
+-#else
++ enqueueEvents(pointerDev, n);
++#elif XORG < 111
+ valuator_mask_set_range(&mask, 0, 2, valuators);
+ n = GetPointerEvents(eventq, pointerDev, MotionNotify, 0, POINTER_ABSOLUTE,
+ &mask);
+-#endif
+ enqueueEvents(pointerDev, n);
++#else
++ valuator_mask_set_range(&mask, 0, 2, valuators);
++ QueuePointerEvents(pointerDev, MotionNotify, 0, POINTER_ABSOLUTE, &mask);
++#endif
+
+ cursorPos = pos;
+ }
+@@ -298,14 +318,20 @@
+ static inline void pressKey(DeviceIntPtr dev, int kc, bool down, const char *msg)
+ {
+ int action;
++#if XORG < 111
+ unsigned int n;
++#endif
+
+ if (msg != NULL)
+ vlog.debug("%s %d %s", msg, kc, down ? "down" : "up");
+
+ action = down ? KeyPress : KeyRelease;
+- n = GetKeyboardEvents(eventq, dev, action, kc);
++#if XORG < 111
++ n = GetKeyboardEvents(eventq, dev, action, kc, NULL);
+ enqueueEvents(dev, n);
++#else
++ QueueKeyboardEvents(dev, action, kc, NULL);
++#endif
+ }
+
+ #define IS_PRESSED(keyc, keycode) \
+@@ -340,8 +366,11 @@
+ int state, maxKeysPerMod, keycode;
+ #if XORG >= 17
+ KeyCode *modmap = NULL;
+-
++#if XORG >= 111
++ state = XkbStateFieldFromRec(&dev->master->key->xkbInfo->state);
++#else /* XORG >= 111 */
+ state = XkbStateFieldFromRec(&dev->u.master->key->xkbInfo->state);
++#endif /* XORG >= 111 */
+ #else
+ KeyClassPtr keyc = dev->key;
+ state = keyc->state;
+@@ -379,7 +408,11 @@
+ #if XORG >= 17
+ KeyCode *modmap = NULL;
+
++#if XORG >= 111
++ keyc = dev->master->key;
++#else /* XORG >= 111 */
+ keyc = dev->u.master->key;
++#endif /* XORG >= 111 */
+ state = XkbStateFieldFromRec(&keyc->xkbInfo->state);
+ #else
+ keyc = dev->key;
+@@ -595,7 +628,11 @@
+ }
+
+ #if XORG >= 17
++#if XORG >= 111
++ keyc = keyboardDev->master->key;
++#else /* XORG >= 111 */
+ keyc = keyboardDev->u.master->key;
++#endif /* XORG >= 111 */
+
+ keymap = XkbGetCoreMap(keyboardDev);
+ if (!keymap) {
+@@ -752,7 +789,11 @@
+ XkbApplyMappingChange(keyboardDev, keymap, minKeyCode,
+ maxKeyCode - minKeyCode + 1,
+ NULL, serverClient);
++#if XORG >= 111
++ XkbCopyDeviceKeymap(keyboardDev->master, keyboardDev);
++#else
+ XkbCopyDeviceKeymap(keyboardDev->u.master, keyboardDev);
++#endif
+ #endif /* XORG < 17 */
+ break;
+ }
+
+--- unix/xserver/hw/vnc/Makefile.am 2011-10-31 17:14:40.000000000 +0900
++++ unix/xserver/hw/vnc/Makefile.am 2013-05-27 18:54:41.196574000 +0900
+@@ -63,7 +63,7 @@
+ BUILT_SOURCES = $(nodist_Xvnc_SOURCES)
+
+ fb.h: $(top_srcdir)/fb/fb.h
+- cat $(top_srcdir)/fb/fb.h | sed -e 's,and,c_and,' -e 's,xor,c_xor,' > $(srcdir)/fb.h
++ cat $(top_srcdir)/fb/fb.h | sed -e 's,and,c_and,g' -e 's,xor,c_xor,g' > $(srcdir)/fb.h
+
+ pixman.h:
+ for i in ${XSERVERLIBS_CFLAGS}; do \
+@@ -78,4 +78,4 @@
+ fi
+
+ fbrop.h: $(top_srcdir)/fb/fbrop.h
+- cat $(top_srcdir)/fb/fbrop.h | sed -e 's,and,c_and,' -e 's,xor,c_xor,' > $(srcdir)/fbrop.h
++ cat $(top_srcdir)/fb/fbrop.h | sed -e 's,and,c_and,g' -e 's,xor,c_xor,g' > $(srcdir)/fbrop.h
+
+--- unix/xserver/hw/vnc/XserverDesktop.cc 2012-01-24 00:54:11.000000000 +0900
++++ unix/xserver/hw/vnc/XserverDesktop.cc 2013-05-27 18:54:41.203576000 +0900
+@@ -200,6 +200,8 @@
+
+ void XserverDesktop::setFramebuffer(int w, int h, void* fbptr, int stride)
+ {
++ ScreenSet layout;
++
+ width_ = w;
+ height_ = h;
+
+@@ -217,9 +219,98 @@
+ data = (rdr::U8*)fbptr;
+ stride_ = stride;
+
+- server->setPixelBuffer(this);
++ layout = computeScreenLayout();
++
++ server->setPixelBuffer(this, layout);
++}
++
++void XserverDesktop::refreshScreenLayout()
++{
++ server->setScreenLayout(computeScreenLayout());
++}
++
++ScreenSet XserverDesktop::computeScreenLayout()
++{
++ ScreenSet layout;
++
++#ifdef RANDR
++ rrScrPrivPtr rp = rrGetScrPriv(pScreen);
++ OutputIdMap newIdMap;
++
++ for (int i = 0;i < rp->numOutputs;i++) {
++ RROutputPtr output;
++ RRCrtcPtr crtc;
++
++ output = rp->outputs[i];
++ crtc = output->crtc;
++
++ /* Disabled? */
++ if ((crtc == NULL) || (crtc->mode == NULL))
++ continue;
++
++ /* Known output? */
++ if (outputIdMap.count(output) == 1)
++ newIdMap[output] = outputIdMap[output];
++ else {
++ rdr::U32 id;
++ OutputIdMap::const_iterator iter;
++
++ while (true) {
++ id = rand();
++ for (iter = outputIdMap.begin();iter != outputIdMap.end();++iter) {
++ if (iter->second == id)
++ break;
++ }
++ if (iter == outputIdMap.end())
++ break;
++ }
++
++ newIdMap[output] = id;
++ }
++
++ layout.add_screen(Screen(newIdMap[output], crtc->x, crtc->y,
++ crtc->mode->mode.width,
++ crtc->mode->mode.height,
++ 0));
++ }
++
++ /* Only keep the entries that are currently active */
++ outputIdMap = newIdMap;
++#endif
++
++ /*
++ * Make sure we have something to display. Hopefully it's just temporary
++ * that we have no active outputs...
++ */
++ if (layout.num_screens() == 0)
++ layout.add_screen(Screen(0, 0, 0, pScreen->width, pScreen->height, 0));
++
++ return layout;
+ }
+
++#ifdef RANDR
++
++extern RRModePtr vncRandRModeGet(int width, int height);
++
++RRModePtr XserverDesktop::findRandRMode(RROutputPtr output, int width, int height)
++{
++ RRModePtr mode;
++
++ for (int i = 0;i < output->numModes;i++) {
++ if ((output->modes[i]->mode.width == width) &&
++ (output->modes[i]->mode.height == height))
++ return output->modes[i];
++ }
++
++ mode = vncRandRModeGet(width, height);
++ if (mode != NULL)
++ return mode;
++
++ return NULL;
++}
++
++#endif
++
+ char* XserverDesktop::substitute(const char* varName)
+ {
+ if (strcmp(varName, "$$") == 0) {
+@@ -727,100 +818,251 @@
+ vncClientCutText(str, len);
+ }
+
+-#ifdef RANDR
++extern RROutputPtr vncRandROutputCreate(ScreenPtr pScreen);
++
+ unsigned int XserverDesktop::setScreenLayout(int fb_width, int fb_height,
+ const rfb::ScreenSet& layout)
+ {
+- int i;
+- Bool ret;
+- RRScreenSizePtr pSize;
+- RROutputPtr output;
+- RRModePtr mode;
+-
+- // Make sure all RandR tables are properly populated
+-#if XORG == 15
+- ret = RRGetInfo(pScreen);
++#ifndef RANDR
++ return rfb::resultProhibited;
+ #else
+- ret = RRGetInfo(pScreen, FALSE);
+-#endif
+- if (!ret)
+- return resultNoResources;
++ int availableOutputs;
++ Bool ret;
+
+- // Register a new size, or get a reference to the existing one
+- pSize = RRRegisterSize(pScreen, fb_width, fb_height,
+- pScreen->mmWidth, pScreen->mmHeight);
+- if (!pSize) {
+- vlog.error("setScreenLayout: Could not get register new resolution");
+- return resultNoResources;
+- }
+- ret = RRRegisterRate(pScreen, pSize, 60);
+- if (!ret) {
+- vlog.error("setScreenLayout: Could not register a rate for the resolution");
+- return resultNoResources;
+- }
+-
+- // Then we have to call RRGetInfo again for it to copy the RandR
+- // 1.0 information to the 1.2 structures.
+-#if XORG == 15
+- ret = RRGetInfo(pScreen);
+-#else
+- ret = RRGetInfo(pScreen, FALSE);
+-#endif
+- if (!ret)
+- return resultNoResources;
++ rrScrPrivPtr rp = rrGetScrPriv(pScreen);
+
+- // Go via RandR to set the resolution in order for X11 notifications
+- // to be sent out properly. We currently only do RandR 1.0, but Xorg
+- // has dropped support for that API. So we have to emulate it via the
+- // same method ProcRRSetScreenConfig() uses.
+- //
+- // FIXME: This will cause setPixelBuffer() to be called, resulting in
+- // an unnecessary ExtendedDesktopSize to be sent.
+-
+- // We'll just reconfigure the first output
+- output = RRFirstOutput(pScreen);
+- if (!output) {
+- vlog.error("setScreenLayout: Could not get first output");
+- return resultNoResources;
+- }
+-
+- // Find first mode with matching size
+- mode = NULL;
+- for (i = 0;i < output->numModes;i++) {
+- if ((output->modes[i]->mode.width == fb_width) &&
+- (output->modes[i]->mode.height == fb_height)) {
+- mode = output->modes[i];
+- break;
++ /*
++ * First check that we don't have any active clone modes. That's just
++ * too messy to deal with.
++ */
++ for (int i = 0;i < rp->numCrtcs;i++) {
++ if (rp->crtcs[i]->numOutputs > 1) {
++ vlog.error("Clone mode active. Refusing to touch screen layout.");
++ return rfb::resultInvalid;
++ }
++ }
++
++ /*
++ * Next count how many useful outputs we have...
++ *
++ * This gets slightly complicated because we might need to hook a CRTC
++ * up to the output, but also check that we don't try to use the same
++ * CRTC for multiple outputs.
++ */
++ std::set<RRCrtcPtr> usedCrtcs;
++ availableOutputs = 0;
++ for (int i = 0;i < rp->numOutputs;i++) {
++ RROutputPtr output;
++
++ output = rp->outputs[i];
++
++ if (output->crtc != NULL)
++ availableOutputs++;
++ else {
++ for (int j = 0;j < output->numCrtcs;j++) {
++ if (output->crtcs[j]->numOutputs != 0)
++ continue;
++ if (usedCrtcs.count(output->crtcs[j]) != 0)
++ continue;
++
++ availableOutputs++;
++ usedCrtcs.insert(output->crtcs[j]);
++
++ break;
++ }
+ }
+ }
+- if (!mode) {
+- vlog.error("setScreenLayout: Could not find a matching mode");
+- return resultNoResources;
++
++ /* Try to create more outputs if needed... (only works on Xvnc) */
++ if (layout.num_screens() > availableOutputs) {
++ for (int i = 0;i < (layout.num_screens() - availableOutputs);i++) {
++ RROutputPtr output;
++ output = vncRandROutputCreate(pScreen);
++ if (output == NULL) {
++ vlog.error("Unable to create more screens, as needed by the new client layout.");
++ return rfb::resultInvalid;
++ }
++ }
+ }
+
+- // Adjust screen size
+- ret = RRScreenSizeSet(pScreen, fb_width, fb_height,
+- pScreen->mmWidth, pScreen->mmHeight);
+- if (!ret) {
+- vlog.error("setScreenLayout: Could not adjust screen size");
+- return resultNoResources;
++ /* First we might need to resize the screen */
++ if ((fb_width != pScreen->width) || (fb_height != pScreen->height)) {
++ /* Try to retain DPI when we resize */
++ ret = RRScreenSizeSet(pScreen, fb_width, fb_height,
++ pScreen->mmWidth * fb_width / pScreen->width,
++ pScreen->mmHeight * fb_height / pScreen->height);
++ if (!ret) {
++ vlog.error("Failed to resize screen to %dx%d", fb_width, fb_height);
++ return rfb::resultInvalid;
++ }
++ }
++
++ /* Next, reconfigure all known outputs, and turn off the other ones */
++ for (int i = 0;i < rp->numOutputs;i++) {
++ RROutputPtr output;
++ RRCrtcPtr crtc;
++ RRModePtr mode;
++
++ ScreenSet::const_iterator iter;
++
++ output = rp->outputs[i];
++ crtc = output->crtc;
++
++ /* Known? */
++ if (outputIdMap.count(output) == 0)
++ continue;
++
++ /* A known output should have a CRTC, but double check... */
++ if (crtc == NULL) {
++ vlog.error("Existing output '%s' has unexpectedly been disabled",
++ output->name);
++ continue;
++ }
++
++ /* Find the corresponding screen... */
++ for (iter = layout.begin();iter != layout.end();++iter) {
++ if (iter->id == outputIdMap[output])
++ break;
++ }
++
++ /* Missing? */
++ if (iter == layout.end()) {
++ /* Disable and move on... */
++ ret = RRCrtcSet(crtc, NULL, crtc->x, crtc->y, crtc->rotation,
++ crtc->numOutputs, crtc->outputs);
++ if (!ret) {
++ vlog.error("Failed to disable unused CRTC for output '%s'",
++ output->name);
++ return rfb::resultInvalid;
++ }
++ outputIdMap.erase(output);
++ continue;
++ }
++
++ /* Need to switch mode? */
++ if ((crtc->mode->mode.width == iter->dimensions.width()) &&
++ (crtc->mode->mode.height == iter->dimensions.height()))
++ mode = crtc->mode;
++ else {
++ mode = findRandRMode(output, iter->dimensions.width(),
++ iter->dimensions.height());
++ if (mode == NULL) {
++ vlog.error("Failed to find a suitable mode for %dx%d for output '%s'",
++ iter->dimensions.width(), iter->dimensions.height(),
++ output->name);
++ return rfb::resultInvalid;
++ }
++ }
++
++ /* Reconfigure new mode and position */
++ ret = RRCrtcSet(crtc, mode, iter->dimensions.tl.x, iter->dimensions.tl.y,
++ crtc->rotation, crtc->numOutputs, crtc->outputs);
++ if (!ret) {
++ vlog.error("Failed to reconfigure output '%s' to %dx%d+%d+%d",
++ output->name,
++ iter->dimensions.width(), iter->dimensions.height(),
++ iter->dimensions.tl.x, iter->dimensions.tl.y);
++ return rfb::resultInvalid;
++ }
+ }
+
+- // And then the CRTC
+- ret = RRCrtcSet(output->crtc, mode, 0, 0, RR_Rotate_0, 1, &output);
+- if (!ret) {
+- vlog.error("setScreenLayout: Could not adjust CRTC");
+- return resultNoResources;
++ /* Finally, allocate new outputs for new screens */
++ ScreenSet::const_iterator iter;
++ for (iter = layout.begin();iter != layout.end();++iter) {
++ OutputIdMap::const_iterator oi;
++
++ RROutputPtr output;
++ RRCrtcPtr crtc;
++ RRModePtr mode;
++
++ int i;
++
++ /* Does this screen have an output already? */
++ for (oi = outputIdMap.begin();oi != outputIdMap.end();++oi) {
++ if (oi->second == iter->id)
++ break;
++ }
++
++ if (oi != outputIdMap.end())
++ continue;
++
++ /* Find an unused output */
++ for (i = 0;i < rp->numOutputs;i++) {
++ output = rp->outputs[i];
++ crtc = output->crtc;
++
++ /* In use? */
++ if (outputIdMap.count(output) == 1)
++ continue;
++
++ /* Need a CRTC? */
++ if (crtc == NULL) {
++ for (int j = 0;j < output->numCrtcs;j++) {
++ if (output->crtcs[j]->numOutputs != 0)
++ continue;
++
++ crtc = output->crtcs[j];
++ break;
++ }
++
++ /* Couldn't find one... */
++ if (crtc == NULL)
++ continue;
++
++ ret = RRCrtcSet(crtc, NULL, 0, 0, RR_Rotate_0,
++ 1, &output);
++ if (!ret) {
++ vlog.error("Failed to associate a CRTC with output '%s'",
++ output->name);
++ return rfb::resultInvalid;
++ }
++ }
++
++ break;
++ }
++
++ /* Shouldn't happen */
++ if (i == rp->numOutputs)
++ return rfb::resultInvalid;
++
++ mode = findRandRMode(output, iter->dimensions.width(),
++ iter->dimensions.height());
++ if (mode == NULL) {
++ vlog.error("Failed to find a suitable mode for %dx%d for output '%s'",
++ iter->dimensions.width(), iter->dimensions.height(),
++ output->name);
++ return rfb::resultInvalid;
++ }
++
++ /*
++ * Make sure we already have an entry for this, or
++ * computeScreenLayout() will think it is a brand new output and
++ * assign it a random id.
++ */
++ outputIdMap[output] = iter->id;
++
++ /* Reconfigure new mode and position */
++ ret = RRCrtcSet(crtc, mode, iter->dimensions.tl.x, iter->dimensions.tl.y,
++ crtc->rotation, crtc->numOutputs, crtc->outputs);
++ if (!ret) {
++ vlog.error("Failed to reconfigure output '%s' to %dx%d+%d+%d",
++ output->name,
++ iter->dimensions.width(), iter->dimensions.height(),
++ iter->dimensions.tl.x, iter->dimensions.tl.y);
++ return rfb::resultInvalid;
++ }
+ }
+
+- // RandR 1.0 doesn't carry any screen layout information, so we need
+- // to update that manually. This results in another unnecessary
+- // ExtendedDesktopSize.
+- server->setScreenLayout(layout);
++ /*
++ * Update timestamp for when screen layout was last changed.
++ * This is normally done in the X11 request handlers, which is
++ * why we have to deal with it manually here.
++ */
++ rp->lastSetTime = currentTime;
+
+- return resultSuccess;
++ return rfb::resultSuccess;
++#endif
+ }
+-#endif // RANDR
+
+ void XserverDesktop::grabRegion(const rfb::Region& region)
+ {
+
+--- unix/xserver/hw/vnc/XserverDesktop.h 2012-01-24 00:54:11.000000000 +0900
++++ unix/xserver/hw/vnc/XserverDesktop.h 2013-05-27 18:54:41.210573000 +0900
+@@ -27,6 +27,8 @@
+ #include <dix-config.h>
+ #endif
+
++#include <map>
++
+ #include <rfb/SDesktop.h>
+ #include <rfb/HTTPServer.h>
+ #include <rfb/PixelBuffer.h>
+@@ -39,6 +41,9 @@
+ #define class c_class
+ #include <scrnintstr.h>
+ #include <os.h>
++#ifdef RANDR
++#include <randrstr.h>
++#endif
+ #undef class
+ }
+
+@@ -64,6 +69,7 @@
+ void blockUpdates();
+ void unblockUpdates();
+ void setFramebuffer(int w, int h, void* fbptr, int stride);
++ void refreshScreenLayout();
+ void setColormap(ColormapPtr cmap);
+ void setColourMapEntries(ColormapPtr pColormap, int ndef, xColorItem* pdef);
+ void bell();
+@@ -101,10 +107,8 @@
+ virtual void keyEvent(rdr::U32 key, bool down);
+ virtual void clientCutText(const char* str, int len);
+ virtual rfb::Point getFbSize() { return rfb::Point(width(), height()); }
+-#ifdef RANDR
+ virtual unsigned int setScreenLayout(int fb_width, int fb_height,
+ const rfb::ScreenSet& layout);
+-#endif
+
+ // rfb::PixelBuffer callbacks
+ virtual void grabRegion(const rfb::Region& r);
+@@ -123,6 +127,11 @@
+
+ private:
+ void setColourMapEntries(int firstColour, int nColours);
++ rfb::ScreenSet computeScreenLayout();
++#ifdef RANDR
++ RRModePtr findRandRMode(RROutputPtr output, int width, int height);
++#endif
++
+ ScreenPtr pScreen;
+ InputDevice *inputDevice;
+ rfb::VNCServerST* server;
+@@ -139,5 +148,10 @@
+ void* queryConnectId;
+ rfb::CharArray queryConnectAddress;
+ rfb::CharArray queryConnectUsername;
++
++#ifdef RANDR
++ typedef std::map<RROutputPtr, rdr::U32> OutputIdMap;
++ OutputIdMap outputIdMap;
++#endif
+ };
+ #endif
+
+--- unix/xserver/hw/vnc/vncExtInit.cc 2011-11-07 21:51:34.000000000 +0900
++++ unix/xserver/hw/vnc/vncExtInit.cc 2013-05-27 18:54:41.172575000 +0900
+@@ -59,6 +59,7 @@
+ #include "XserverDesktop.h"
+ #include "vncHooks.h"
+ #include "vncExtInit.h"
++#include "xorg-version.h"
+
+ extern "C" {
+
+@@ -449,10 +450,16 @@
+ ev.window = cur->window;
+ ev.time = GetTimeInMillis();
+ if (cur->client->swapped) {
++#if XORG < 112
+ int n;
+ swaps(&ev.sequenceNumber, n);
+ swapl(&ev.window, n);
+ swapl(&ev.time, n);
++#else
++ swaps(&ev.sequenceNumber);
++ swapl(&ev.window);
++ swapl(&ev.time);
++#endif
+ }
+ WriteToClient(cur->client, sizeof(xVncExtClientCutTextNotifyEvent),
+ (char *)&ev);
+@@ -495,9 +502,14 @@
+ ev.sequenceNumber = cur->client->sequence;
+ ev.window = cur->window;
+ if (cur->client->swapped) {
++#if XORG < 112
+ int n;
+ swaps(&ev.sequenceNumber, n);
+ swapl(&ev.window, n);
++#else
++ swaps(&ev.sequenceNumber);
++ swapl(&ev.window);
++#endif
+ }
+ WriteToClient(cur->client, sizeof(xVncExtQueryConnectNotifyEvent),
+ (char *)&ev);
+@@ -538,10 +550,16 @@
+ ev.window = cur->window;
+ ev.selection = selection;
+ if (cur->client->swapped) {
++#if XORG < 112
+ int n;
+ swaps(&ev.sequenceNumber, n);
+ swapl(&ev.window, n);
+ swapl(&ev.selection, n);
++#else
++ swaps(&ev.sequenceNumber);
++ swapl(&ev.window);
++ swapl(&ev.selection);
++#endif
+ }
+ WriteToClient(cur->client, sizeof(xVncExtSelectionChangeNotifyEvent),
+ (char *)&ev);
+@@ -562,7 +580,6 @@
+ param.buf[stuff->paramLen] = 0;
+
+ xVncExtSetParamReply rep;
+- int n;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.success = 0;
+@@ -603,8 +620,14 @@
+
+ deny:
+ if (client->swapped) {
++#if XORG < 112
++ int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
++#else
++ swaps(&rep.sequenceNumber);
++ swapl(&rep.length);
++#endif
+ }
+ WriteToClient(client, sizeof(xVncExtSetParamReply), (char *)&rep);
+ return (client->noClientException);
+@@ -612,9 +635,13 @@
+
+ static int SProcVncExtSetParam(ClientPtr client)
+ {
+- register char n;
+ REQUEST(xVncExtSetParamReq);
++#if XORG < 112
++ register char n;
+ swaps(&stuff->length, n);
++#else
++ swaps(&stuff->length);
++#endif
+ REQUEST_AT_LEAST_SIZE(xVncExtSetParamReq);
+ return ProcVncExtSetParam(client);
+ }
+@@ -628,7 +655,6 @@
+ param.buf[stuff->paramLen] = 0;
+
+ xVncExtGetParamReply rep;
+- int n;
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.success = 0;
+@@ -646,9 +672,16 @@
+ rep.length = (len + 3) >> 2;
+ rep.valueLen = len;
+ if (client->swapped) {
++#if XORG < 112
++ int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.valueLen, n);
++#else
++ swaps(&rep.sequenceNumber);
++ swapl(&rep.length);
++ swaps(&rep.valueLen);
++#endif
+ }
+ WriteToClient(client, sizeof(xVncExtGetParamReply), (char *)&rep);
+ if (value)
+@@ -659,9 +692,13 @@
+
+ static int SProcVncExtGetParam(ClientPtr client)
+ {
+- register char n;
+ REQUEST(xVncExtGetParamReq);
++#if XORG < 112
++ register char n;
+ swaps(&stuff->length, n);
++#else
++ swaps(&stuff->length);
++#endif
+ REQUEST_AT_LEAST_SIZE(xVncExtGetParamReq);
+ return ProcVncExtGetParam(client);
+ }
+@@ -675,7 +712,6 @@
+ param.buf[stuff->paramLen] = 0;
+
+ xVncExtGetParamDescReply rep;
+- int n;
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.success = 0;
+@@ -690,9 +726,16 @@
+ rep.length = (len + 3) >> 2;
+ rep.descLen = len;
+ if (client->swapped) {
++#if XORG < 112
++ int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.descLen, n);
++#else
++ swaps(&rep.sequenceNumber);
++ swapl(&rep.length);
++ swaps(&rep.descLen);
++#endif
+ }
+ WriteToClient(client, sizeof(xVncExtGetParamDescReply), (char *)&rep);
+ if (desc)
+@@ -702,9 +745,13 @@
+
+ static int SProcVncExtGetParamDesc(ClientPtr client)
+ {
+- register char n;
+ REQUEST(xVncExtGetParamDescReq);
++#if XORG < 112
++ register char n;
+ swaps(&stuff->length, n);
++#else
++ swaps(&stuff->length);
++#endif
+ REQUEST_AT_LEAST_SIZE(xVncExtGetParamDescReq);
+ return ProcVncExtGetParamDesc(client);
+ }
+@@ -715,7 +762,6 @@
+ REQUEST_SIZE_MATCH(xVncExtListParamsReq);
+
+ xVncExtListParamsReply rep;
+- int n;
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+
+@@ -731,9 +777,16 @@
+ rep.length = (len + 3) >> 2;
+ rep.nParams = nParams;
+ if (client->swapped) {
++#if XORG < 112
++ int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.nParams, n);
++#else
++ swaps(&rep.sequenceNumber);
++ swapl(&rep.length);
++ swaps(&rep.nParams);
++#endif
+ }
+ WriteToClient(client, sizeof(xVncExtListParamsReply), (char *)&rep);
+ rdr::U8* data = new rdr::U8[len];
+@@ -753,9 +806,13 @@
+
+ static int SProcVncExtListParams(ClientPtr client)
+ {
+- register char n;
+ REQUEST(xVncExtListParamsReq);
++#if XORG < 112
++ register char n;
+ swaps(&stuff->length, n);
++#else
++ swaps(&stuff->length);
++#endif
+ REQUEST_SIZE_MATCH(xVncExtListParamsReq);
+ return ProcVncExtListParams(client);
+ }
+@@ -778,11 +835,19 @@
+
+ static int SProcVncExtSetServerCutText(ClientPtr client)
+ {
+- register char n;
+ REQUEST(xVncExtSetServerCutTextReq);
++#if XORG < 112
++ register char n;
+ swaps(&stuff->length, n);
++#else
++ swaps(&stuff->length);
++#endif
+ REQUEST_AT_LEAST_SIZE(xVncExtSetServerCutTextReq);
++#if XORG < 112
+ swapl(&stuff->textLen, n);
++#else
++ swapl(&stuff->textLen);
++#endif
+ return ProcVncExtSetServerCutText(client);
+ }
+
+@@ -792,15 +857,21 @@
+ REQUEST_SIZE_MATCH(xVncExtGetClientCutTextReq);
+
+ xVncExtGetClientCutTextReply rep;
+- int n;
+ rep.type = X_Reply;
+ rep.length = (clientCutTextLen + 3) >> 2;
+ rep.sequenceNumber = client->sequence;
+ rep.textLen = clientCutTextLen;
+ if (client->swapped) {
++#if XORG < 112
++ int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.textLen, n);
++#else
++ swaps(&rep.sequenceNumber);
++ swapl(&rep.length);
++ swapl(&rep.textLen);
++#endif
+ }
+ WriteToClient(client, sizeof(xVncExtGetClientCutTextReply), (char *)&rep);
+ if (clientCutText)
+@@ -810,9 +881,13 @@
+
+ static int SProcVncExtGetClientCutText(ClientPtr client)
+ {
+- register char n;
+ REQUEST(xVncExtGetClientCutTextReq);
++#if XORG < 112
++ register char n;
+ swaps(&stuff->length, n);
++#else
++ swaps(&stuff->length);
++#endif
+ REQUEST_SIZE_MATCH(xVncExtGetClientCutTextReq);
+ return ProcVncExtGetClientCutText(client);
+ }
+@@ -842,12 +917,21 @@
+
+ static int SProcVncExtSelectInput(ClientPtr client)
+ {
+- register char n;
+ REQUEST(xVncExtSelectInputReq);
++#if XORG < 112
++ register char n;
+ swaps(&stuff->length, n);
++#else
++ swaps(&stuff->length);
++#endif
+ REQUEST_SIZE_MATCH(xVncExtSelectInputReq);
++#if XORG < 112
+ swapl(&stuff->window, n);
+ swapl(&stuff->mask, n);
++#else
++ swapl(&stuff->window);
++ swapl(&stuff->mask);
++#endif
+ return ProcVncExtSelectInput(client);
+ }
+
+@@ -893,9 +977,14 @@
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (client->swapped) {
++#if XORG < 112
+ int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
++#else
++ swaps(&rep.sequenceNumber);
++ swapl(&rep.length);
++#endif
+ }
+ WriteToClient(client, sizeof(xVncExtConnectReply), (char *)&rep);
+ return (client->noClientException);
+@@ -903,9 +992,13 @@
+
+ static int SProcVncExtConnect(ClientPtr client)
+ {
+- register char n;
+ REQUEST(xVncExtConnectReq);
++#if XORG < 112
++ register char n;
+ swaps(&stuff->length, n);
++#else
++ swaps(&stuff->length);
++#endif
+ REQUEST_AT_LEAST_SIZE(xVncExtConnectReq);
+ return ProcVncExtConnect(client);
+ }
+@@ -925,7 +1018,6 @@
+ qcTimeout = 0;
+
+ xVncExtGetQueryConnectReply rep;
+- int n;
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.timeout = qcTimeout;
+@@ -934,11 +1026,20 @@
+ rep.opaqueId = (CARD32)(long)queryConnectId;
+ rep.length = (rep.userLen + rep.addrLen + 3) >> 2;
+ if (client->swapped) {
++#if XORG < 112
++ int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.userLen, n);
+ swapl(&rep.addrLen, n);
+ swapl(&rep.timeout, n);
+ swapl(&rep.opaqueId, n);
++#else
++ swaps(&rep.sequenceNumber);
++ swapl(&rep.userLen);
++ swapl(&rep.addrLen);
++ swapl(&rep.timeout);
++ swapl(&rep.opaqueId);
++#endif
+ }
+ WriteToClient(client, sizeof(xVncExtGetQueryConnectReply), (char *)&rep);
+ if (qcTimeout)
+@@ -950,9 +1051,13 @@
+
+ static int SProcVncExtGetQueryConnect(ClientPtr client)
+ {
+- register char n;
+ REQUEST(xVncExtGetQueryConnectReq);
++#if XORG < 112
++ register char n;
+ swaps(&stuff->length, n);
++#else
++ swaps(&stuff->length);
++#endif
+ REQUEST_SIZE_MATCH(xVncExtGetQueryConnectReq);
+ return ProcVncExtGetQueryConnect(client);
+ }
+@@ -977,10 +1082,15 @@
+
+ static int SProcVncExtApproveConnect(ClientPtr client)
+ {
+- register char n;
+ REQUEST(xVncExtApproveConnectReq);
++#if XORG < 112
++ register char n;
+ swaps(&stuff->length, n);
+ swapl(&stuff->opaqueId, n);
++#else
++ swaps(&stuff->length);
++ swapl(&stuff->opaqueId);
++#endif
+ REQUEST_SIZE_MATCH(xVncExtApproveConnectReq);
+ return ProcVncExtApproveConnect(client);
+ }
+
+--- unix/xserver/hw/vnc/vncHooks.cc 2012-01-24 00:54:11.000000000 +0900
++++ unix/xserver/hw/vnc/vncHooks.cc 2013-05-27 18:55:18.837574000 +0900
+@@ -84,6 +84,8 @@
+ #endif
+ #ifdef RANDR
+ RRSetConfigProcPtr RandRSetConfig;
++ RRScreenSetSizeProcPtr RandRScreenSetSize;
++ RRCrtcSetProcPtr RandRCrtcSet;
+ #endif
+ } vncHooksScreenRec, *vncHooksScreenPtr;
+
+@@ -143,6 +145,13 @@
+ #ifdef RANDR
+ static Bool vncHooksRandRSetConfig(ScreenPtr pScreen, Rotation rotation,
+ int rate, RRScreenSizePtr pSize);
++static Bool vncHooksRandRScreenSetSize(ScreenPtr pScreen,
++ CARD16 width, CARD16 height,
++ CARD32 mmWidth, CARD32 mmHeight);
++static Bool vncHooksRandRCrtcSet(ScreenPtr pScreen, RRCrtcPtr crtc,
++ RRModePtr mode, int x, int y,
++ Rotation rotation, int numOutputs,
++ RROutputPtr *outputs);
+ #endif
+
+ // GC "funcs"
+@@ -283,6 +292,8 @@
+ rp = rrGetScrPriv(pScreen);
+ if (rp) {
+ vncHooksScreen->RandRSetConfig = rp->rrSetConfig;
++ vncHooksScreen->RandRScreenSetSize = rp->rrScreenSetSize;
++ vncHooksScreen->RandRCrtcSet = rp->rrCrtcSet;
+ }
+ #endif
+
+@@ -304,7 +315,13 @@
+ #endif
+ #ifdef RANDR
+ if (rp) {
+- rp->rrSetConfig = vncHooksRandRSetConfig;
++ /* Some RandR callbacks are optional */
++ if (rp->rrSetConfig)
++ rp->rrSetConfig = vncHooksRandRSetConfig;
++ if (rp->rrScreenSetSize)
++ rp->rrScreenSetSize = vncHooksRandRScreenSetSize;
++ if (rp->rrCrtcSet)
++ rp->rrCrtcSet = vncHooksRandRCrtcSet;
+ }
+ #endif
+
+@@ -361,6 +378,8 @@
+ rp = rrGetScrPriv(pScreen);
+ if (rp) {
+ rp->rrSetConfig = vncHooksScreen->RandRSetConfig;
++ rp->rrScreenSetSize = vncHooksScreen->RandRScreenSetSize;
++ rp->rrCrtcSet = vncHooksScreen->RandRCrtcSet;
+ }
+ #endif
+
+@@ -596,42 +615,106 @@
+
+ #ifdef RANDR
+
++static void vncPreScreenResize(ScreenPtr pScreen)
++{
++ vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen);
++
++ // We need to prevent the RFB core from accessing the framebuffer
++ // for a while as there might be updates thrown our way inside
++ // the routines that change the screen (i.e. before we have a
++ // pointer to the new framebuffer).
++ vncHooksScreen->desktop->blockUpdates();
++}
++
++static void vncPostScreenResize(ScreenPtr pScreen, Bool success)
++{
++ vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen);
++
++ RegionRec reg;
++ BoxRec box;
++
++ if (success) {
++ // Let the RFB core know of the new dimensions and framebuffer
++ vncHooksScreen->desktop->setFramebuffer(pScreen->width, pScreen->height,
++ vncFbptr[pScreen->myNum],
++ vncFbstride[pScreen->myNum]);
++ }
++
++ vncHooksScreen->desktop->unblockUpdates();
++
++ if (success) {
++ // Mark entire screen as changed
++ box.x1 = 0;
++ box.y1 = 0;
++ box.x2 = pScreen->width;
++ box.y2 = pScreen->height;
++ REGION_INIT(pScreen, &reg, &box, 1);
++
++ vncHooksScreen->desktop->add_changed(&reg);
++ }
++}
++
+ static Bool vncHooksRandRSetConfig(ScreenPtr pScreen, Rotation rotation,
+ int rate, RRScreenSizePtr pSize)
+ {
+ vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen);
+ rrScrPrivPtr rp = rrGetScrPriv(pScreen);
+ Bool ret;
+- RegionRec reg;
+- BoxRec box;
+
+- // We need to prevent the RFB core from accessing the framebuffer
+- // for a while as there might be updates thrown our way inside
+- // rrSetConfig (i.e. before we have a pointer to the new framebuffer).
+- vncHooksScreen->desktop->blockUpdates();
++ vncPreScreenResize(pScreen);
+
+ rp->rrSetConfig = vncHooksScreen->RandRSetConfig;
+ ret = (*rp->rrSetConfig)(pScreen, rotation, rate, pSize);
+ rp->rrSetConfig = vncHooksRandRSetConfig;
+
++ vncPostScreenResize(pScreen, ret);
++
+ if (!ret)
+ return FALSE;
+
+- // Let the RFB core know of the new dimensions and framebuffer
+- vncHooksScreen->desktop->setFramebuffer(pScreen->width, pScreen->height,
+- vncFbptr[pScreen->myNum],
+- vncFbstride[pScreen->myNum]);
++ return TRUE;
++}
+
+- vncHooksScreen->desktop->unblockUpdates();
++static Bool vncHooksRandRScreenSetSize(ScreenPtr pScreen,
++ CARD16 width, CARD16 height,
++ CARD32 mmWidth, CARD32 mmHeight)
++{
++ vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen);
++ rrScrPrivPtr rp = rrGetScrPriv(pScreen);
++ Bool ret;
++
++ vncPreScreenResize(pScreen);
++
++ rp->rrScreenSetSize = vncHooksScreen->RandRScreenSetSize;
++ ret = (*rp->rrScreenSetSize)(pScreen, width, height, mmWidth, mmHeight);
++ rp->rrScreenSetSize = vncHooksRandRScreenSetSize;
++
++ vncPostScreenResize(pScreen, ret);
++
++ if (!ret)
++ return FALSE;
++
++ return TRUE;
++}
++
++static Bool vncHooksRandRCrtcSet(ScreenPtr pScreen, RRCrtcPtr crtc,
++ RRModePtr mode, int x, int y,
++ Rotation rotation, int num_outputs,
++ RROutputPtr *outputs)
++{
++ vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen);
++ rrScrPrivPtr rp = rrGetScrPriv(pScreen);
++ Bool ret;
+
+- // Mark entire screen as changed
+- box.x1 = 0;
+- box.y1 = 0;
+- box.x2 = pScreen->width;
+- box.y2 = pScreen->height;
+- REGION_INIT(pScreen, &reg, &box, 1);
++ rp->rrCrtcSet = vncHooksScreen->RandRCrtcSet;
++ ret = (*rp->rrCrtcSet)(pScreen, crtc, mode, x, y, rotation,
++ num_outputs, outputs);
++ rp->rrCrtcSet = vncHooksRandRCrtcSet;
+
+- vncHooksScreen->desktop->add_changed(&reg);
++ if (!ret)
++ return FALSE;
++
++ vncHooksScreen->desktop->refreshScreenLayout();
+
+ return TRUE;
+ }
+@@ -667,7 +750,7 @@
+ };
+
+
+-// ValidateGC - wrap the "ops" if a viewable window
++// ValidateGC - wrap the "ops" if a viewable window OR the screen pixmap
+
+ static void vncHooksValidateGC(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDrawable)
+@@ -679,7 +762,9 @@
+ (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
+
+ u.vncHooksGC->wrappedOps = 0;
+- if (pDrawable->type == DRAWABLE_WINDOW && ((WindowPtr) pDrawable)->viewable) {
++ if ((pDrawable->type == DRAWABLE_WINDOW &&
++ ((WindowPtr) pDrawable)->viewable) ||
++ (pDrawable == &pGC->pScreen->GetScreenPixmap(pGC->pScreen)->drawable)) {
+ u.vncHooksGC->wrappedOps = pGC->ops;
+ DBGPRINT((stderr,"vncHooksValidateGC: wrapped GC ops\n"));
+ }
+@@ -750,7 +835,7 @@
+ DBGPRINT((stderr,"vncHooks" #name " called\n"));
+
+
+-// FillSpans - changed region is the whole of borderClip. This is pessimistic,
++// FillSpans - assume the entire clip region is damaged. This is pessimistic,
+ // but I believe this function is rarely used so it doesn't matter.
+
+ static void vncHooksFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit,
+@@ -759,14 +844,18 @@
+ {
+ GC_OP_UNWRAPPER(pDrawable, pGC, FillSpans);
+
+- RegionHelper changed(pScreen, &((WindowPtr)pDrawable)->borderClip);
++ RegionHelper changed(pScreen, pGC->pCompositeClip);
++
++ if (pDrawable->type == DRAWABLE_WINDOW)
++ REGION_INTERSECT(pScreen, changed.reg, changed.reg,
++ &((WindowPtr)pDrawable)->borderClip);
+
+ (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
+
+ vncHooksScreen->desktop->add_changed(changed.reg);
+ }
+
+-// SetSpans - changed region is the whole of borderClip. This is pessimistic,
++// SetSpans - assume the entire clip region is damaged. This is pessimistic,
+ // but I believe this function is rarely used so it doesn't matter.
+
+ static void vncHooksSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
+@@ -775,7 +864,11 @@
+ {
+ GC_OP_UNWRAPPER(pDrawable, pGC, SetSpans);
+
+- RegionHelper changed(pScreen, &((WindowPtr)pDrawable)->borderClip);
++ RegionHelper changed(pScreen, pGC->pCompositeClip);
++
++ if (pDrawable->type == DRAWABLE_WINDOW)
++ REGION_INTERSECT(pScreen, changed.reg, changed.reg,
++ &((WindowPtr)pDrawable)->borderClip);
+
+ (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
+
+@@ -827,16 +920,23 @@
+
+ RegionHelper src(pScreen);
+
+- if ((pSrc->type == DRAWABLE_WINDOW) && (pSrc->pScreen == pScreen)) {
++ // The source of the data has to be something that's on screen.
++ // This means either a window, or the screen pixmap.
++ if ((pSrc->pScreen == pScreen) &&
++ ((pSrc->type == DRAWABLE_WINDOW) ||
++ (pSrc == &pScreen->GetScreenPixmap(pScreen)->drawable))) {
+ box.x1 = srcx + pSrc->x;
+ box.y1 = srcy + pSrc->y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+
+ src.init(&box, 0);
+- if (REGION_NOTEMPTY(pScreen, &((WindowPtr)pSrc)->clipList)) {
+- REGION_INTERSECT(pScreen, src.reg, src.reg, &((WindowPtr)pSrc)->clipList);
++
++ if ((pSrc->type == DRAWABLE_WINDOW) &&
++ REGION_NOTEMPTY(pScreen, &((WindowPtr)pSrc)->clipList)) {
++ REGION_INTERSECT(pScreen, src.reg, src.reg, &((WindowPtr)pSrc)->clipList);
+ }
++
+ REGION_TRANSLATE(pScreen, src.reg,
+ dstx + pDst->x - srcx - pSrc->x,
+ dsty + pDst->y - srcy - pSrc->y);
+
+--- unix/xserver/hw/vnc/xf86vncModule.cc 2010-04-23 22:55:10.000000000 +0900
++++ unix/xserver/hw/vnc/xf86vncModule.cc 2013-05-27 18:54:41.207573000 +0900
+@@ -25,6 +25,10 @@
+ #include <rfb/Configuration.h>
+ #include <rfb/Logger_stdio.h>
+ #include <rfb/LogWriter.h>
++#include <rfb/ScreenSet.h>
++#include <rfb/screenTypes.h>
++
++#include "xorg-version.h"
+
+ extern "C" {
+ #define class c_class
+@@ -33,6 +37,9 @@
+ #define new c_new
+ #include "xf86.h"
+ #include "xf86Module.h"
++#ifdef RANDR
++#include "randrstr.h"
++#endif /* RANDR */
+ #undef class
+ #undef private
+ #undef bool
+@@ -89,7 +96,12 @@
+ ScrnInfoPtr pScrn = xf86Screens[scr];
+
+ for (ParameterIterator i(Configuration::global()); i.param; i.next()) {
+- char* val = xf86FindOptionValue(pScrn->options, i.param->getName());
++ const char *val;
++#if XORG < 112
++ val = xf86FindOptionValue(pScrn->options, i.param->getName());
++#else
++ val = xf86FindOptionValue((XF86OptionPtr)pScrn->options, i.param->getName());
++#endif
+ if (val)
+ i.param->setParam(val);
+ }
+@@ -98,3 +110,13 @@
+ vncExtensionInit();
+ }
+ }
++
++RRModePtr vncRandRModeGet(int width, int height)
++{
++ return NULL;
++}
++
++RROutputPtr vncRandROutputCreate(ScreenPtr pScreen)
++{
++ return NULL;
++}
+
+--- unix/xserver/hw/vnc/xorg-version.h 2010-12-09 01:05:48.000000000 +0900
++++ unix/xserver/hw/vnc/xorg-version.h 2013-05-27 18:54:41.193575000 +0900
+@@ -36,6 +36,10 @@
+ #define XORG 19
+ #elif XORG_VERSION_CURRENT < ((1 * 10000000) + (10 * 100000) + (99 * 1000))
+ #define XORG 110
++#elif XORG_VERSION_CURRENT < ((1 * 10000000) + (11 * 100000) + (99 * 1000))
++#define XORG 111
++#elif XORG_VERSION_CURRENT < ((1 * 10000000) + (12 * 100000) + (99 * 1000))
++#define XORG 112
+ #else
+ #error "X.Org newer than 1.10 is not supported"
+ #endif
+
+--- unix/xserver/hw/vnc/xvnc.cc 2012-03-10 05:34:29.000000000 +0900
++++ unix/xserver/hw/vnc/xvnc.cc 2013-05-27 18:54:41.182576000 +0900
+@@ -96,7 +96,7 @@
+ #define Xfree free
+ #endif
+
+-#define XVNCVERSION "TigerVNC 1.2.0"
++#define XVNCVERSION "TigerVNC 1.2.80"
+ #define XVNCCOPYRIGHT ("Copyright (C) 1999-2011 TigerVNC Team and many others (see README.txt)\n" \
+ "See http://www.tigervnc.org for information on TigerVNC.\n")
+
+@@ -229,7 +229,11 @@
+ }
+ #endif
+
++#if XORG < 111
+ void ddxGiveUp()
++#else
++void ddxGiveUp(enum ExitCode error)
++#endif
+ {
+ int i;
+
+@@ -239,9 +243,17 @@
+ }
+
+ void
++#if XORG < 111
+ AbortDDX()
++#else
++AbortDDX(enum ExitCode error)
++#endif
+ {
++#if XORG < 111
+ ddxGiveUp();
++#else
++ ddxGiveUp(error);
++#endif
+ }
+
+ #ifdef __DARWIN__
+@@ -686,8 +698,13 @@
+ {
+ if (pmap->mid != pmap->pScreen->defColormap)
+ {
++#if XORG < 111
+ curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
+ RT_COLORMAP);
++#else
++ dixLookupResourceByType((pointer *) &curpmap, pmap->pScreen->defColormap,
++ RT_COLORMAP, serverClient, DixUnknownAccess);
++#endif
+ (*pmap->pScreen->InstallColormap)(curpmap);
+ }
+ }
+@@ -859,45 +876,8 @@
+
+ static Bool vncRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+ {
+- Bool ret, gotCurrent = FALSE;
+- int i;
+-
+- const int widths[] = { 1920, 1920, 1600, 1680, 1400, 1360, 1280, 1280, 1280, 1280, 1024, 800, 640 };
+- const int heights[] = { 1200, 1080, 1200, 1050, 1050, 768, 1024, 960, 800, 720, 768, 600, 480 };
+-
+- for (i = 0;i < sizeof(widths)/sizeof(*widths);i++) {
+- RRScreenSizePtr pSize;
+-
+- pSize = RRRegisterSize(pScreen, widths[i], heights[i],
+- pScreen->mmWidth, pScreen->mmHeight);
+- if (!pSize)
+- return FALSE;
+-
+- ret = RRRegisterRate(pScreen, pSize, 60);
+- if (!ret)
+- return FALSE;
+-
+- if ((widths[i] == pScreen->width) && (heights[i] == pScreen->height)) {
+- RRSetCurrentConfig(pScreen, RR_Rotate_0, 60, pSize);
+- gotCurrent = TRUE;
+- }
+- }
+-
+- if (!gotCurrent) {
+- RRScreenSizePtr pSize;
+-
+- pSize = RRRegisterSize(pScreen, pScreen->width, pScreen->height,
+- pScreen->mmWidth, pScreen->mmHeight);
+- if (!pSize)
+- return FALSE;
+-
+- RRRegisterRate(pScreen, pSize, 60);
+-
+- RRSetCurrentConfig(pScreen, RR_Rotate_0, 60, pSize);
+- }
+-
+- *rotations = RR_Rotate_0;
+-
++ // We update all information right away, so there is nothing to
++ // do here.
+ return TRUE;
+ }
+
+@@ -1050,16 +1030,19 @@
+ FlushAllOutput ();
+ }
+
+-static Bool vncRandRSetConfig (ScreenPtr pScreen, Rotation rotation,
+- int rate, RRScreenSizePtr pSize)
++RRModePtr vncRandRModeGet(int width, int height);
++
++static Bool vncRandRScreenSetSize(ScreenPtr pScreen,
++ CARD16 width, CARD16 height,
++ CARD32 mmWidth, CARD32 mmHeight)
+ {
+ vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
+ vfbFramebufferInfo fb;
++ rrScrPrivPtr rp = rrGetScrPriv(pScreen);
+ PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ void *pbits;
+ Bool ret;
+ int oldwidth, oldheight, oldmmWidth, oldmmHeight;
+- int dpix, dpiy;
+
+ /* Prevent updates while we fiddle */
+ xf86SetRootClip(pScreen, FALSE);
+@@ -1070,17 +1053,11 @@
+ oldmmWidth = pScreen->mmWidth;
+ oldmmHeight = pScreen->mmHeight;
+
+- /* Compute the current DPI (for use later) */
+- dpix = (pScreen->width * 254 + pScreen->mmWidth * 5) / (pScreen->mmWidth * 10);
+- dpiy = (pScreen->height * 254 + pScreen->mmHeight * 5) / (pScreen->mmHeight * 10);
+-
+ /* Then set the new dimensions */
+- pScreen->width = pSize->width;
+- pScreen->height = pSize->height;
+-
+- /* Try to keep the same DPI as we do not have a physical screen */
+- pScreen->mmWidth = (pScreen->width * 254 + dpix * 5) / (dpix * 10);
+- pScreen->mmHeight = (pScreen->height * 254 + dpiy * 5) / (dpiy * 10);
++ pScreen->width = width;
++ pScreen->height = height;
++ pScreen->mmWidth = mmWidth;
++ pScreen->mmHeight = mmHeight;
+
+ /* Allocate a new framebuffer */
+ memset(&fb, 0, sizeof(vfbFramebufferInfo));
+@@ -1130,6 +1107,207 @@
+ /* Restore ability to update screen, now with new dimensions */
+ xf86SetRootClip(pScreen, TRUE);
+
++ /*
++ * Let RandR know we changed something (it doesn't assume that
++ * TRUE means something changed for some reason...).
++ */
++ RRScreenSizeNotify(pScreen);
++
++ /* Crop all CRTCs to the new screen */
++ for (int i = 0;i < rp->numCrtcs;i++) {
++ RRCrtcPtr crtc;
++ RRModePtr mode;
++
++ crtc = rp->crtcs[i];
++
++ /* Disabled? */
++ if (crtc->mode == NULL)
++ continue;
++
++ /* Fully inside? */
++ if ((crtc->x + crtc->mode->mode.width <= width) &&
++ (crtc->y + crtc->mode->mode.height <= height))
++ continue;
++
++ /* Fully outside? */
++ if ((crtc->x >= width) || (crtc->y >= height)) {
++ /* Disable it */
++ ret = RRCrtcNotify(crtc, NULL, crtc->x, crtc->y, crtc->rotation,
++#if XORG >= 16
++ NULL,
++#endif
++ crtc->numOutputs, crtc->outputs);
++ if (!ret)
++ ErrorF("Warning: Unable to disable CRTC that is outside of new screen dimensions");
++ continue;
++ }
++
++ /* Just needs to be resized */
++ mode = vncRandRModeGet(width - crtc->x, height - crtc->y);
++ if (mode == NULL) {
++ ErrorF("Warning: Unable to create custom mode for %dx%d",
++ width - crtc->x, height - crtc->y);
++ continue;
++ }
++
++ ret = RRCrtcNotify(crtc, mode, crtc->x, crtc->y, crtc->rotation,
++#if XORG >= 16
++ NULL,
++#endif
++ crtc->numOutputs, crtc->outputs);
++ RRModeDestroy(mode);
++ if (!ret)
++ ErrorF("Warning: Unable to crop CRTC to new screen dimensions");
++ }
++
++ return TRUE;
++}
++
++static Bool vncRandRCrtcSet(ScreenPtr pScreen, RRCrtcPtr crtc, RRModePtr mode,
++ int x, int y, Rotation rotation, int num_outputs,
++ RROutputPtr *outputs)
++{
++ Bool ret;
++
++ /* Let RandR know we approve, and let it update its internal state */
++ ret = RRCrtcNotify(crtc, mode, x, y, rotation,
++#if XORG >= 16
++ NULL,
++#endif
++ num_outputs, outputs);
++ if (!ret)
++ return FALSE;
++
++ return TRUE;
++}
++
++static Bool vncRandROutputValidateMode(ScreenPtr pScreen,
++ RROutputPtr output, RRModePtr mode)
++{
++ /* We have no hardware so any mode works */
++ return TRUE;
++}
++
++static void vncRandRModeDestroy(ScreenPtr pScreen, RRModePtr mode)
++{
++ /* We haven't allocated anything so nothing to destroy */
++}
++
++static const int vncRandRWidths[] = { 1920, 1920, 1600, 1680, 1400, 1360, 1280, 1280, 1280, 1280, 1024, 800, 640 };
++static const int vncRandRHeights[] = { 1200, 1080, 1200, 1050, 1050, 768, 1024, 960, 800, 720, 768, 600, 480 };
++
++static int vncRandRIndex = 0;
++
++/* This is a global symbol since XserverDesktop also uses it */
++RRModePtr vncRandRModeGet(int width, int height)
++{
++ xRRModeInfo modeInfo;
++ char name[100];
++ RRModePtr mode;
++
++ memset(&modeInfo, 0, sizeof(modeInfo));
++ sprintf(name, "%dx%d", width, height);
++
++ modeInfo.width = width;
++ modeInfo.height = height;
++ modeInfo.hTotal = width;
++ modeInfo.vTotal = height;
++ modeInfo.dotClock = ((CARD32)width * (CARD32)height * 60);
++ modeInfo.nameLength = strlen(name);
++ mode = RRModeGet(&modeInfo, name);
++ if (mode == NULL)
++ return NULL;
++
++ return mode;
++}
++
++static RRCrtcPtr vncRandRCrtcCreate(ScreenPtr pScreen)
++{
++ RRCrtcPtr crtc;
++ RROutputPtr output;
++ RRModePtr mode;
++ char name[100];
++
++ /* First we create the CRTC... */
++ crtc = RRCrtcCreate(pScreen, NULL);
++
++ /* We don't actually support gamma, but xrandr complains when it is missing */
++ RRCrtcGammaSetSize (crtc, 256);
++
++ /* Then we create a dummy output for it... */
++ sprintf(name, "VNC-%d", vncRandRIndex);
++ vncRandRIndex++;
++
++ output = RROutputCreate(pScreen, name, strlen(name), NULL);
++
++ RROutputSetCrtcs(output, &crtc, 1);
++ RROutputSetConnection(output, RR_Connected);
++
++ /* Make sure the CRTC has this output set */
++ RRCrtcNotify(crtc, NULL, 0, 0, RR_Rotate_0,
++#if XORG >= 16
++ NULL,
++#endif
++ 1, &output);
++
++ /* Populate a list of default modes */
++ RRModePtr modes[sizeof(vncRandRWidths)/sizeof(*vncRandRWidths)];
++ int num_modes;
++
++ num_modes = 0;
++ for (int i = 0;i < sizeof(vncRandRWidths)/sizeof(*vncRandRWidths);i++) {
++ mode = vncRandRModeGet(vncRandRWidths[i], vncRandRHeights[i]);
++ if (mode != NULL) {
++ modes[num_modes] = mode;
++ num_modes++;
++ }
++ }
++
++ RROutputSetModes(output, modes, num_modes, 0);
++
++ return crtc;
++}
++
++/* Used from XserverDesktop when it needs more outputs... */
++RROutputPtr vncRandROutputCreate(ScreenPtr pScreen)
++{
++ RRCrtcPtr crtc;
++
++ crtc = vncRandRCrtcCreate(pScreen);
++ if (crtc == NULL)
++ return NULL;
++
++ return crtc->outputs[0];
++}
++
++static Bool vncRandRInit(ScreenPtr pScreen)
++{
++ RRCrtcPtr crtc;
++ RRModePtr mode;
++
++ if (!RRInit())
++ return FALSE;
++
++ /* These are completely arbitrary */
++ RRScreenSetSizeRange(pScreen, 32, 32, 32768, 32768);
++
++ /*
++ * Start with a single CRTC with a single output. More will be
++ * allocated as needed...
++ */
++ crtc = vncRandRCrtcCreate(pScreen);
++
++ /* Make sure the current screen size is the active mode */
++ mode = vncRandRModeGet(pScreen->width, pScreen->height);
++ if (mode == NULL)
++ return FALSE;
++
++ RRCrtcNotify(crtc, mode, 0, 0, RR_Rotate_0,
++#if XORG >= 16
++ NULL,
++#endif
++ crtc->numOutputs, crtc->outputs);
++
+ return TRUE;
+ }
+
+@@ -1291,8 +1469,16 @@
+ if (!ret) return FALSE;
+
+ rp = rrGetScrPriv(pScreen);
++
+ rp->rrGetInfo = vncRandRGetInfo;
+- rp->rrSetConfig = vncRandRSetConfig;
++ rp->rrSetConfig = NULL;
++ rp->rrScreenSetSize = vncRandRScreenSetSize;
++ rp->rrCrtcSet = vncRandRCrtcSet;
++ rp->rrOutputValidateMode = vncRandROutputValidateMode;
++ rp->rrModeDestroy = vncRandRModeDestroy;
++
++ ret = vncRandRInit(pScreen);
++ if (!ret) return FALSE;
+ #endif
+
+
diff --git a/net/tigervnc/files/xserver112.patch b/net/tigervnc/files/xserver112.patch
new file mode 100644
index 000000000000..712889cead74
--- /dev/null
+++ b/net/tigervnc/files/xserver112.patch
@@ -0,0 +1,91 @@
+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 TIGERVNC
++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 TIGERVNC
++ vncExtensionInit();
++#endif
+ #if !defined(NO_HW_ONLY_EXTS)
+ #if defined(XF86VIDMODE)
+ if (!noXFree86VidModeExtension)