diff options
author | Steve Wills <swills@FreeBSD.org> | 2013-05-29 16:29:40 +0000 |
---|---|---|
committer | Steve Wills <swills@FreeBSD.org> | 2013-05-29 16:29:40 +0000 |
commit | 863d70a0517d160bd8607a5175c50f537b89def0 (patch) | |
tree | e6bdde55254231c23845543ff1e8bb74159943f5 /net/tigervnc | |
parent | 7324889637956b06137824641e60773425fb1e53 (diff) | |
download | ports-863d70a0517d160bd8607a5175c50f537b89def0.tar.gz ports-863d70a0517d160bd8607a5175c50f537b89def0.zip |
Notes
Diffstat (limited to 'net/tigervnc')
-rw-r--r-- | net/tigervnc/Makefile | 16 | ||||
-rw-r--r-- | net/tigervnc/files/extra-patch-common_rdr.patch | 214 | ||||
-rw-r--r-- | net/tigervnc/files/extra-patch-common_rfb.patch | 259 | ||||
-rw-r--r-- | net/tigervnc/files/extra-patch-unix_hw_vnc.patch | 1806 | ||||
-rw-r--r-- | net/tigervnc/files/xserver112.patch | 91 |
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, ®, &box, 1); ++ ++ vncHooksScreen->desktop->add_changed(®); ++ } ++} ++ + 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, ®, &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(®); ++ 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) |