diff --git a/.gitignore b/.gitignore
index 473d203..d48d90b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/tigervnc-1.10.1.tar.gz
+SOURCES/tigervnc-1.11.0.tar.gz
diff --git a/.tigervnc.metadata b/.tigervnc.metadata
index 957f8a1..c7c0b3c 100644
--- a/.tigervnc.metadata
+++ b/.tigervnc.metadata
@@ -1 +1 @@
-34efc6e2e67be672dca38c10ce064bcb08adee9f SOURCES/tigervnc-1.10.1.tar.gz
+6f6b621a76b734888748de10c32c2b5b59d40b19 SOURCES/tigervnc-1.11.0.tar.gz
diff --git a/SOURCES/0001-rpath-hack.patch b/SOURCES/0001-rpath-hack.patch
index 689de34..4e438dd 100644
--- a/SOURCES/0001-rpath-hack.patch
+++ b/SOURCES/0001-rpath-hack.patch
@@ -15,14 +15,10 @@ diff --git a/configure.ac b/configure.ac
 index fa15a2d..a5af1e0 100644
 --- a/configure.ac
 +++ b/configure.ac
-@@ -1357,6 +1357,7 @@ else
- fi
- AM_CONDITIONAL(GLX, test "x$GLX" = xyes)
-
+@@ -1261,6 +1261,7 @@ AM_CONDITIONAL(GLX, test "x$GLX" = xyes)
+ 
+ AM_CONDITIONAL(HASHTABLE, test "x$HASHTABLE" = xyes)
+ 
 +GLX_SYS_LIBS="$GLX_SYS_LIBS -Wl,-rpath=\$(libdir)"
  AC_SUBST([GLX_DEFINES])
  AC_SUBST([GLX_SYS_LIBS])
-
---
-2.5.0
-
diff --git a/SOURCES/0001-xserver-add-no-op-input-thread-init-function.patch b/SOURCES/0001-xserver-add-no-op-input-thread-init-function.patch
deleted file mode 100644
index b67127b..0000000
--- a/SOURCES/0001-xserver-add-no-op-input-thread-init-function.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 920d9c4d6562ecabf79497bc901d50522d4bc661 Mon Sep 17 00:00:00 2001
-From: Linus Heckemann <git@sphalerite.org>
-Date: Sat, 1 Feb 2020 11:08:26 +0100
-Subject: [PATCH] xserver: add no-op input thread init function
-
-This allows Xvnc to build with xorg-server 1.20.7, which requires OS
-layers to implement a ddxInputThreadInit function when configured with
---enable-input-thread (the default).
-
-relevant xorg-server commit: e3f26605d85d987da434640f52646d728f1fe919
----
- unix/xserver/hw/vnc/Input.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
-diff --git a/unix/xserver/hw/vnc/Input.c b/unix/xserver/hw/vnc/Input.c
-index 534e435e..b342d4d6 100644
---- a/unix/xserver/hw/vnc/Input.c
-+++ b/unix/xserver/hw/vnc/Input.c
-@@ -711,3 +711,12 @@ static void vncKeysymKeyboardEvent(KeySym keysym, int down)
- 	 */
- 	mieqProcessInputEvents();
- }
-+
-+#if INPUTTHREAD
-+/** This function is called in Xserver/os/inputthread.c when starting
-+    the input thread. */
-+void
-+ddxInputThreadInit(void)
-+{
-+}
-+#endif
--- 
-2.24.1
-
diff --git a/SOURCES/HOWTO.md b/SOURCES/HOWTO.md
index d9a6308..28b710d 100644
--- a/SOURCES/HOWTO.md
+++ b/SOURCES/HOWTO.md
@@ -25,9 +25,6 @@ For example you can have
 :2=vncuser
 ```
 
-### Note:
-Make sure you don't leave a space character after the username. 
-
 ## Configure Xvnc options
 To configure Xvnc parameters, you need to go to the same directory where you did
 the user mapping and open `vncserver-config-defaults` configuration file. This 
diff --git a/SOURCES/tigervnc-correctly-start-vncsession-as-daemon.patch b/SOURCES/tigervnc-correctly-start-vncsession-as-daemon.patch
new file mode 100644
index 0000000..af5e7f2
--- /dev/null
+++ b/SOURCES/tigervnc-correctly-start-vncsession-as-daemon.patch
@@ -0,0 +1,13 @@
+diff --git a/unix/vncserver/vncsession.c b/unix/vncserver/vncsession.c
+index 2b47f5f5..f78c096f 100644
+--- a/unix/vncserver/vncsession.c
++++ b/unix/vncserver/vncsession.c
+@@ -99,7 +99,7 @@ begin_daemon(void)
+         return -1;
+     }
+ 
+-    if (pid == 0)
++    if (pid != 0)
+         _exit(0);
+ 
+     /* Send all stdio to /dev/null */
diff --git a/SOURCES/tigervnc-provide-correct-dimensions-for-xshm-setup.patch b/SOURCES/tigervnc-provide-correct-dimensions-for-xshm-setup.patch
deleted file mode 100644
index cefc769..0000000
--- a/SOURCES/tigervnc-provide-correct-dimensions-for-xshm-setup.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 0f1ded057dbf875e69a0d72418d95610db8fa6a3 Mon Sep 17 00:00:00 2001
-From: Pierre Ossman <ossman@cendio.se>
-Date: Mon, 30 Dec 2019 10:50:52 +0100
-Subject: [PATCH] Provide correct dimensions for XShm setup
-
-Since 53f913a we initialize the underlying PixelBuffer with 0x0
-dimensions, which means we need to keep more explicit track of what
-we are trying to allocate in the setup methods.
----
- vncviewer/PlatformPixelBuffer.cxx | 6 +++---
- vncviewer/PlatformPixelBuffer.h   | 2 +-
- 2 files changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/vncviewer/PlatformPixelBuffer.cxx b/vncviewer/PlatformPixelBuffer.cxx
-index 61f7b743b..59e51d596 100644
---- a/vncviewer/PlatformPixelBuffer.cxx
-+++ b/vncviewer/PlatformPixelBuffer.cxx
-@@ -43,7 +43,7 @@ PlatformPixelBuffer::PlatformPixelBuffer(int width, int height) :
- #endif
- {
- #if !defined(WIN32) && !defined(__APPLE__)
--  if (!setupShm()) {
-+  if (!setupShm(width, height)) {
-     xim = XCreateImage(fl_display, CopyFromParent, 32,
-                        ZPixmap, 0, 0, width, height, 32, 0);
-     if (!xim)
-@@ -136,7 +136,7 @@ static int XShmAttachErrorHandler(Display *dpy, XErrorEvent *error)
-   return 0;
- }
- 
--bool PlatformPixelBuffer::setupShm()
-+bool PlatformPixelBuffer::setupShm(int width, int height)
- {
-   int major, minor;
-   Bool pixmaps;
-@@ -153,7 +153,7 @@ bool PlatformPixelBuffer::setupShm()
-   shminfo = new XShmSegmentInfo;
- 
-   xim = XShmCreateImage(fl_display, CopyFromParent, 32,
--                        ZPixmap, 0, shminfo, width(), height());
-+                        ZPixmap, 0, shminfo, width, height);
-   if (!xim)
-     goto free_shminfo;
- 
-diff --git a/vncviewer/PlatformPixelBuffer.h b/vncviewer/PlatformPixelBuffer.h
-index f9038cd9c..ec439f64f 100644
---- a/vncviewer/PlatformPixelBuffer.h
-+++ b/vncviewer/PlatformPixelBuffer.h
-@@ -53,7 +53,7 @@ class PlatformPixelBuffer: public rfb::FullFramePixelBuffer, public Surface {
- 
- #if !defined(WIN32) && !defined(__APPLE__)
- protected:
--  bool setupShm();
-+  bool setupShm(int width, int height);
- 
- protected:
-   XShmSegmentInfo *shminfo;
diff --git a/SOURCES/tigervnc-systemd-service.patch b/SOURCES/tigervnc-systemd-service.patch
new file mode 100644
index 0000000..846a34b
--- /dev/null
+++ b/SOURCES/tigervnc-systemd-service.patch
@@ -0,0 +1,47 @@
+From 40f104ffe1e36df9613f8d316f616fb2b089cc86 Mon Sep 17 00:00:00 2001
+From: Jan Grulich <jgrulich@redhat.com>
+Date: Tue, 29 Sep 2020 13:37:16 +0200
+Subject: [PATCH] Use /run instead of /var/run which is just a symlink
+
+---
+ unix/vncserver/selinux/vncsession.fc | 2 +-
+ unix/vncserver/vncserver@.service.in | 2 +-
+ unix/vncserver/vncsession.c          | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/unix/vncserver/selinux/vncsession.fc b/unix/vncserver/selinux/vncsession.fc
+index 121cdd237..ae768baa4 100644
+--- a/unix/vncserver/selinux/vncsession.fc
++++ b/unix/vncserver/selinux/vncsession.fc
+@@ -23,4 +23,4 @@ HOME_ROOT/\.vnc(/.*)?      gen_context(system_u:object_r:xdm_home_t,s0)
+ /usr/sbin/vncsession			--	gen_context(system_u:object_r:vnc_session_exec_t,s0)
+ /usr/libexec/vncsession-start		--	gen_context(system_u:object_r:vnc_session_exec_t,s0)
+ 
+-/var/run/vncsession-:[0-9]*\.pid	--      gen_context(system_u:object_r:vnc_session_var_run_t,s0)
++/run/vncsession-:[0-9]*\.pid	--      gen_context(system_u:object_r:vnc_session_var_run_t,s0)
+diff --git a/unix/vncserver/vncserver@.service.in b/unix/vncserver/vncserver@.service.in
+index 584ecf4b1..5624dff76 100644
+--- a/unix/vncserver/vncserver@.service.in
++++ b/unix/vncserver/vncserver@.service.in
+@@ -36,7 +36,7 @@ After=syslog.target network.target
+ [Service]
+ Type=forking
+ ExecStart=@CMAKE_INSTALL_FULL_LIBEXECDIR@/vncsession-start %i
+-PIDFile=/var/run/vncsession-%i.pid
++PIDFile=/run/vncsession-%i.pid
+ SELinuxContext=system_u:system_r:vnc_session_t:s0
+ 
+ [Install]
+diff --git a/unix/vncserver/vncsession.c b/unix/vncserver/vncsession.c
+index 3e0c98f0f..2b47f5f55 100644
+--- a/unix/vncserver/vncsession.c
++++ b/unix/vncserver/vncsession.c
+@@ -543,7 +543,7 @@ main(int argc, char **argv)
+     }
+ 
+     snprintf(pid_file, sizeof(pid_file),
+-             "/var/run/vncsession-%s.pid", display);
++             "/run/vncsession-%s.pid", display);
+     f = fopen(pid_file, "w");
+     if (f == NULL) {
+         syslog(LOG_ERR, "Failure creating pid file \"%s\": %s",
diff --git a/SOURCES/tigervnc-systemd-support.patch b/SOURCES/tigervnc-systemd-support.patch
deleted file mode 100644
index 3b56cd8..0000000
--- a/SOURCES/tigervnc-systemd-support.patch
+++ /dev/null
@@ -1,2176 +0,0 @@
-From 8f09de712b53e54d15d2bd5367c10a61c57cda23 Mon Sep 17 00:00:00 2001
-From: Jan Grulich <jgrulich@redhat.com>
-Date: Wed, 6 May 2020 10:37:21 +0200
-Subject: Foo
-
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 2d19b72..78eb93d 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -7,6 +7,10 @@ if(POLICY CMP0022)
-   cmake_policy(SET CMP0022 OLD)
- endif()
- 
-+if(${CMAKE_VERSION} VERSION_LESS "3.4.0")
-+  message(WARNING "CMake 3.4.0 or newer is required to get correct default installation paths")
-+endif()
-+
- # Internal cmake modules
- set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
- 
-@@ -27,17 +31,16 @@ set(VERSION 1.10.1)
- set(RCVERSION 1,10,1,0)
- 
- # Installation paths
--set(BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin")
--set(DATA_DIR "${CMAKE_INSTALL_PREFIX}/share")
--set(MAN_DIR "${DATA_DIR}/man")
--set(LOCALE_DIR "${DATA_DIR}/locale")
--set(DOC_DIR "${CMAKE_INSTALL_PREFIX}/share/doc/${CMAKE_PROJECT_NAME}-${VERSION}")
--
--if(WIN32)
--set(BIN_DIR "${CMAKE_INSTALL_PREFIX}")
--set(DOC_DIR "${CMAKE_INSTALL_PREFIX}")
-+include(GNUInstallDirs)
-+set(CMAKE_INSTALL_UNITDIR "lib/systemd/system" CACHE PATH "systemd unit files (lib/systemd/system)")
-+if(IS_ABSOLUTE "${CMAKE_INSTALL_UNITDIR}")
-+  set(CMAKE_INSTALL_FULL_UNITDIR "${CMAKE_INSTALL_UNITDIR}")
-+else()
-+  set(CMAKE_INSTALL_FULL_UNITDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_UNITDIR}")
- endif()
- 
-+option(INSTALL_SYSTEMD_UNITS "Install TigerVNC systemd units" ON)
-+
- if(MSVC)
-   message(FATAL_ERROR "TigerVNC cannot be built with Visual Studio.  Please use MinGW")
- endif()
-@@ -259,8 +262,7 @@ if(ENABLE_GNUTLS)
- endif()
- 
- # Check for PAM library
--option(ENABLE_PAM "Enable PAM authentication support" ON)
--if(ENABLE_PAM)
-+if(UNIX AND NOT APPLE)
-   check_include_files(security/pam_appl.h HAVE_PAM_H)
-   set(CMAKE_REQUIRED_LIBRARIES -lpam)
-   check_function_exists(pam_start HAVE_PAM_START)
-@@ -268,10 +270,9 @@ if(ENABLE_PAM)
-   if(HAVE_PAM_H AND HAVE_PAM_START)
-     set(PAM_LIBS pam)
-   else()
--    set(ENABLE_PAM 0)
-+    message(FATAL_ERROR "Could not find PAM development files")
-   endif()
- endif()
--set(HAVE_PAM ${ENABLE_PAM})
- 
- # Generate config.h and make sure the source finds it
- configure_file(config.h.in config.h)
-diff --git a/cmake/BuildPackages.cmake b/cmake/BuildPackages.cmake
-index ec96318..1f25192 100644
---- a/cmake/BuildPackages.cmake
-+++ b/cmake/BuildPackages.cmake
-@@ -86,5 +86,5 @@ endif() #UNIX
- # Common
- #
- 
--install(FILES ${CMAKE_SOURCE_DIR}/LICENCE.TXT DESTINATION ${DOC_DIR})
--install(FILES ${CMAKE_SOURCE_DIR}/README.rst DESTINATION ${DOC_DIR})
-+install(FILES ${CMAKE_SOURCE_DIR}/LICENCE.TXT DESTINATION ${CMAKE_INSTALL_FULL_DOCDIR})
-+install(FILES ${CMAKE_SOURCE_DIR}/README.rst DESTINATION ${CMAKE_INSTALL_FULL_DOCDIR})
-diff --git a/cmake/StaticBuild.cmake b/cmake/StaticBuild.cmake
-index e539619..793b190 100644
---- a/cmake/StaticBuild.cmake
-+++ b/cmake/StaticBuild.cmake
-@@ -115,7 +115,7 @@ endif()
- if(BUILD_STATIC_GCC)
-   # This ensures that we don't depend on libstdc++ or libgcc_s
-   set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nodefaultlibs")
--  set(STATIC_BASE_LIBRARIES "-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic")
-+  set(STATIC_BASE_LIBRARIES "")
-   if(ENABLE_ASAN AND NOT WIN32 AND NOT APPLE)
-     set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -Wl,-Bstatic -lasan -Wl,-Bdynamic -ldl -lm -lpthread")
-   endif()
-@@ -135,5 +135,6 @@ if(BUILD_STATIC_GCC)
-   else()
-     set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -lgcc -lgcc_eh -lc")
-   endif()
--  set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} ${STATIC_BASE_LIBRARIES}")
-+  set(CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE} ${STATIC_BASE_LIBRARIES}")
-+  set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic ${STATIC_BASE_LIBRARIES}")
- endif()
-diff --git a/common/rfb/CMakeLists.txt b/common/rfb/CMakeLists.txt
-index 8e532a2..689cdcc 100644
---- a/common/rfb/CMakeLists.txt
-+++ b/common/rfb/CMakeLists.txt
-@@ -75,7 +75,7 @@ endif(WIN32)
- 
- set(RFB_LIBRARIES ${JPEG_LIBRARIES} os rdr Xregion)
- 
--if(HAVE_PAM)
-+if(UNIX AND NOT APPLE)
-   set(RFB_SOURCES ${RFB_SOURCES} UnixPasswordValidator.cxx
-     UnixPasswordValidator.h pam.c pam.h)
-   set(RFB_LIBRARIES ${RFB_LIBRARIES} ${PAM_LIBS})
-diff --git a/common/rfb/SSecurityPlain.cxx b/common/rfb/SSecurityPlain.cxx
-index 6f72432..f577c0d 100644
---- a/common/rfb/SSecurityPlain.cxx
-+++ b/common/rfb/SSecurityPlain.cxx
-@@ -25,10 +25,10 @@
- #include <rfb/SConnection.h>
- #include <rfb/Exception.h>
- #include <rdr/InStream.h>
--#ifdef HAVE_PAM
-+#if !defined(WIN32) && !defined(__APPLE__)
- #include <rfb/UnixPasswordValidator.h>
- #endif
--#ifdef BUILD_WIN
-+#ifdef WIN32
- #include <rfb/WinPasswdValidator.h>
- #endif
- 
-@@ -62,10 +62,10 @@ bool PasswordValidator::validUser(const char* username)
- 
- SSecurityPlain::SSecurityPlain(SConnection* sc) : SSecurity(sc)
- {
--#ifdef HAVE_PAM
--  valid = new UnixPasswordValidator();
--#elif BUILD_WIN
-+#ifdef WIN32
-   valid = new WinPasswdValidator();
-+#elif !defined(__APPLE__)
-+  valid = new UnixPasswordValidator();
- #else
-   valid = NULL;
- #endif
-diff --git a/common/rfb/UnixPasswordValidator.cxx b/common/rfb/UnixPasswordValidator.cxx
-index d096079..ee7bc0d 100644
---- a/common/rfb/UnixPasswordValidator.cxx
-+++ b/common/rfb/UnixPasswordValidator.cxx
-@@ -25,9 +25,7 @@
- #include <rfb/Configuration.h>
- #include <rfb/Exception.h>
- #include <rfb/UnixPasswordValidator.h>
--#ifdef HAVE_PAM
- #include <rfb/pam.h>
--#endif
- 
- using namespace rfb;
- 
-@@ -43,10 +41,6 @@ bool UnixPasswordValidator::validateInternal(SConnection * sc,
- 					     const char *username,
- 					     const char *password)
- {
--#ifdef HAVE_PAM
-   CharArray service(strDup(pamService.getData()));
-   return do_pam_auth(service.buf, username, password);
--#else
--  throw AuthFailureException("PAM not supported");
--#endif
- }
-diff --git a/common/rfb/pam.c b/common/rfb/pam.c
-index cb067fd..acac0f4 100644
---- a/common/rfb/pam.c
-+++ b/common/rfb/pam.c
-@@ -22,9 +22,6 @@
- #include <config.h>
- #endif
- 
--#ifndef HAVE_PAM
--#error "This source should not be compiled when PAM is unsupported"
--#endif
- 
- #include <stdlib.h>
- #include <string.h>
-diff --git a/common/rfb/pam.h b/common/rfb/pam.h
-index 2688f21..d378d19 100644
---- a/common/rfb/pam.h
-+++ b/common/rfb/pam.h
-@@ -21,14 +21,6 @@
- #ifndef __RFB_PAM_H__
- #define __RFB_PAM_H__
- 
--#ifdef HAVE_CONFIG_H
--#include <config.h>
--#endif
--
--#ifndef HAVE_PAM
--#error "This header should not be included when PAM is unsupported"
--#endif
--
- #ifdef __cplusplus
- extern "C" {
- #endif
-diff --git a/config.h.in b/config.h.in
-index 2d6db9c..2d7a741 100644
---- a/config.h.in
-+++ b/config.h.in
-@@ -4,10 +4,10 @@
- #cmakedefine HAVE_ACTIVE_DESKTOP_H
- #cmakedefine HAVE_ACTIVE_DESKTOP_L
- #cmakedefine ENABLE_NLS 1
--#cmakedefine HAVE_PAM
- 
--#cmakedefine DATA_DIR "@DATA_DIR@"
--#cmakedefine LOCALE_DIR "@LOCALE_DIR@"
-+#cmakedefine CMAKE_INSTALL_FULL_LIBEXECDIR "@CMAKE_INSTALL_FULL_LIBEXECDIR@"
-+#cmakedefine CMAKE_INSTALL_FULL_DATADIR "@CMAKE_INSTALL_FULL_DATADIR@"
-+#cmakedefine CMAKE_INSTALL_FULL_LOCALEDIR "@CMAKE_INSTALL_FULL_LOCALEDIR@"
- 
- /* MS Visual Studio 2008 and newer doesn't know ssize_t */
- #if defined(HAVE_GNUTLS) && defined(WIN32) && !defined(__MINGW32__)
-diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt
-index f61e355..77ec21b 100644
---- a/java/CMakeLists.txt
-+++ b/java/CMakeLists.txt
-@@ -7,8 +7,6 @@ endif()
- 
- find_package(Java)
- 
--set(DATA_DIR "${CMAKE_INSTALL_PREFIX}/share")
--
- set(DEFAULT_JAVACFLAGS "-source 8 -target 8 -encoding UTF-8 -Xlint:all,-serial,-cast,-unchecked,-fallthrough,-dep-ann,-deprecation,-rawtypes")
- set(JAVACFLAGS ${DEFAULT_JAVACFLAGS} CACHE STRING
-   "Java compiler flags (Default: ${DEFAULT_JAVACFLAGS})")
-diff --git a/media/CMakeLists.txt b/media/CMakeLists.txt
-index 256d435..088c72f 100644
---- a/media/CMakeLists.txt
-+++ b/media/CMakeLists.txt
-@@ -13,11 +13,11 @@ if(CONVERT_EXECUTABLE)
-   if(UNIX AND NOT APPLE)
-     foreach(SIZE 16 22 24 32 48)
-       install(FILES icons/tigervnc_${SIZE}.png
--        DESTINATION ${DATA_DIR}/icons/hicolor/${SIZE}x${SIZE}/apps
-+        DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/${SIZE}x${SIZE}/apps
-         RENAME tigervnc.png)
-     endforeach()
-     install(FILES icons/tigervnc.svg
--      DESTINATION ${DATA_DIR}/icons/hicolor/scalable/apps)
-+      DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/scalable/apps)
-   endif()
- endif()
- 
-diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt
-index 9c8ddef..2eb10e7 100644
---- a/po/CMakeLists.txt
-+++ b/po/CMakeLists.txt
-@@ -46,7 +46,7 @@ foreach(lang ${po_FILES})
-   )
- 
-   install(FILES ${mo}
--    DESTINATION "${LOCALE_DIR}/${lang}/LC_MESSAGES"
-+    DESTINATION "${CMAKE_INSTALL_FULL_LOCALEDIR}/${lang}/LC_MESSAGES"
-     RENAME tigervnc.mo
-   )
- 
-diff --git a/unix/CMakeLists.txt b/unix/CMakeLists.txt
-index 7a1457d..5456e00 100644
---- a/unix/CMakeLists.txt
-+++ b/unix/CMakeLists.txt
-@@ -2,7 +2,5 @@ add_subdirectory(tx)
- add_subdirectory(common)
- add_subdirectory(vncconfig)
- add_subdirectory(vncpasswd)
-+add_subdirectory(vncserver)
- add_subdirectory(x0vncserver)
--
--install(PROGRAMS vncserver DESTINATION ${BIN_DIR})
--install(FILES vncserver.man DESTINATION ${MAN_DIR}/man1 RENAME vncserver.1)
-diff --git a/unix/vncconfig/CMakeLists.txt b/unix/vncconfig/CMakeLists.txt
-index 959681f..c3823ab 100644
---- a/unix/vncconfig/CMakeLists.txt
-+++ b/unix/vncconfig/CMakeLists.txt
-@@ -11,5 +11,5 @@ add_executable(vncconfig
- 
- target_link_libraries(vncconfig tx rfb network rdr ${X11_LIBRARIES})
- 
--install(TARGETS vncconfig DESTINATION ${BIN_DIR})
--install(FILES vncconfig.man DESTINATION ${MAN_DIR}/man1 RENAME vncconfig.1)
-+install(TARGETS vncconfig DESTINATION ${CMAKE_INSTALL_FULL_BINDIR})
-+install(FILES vncconfig.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man1 RENAME vncconfig.1)
-diff --git a/unix/vncconfig/vncconfig.man b/unix/vncconfig/vncconfig.man
-index b685a46..ed9ddda 100644
---- a/unix/vncconfig/vncconfig.man
-+++ b/unix/vncconfig/vncconfig.man
-@@ -111,8 +111,8 @@ When run as a "helper" app, make the window iconified at startup.
- .SH SEE ALSO
- .BR vncpasswd (1),
- .BR vncviewer (1),
--.BR vncserver (1),
--.BR Xvnc (1)
-+.BR Xvnc (1),
-+.BR vncsession (8)
- .br
- https://www.tigervnc.org
- 
-diff --git a/unix/vncpasswd/CMakeLists.txt b/unix/vncpasswd/CMakeLists.txt
-index a04ed0b..9f716fa 100644
---- a/unix/vncpasswd/CMakeLists.txt
-+++ b/unix/vncpasswd/CMakeLists.txt
-@@ -5,5 +5,5 @@ add_executable(vncpasswd
- 
- target_link_libraries(vncpasswd tx rfb os)
- 
--install(TARGETS vncpasswd DESTINATION ${BIN_DIR})
--install(FILES vncpasswd.man DESTINATION ${MAN_DIR}/man1 RENAME vncpasswd.1)
-+install(TARGETS vncpasswd DESTINATION ${CMAKE_INSTALL_FULL_BINDIR})
-+install(FILES vncpasswd.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man1 RENAME vncpasswd.1)
-diff --git a/unix/vncpasswd/vncpasswd.man b/unix/vncpasswd/vncpasswd.man
-index 9e68181..c70a425 100644
---- a/unix/vncpasswd/vncpasswd.man
-+++ b/unix/vncpasswd/vncpasswd.man
-@@ -43,9 +43,9 @@ Default location of the VNC password file.
- 
- .SH SEE ALSO
- .BR vncviewer (1),
--.BR vncserver (1),
- .BR Xvnc (1)
- .BR vncconfig (1),
-+.BR vncsession (8)
- .br
- https://www.tigervnc.org
- 
-diff --git a/unix/vncserver.man b/unix/vncserver.man
-deleted file mode 100644
-index 95f7960..0000000
---- a/unix/vncserver.man
-+++ /dev/null
-@@ -1,204 +0,0 @@
--.TH vncserver 1 "" "TigerVNC" "Virtual Network Computing"
--.SH NAME
--vncserver \- start or stop a VNC server
--.SH SYNOPSIS
--.B vncserver
--.RI [: display# ]
--.RB [ \-name
--.IR desktop-name ]
--.RB [ \-geometry
--.IR width x height ]
--.RB [ \-depth
--.IR depth ]
--.RB [ \-pixelformat
--.IR format ]
--.RB [ \-fp
--.IR font-path ]
--.RB [ \-fg ]
--.RB [ \-autokill ]
--.RB [ \-noxstartup ]
--.RB [ \-xstartup 
--.IR script ]
--.RI [ Xvnc-options... ]
--.br
--.BI "vncserver \-kill :" display#
--.br
--.BI "vncserver \-list"
--.SH DESCRIPTION
--.B vncserver
--is used to start a VNC (Virtual Network Computing) desktop.
--.B vncserver
--is a Perl script which simplifies the process of starting an Xvnc server.  It
--runs Xvnc with appropriate options and starts a window manager on the VNC
--desktop.
--
--.B vncserver
--can be run with no options at all. In this case it will choose the first
--available display number (usually :1), start Xvnc with that display number,
--and start the default window manager in the Xvnc session.  You can also
--specify the display number, in which case vncserver will attempt to start
--Xvnc with that display number and exit if the display number is not
--available.  For example:
--
--.RS
--vncserver :13
--.RE
--
--Editing the file $HOME/.vnc/xstartup allows you to change the applications run
--at startup (but note that this will not affect an existing VNC session.)
--
--.SH OPTIONS
--You can get a list of options by passing \fB\-h\fP as an option to vncserver.
--In addition to the options listed below, any unrecognised options will be
--passed to Xvnc - see the Xvnc man page, or "Xvnc \-help", for details.
--
--.TP
--.B \-name \fIdesktop-name\fP
--Each VNC desktop has a name which may be displayed by the viewer. The desktop
--name defaults to "\fIhost\fP:\fIdisplay#\fP (\fIusername\fP)", but you can
--change it with this option.  The desktop name option is passed to the xstartup
--script via the $VNCDESKTOP environment variable, which allows you to run a
--different set of applications depending on the name of the desktop.
--.
--.TP
--.B \-geometry \fIwidth\fPx\fIheight\fP
--Specify the size of the VNC desktop to be created. Default is 1024x768. 
--.
--.TP
--.B \-depth \fIdepth\fP
--Specify the pixel depth (in bits) of the VNC desktop to be created. Default is
--24.  Other possible values are 8, 15 and 16 - anything else is likely to cause
--strange behaviour by applications.
--.
--.TP
--.B \-pixelformat \fIformat\fP
--Specify pixel format for Xvnc to use (BGRnnn or RGBnnn).  The default for
--depth 8 is BGR233 (meaning the most significant two bits represent blue, the
--next three green, and the least significant three represent red), the default
--for depth 16 is RGB565, and the default for depth 24 is RGB888.
--.
--.TP
--.B \-cc 3
--As an alternative to the default TrueColor visual, this allows you to run an
--Xvnc server with a PseudoColor visual (i.e. one which uses a color map or
--palette), which can be useful for running some old X applications which only
--work on such a display.  Values other than 3 (PseudoColor) and 4 (TrueColor)
--for the \-cc option may result in strange behaviour, and PseudoColor desktops
--must have an 8-bit depth.
--.
--.TP
--.B \-kill :\fIdisplay#\fP
--This kills a VNC desktop previously started with vncserver.  It does this by
--killing the Xvnc process, whose process ID is stored in the file
--"$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.pid".  The
--.B \-kill
--option ignores anything preceding the first colon (":") in the display
--argument.  Thus, you can invoke "vncserver \-kill $DISPLAY", for example at the
--end of your xstartup file after a particular application exits.
--.
--.TP
--.B \-fp \fIfont-path\fP
--If the vncserver script detects that the X Font Server (XFS) is running, it
--will attempt to start Xvnc and configure Xvnc to use XFS for font handling.
--Otherwise, if XFS is not running, the vncserver script will attempt to start
--Xvnc and allow Xvnc to use its own preferred method of font handling (which may
--be a hard-coded font path or, on more recent systems, a font catalog.)  In
--any case, if Xvnc fails to start, the vncserver script will then attempt to
--determine an appropriate X font path for this system and start Xvnc using
--that font path.
--
--The
--.B \-fp
--argument allows you to override the above fallback logic and specify a font
--path for Xvnc to use.
--.
--.TP
--.B \-fg
--Runs Xvnc as a foreground process.  This has two effects: (1) The VNC server
--can be aborted with CTRL-C, and (2) the VNC server will exit as soon as the
--user logs out of the window manager in the VNC session.  This may be necessary
--when launching TigerVNC from within certain grid computing environments.
--.
--.TP
--.B \-autokill
--Automatically kill Xvnc whenever the xstartup script exits.  In most cases,
--this has the effect of terminating Xvnc when the user logs out of the window
--manager.
--.
--.TP
--.B \-noxstartup
--Do not run the %HOME/.vnc/xstartup script after launching Xvnc.  This
--option allows you to manually start a window manager in your TigerVNC session.
--.
--.TP
--.B \-xstartup \fIscript\fP
--Run a custom startup script, instead of %HOME/.vnc/xstartup, after launching
--Xvnc. This is useful to run full-screen applications.
--.
--.TP
--.B \-list
--Lists all VNC desktops started by vncserver.
--
--.SH FILES
--Several VNC-related files are found in the directory $HOME/.vnc:
--.TP
--$HOME/.vnc/xstartup
--A shell script specifying X applications to be run when a VNC desktop is
--started.  If this file does not exist, then vncserver will create a default
--xstartup script which attempts to launch your chosen window manager.
--.TP
--/etc/tigervnc/vncserver-config-defaults
--The optional system-wide equivalent of $HOME/.vnc/config. If this file exists
--and defines options to be passed to Xvnc, they will be used as defaults for
--users. The user's $HOME/.vnc/config overrides settings configured in this file.
--The overall configuration file load order is: this file, $HOME/.vnc/config,
--and then /etc/tigervnc/vncserver-config-mandatory. None are required to exist.
--.TP
--/etc/tigervnc/vncserver-config-mandatory
--The optional system-wide equivalent of $HOME/.vnc/config. If this file exists
--and defines options to be passed to Xvnc, they will override any of the same
--options defined in a user's $HOME/.vnc/config. This file offers a mechanism
--to establish some basic form of system-wide policy. WARNING! There is
--nothing stopping users from constructing their own vncserver-like script
--that calls Xvnc directly to bypass any options defined in
--/etc/tigervnc/vncserver-config-mandatory.  Likewise, any CLI arguments passed
--to vncserver will override ANY config file setting of the same name. The
--overall configuration file load order is:
--/etc/tigervnc/vncserver-config-defaults, $HOME/.vnc/config, and then this file.
--None are required to exist.
--.TP
--$HOME/.vnc/config
--An optional server config file wherein options to be passed to Xvnc are listed
--to avoid hard-coding them to the physical invocation. List options in this file
--one per line. For those requiring an argument, simply separate the option from
--the argument with an equal sign, for example: "geometry=2000x1200" or
--"securitytypes=vncauth,tlsvnc". Options without an argument are simply listed
--as a single word, for example: "localhost" or "alwaysshared".
--.TP
--$HOME/.vnc/passwd
--The VNC password file.
--.TP
--$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.log
--The log file for Xvnc and applications started in xstartup.
--.TP
--$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.pid
--Identifies the Xvnc process ID, used by the
--.B \-kill
--option.
--
--.SH SEE ALSO
--.BR vncviewer (1),
--.BR vncpasswd (1),
--.BR vncconfig (1),
--.BR Xvnc (1)
--.br
--https://www.tigervnc.org
--
--.SH AUTHOR
--Tristan Richardson, RealVNC Ltd., D. R. Commander and others.
--
--VNC was originally developed by the RealVNC team while at Olivetti
--Research Ltd / AT&T Laboratories Cambridge.  TightVNC additions were
--implemented by Constantin Kaplinsky. Many other people have since
--participated in development, testing and support. This manual is part
--of the TigerVNC software suite.
-diff --git a/unix/vncserver/CMakeLists.txt b/unix/vncserver/CMakeLists.txt
-new file mode 100644
-index 0000000..eeb4b7b
---- /dev/null
-+++ b/unix/vncserver/CMakeLists.txt
-@@ -0,0 +1,20 @@
-+add_executable(vncsession vncsession.c)
-+target_link_libraries(vncsession ${PAM_LIBS})
-+
-+configure_file(vncserver@.service.in vncserver@.service @ONLY)
-+configure_file(vncsession-start.in vncsession-start @ONLY)
-+configure_file(vncserver.in vncserver @ONLY)
-+
-+install(TARGETS vncsession DESTINATION ${CMAKE_INSTALL_FULL_SBINDIR})
-+install(FILES tigervnc.pam DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/pam.d RENAME tigervnc)
-+install(FILES vncsession.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man8 RENAME vncsession.8)
-+install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/vncserver DESTINATION ${CMAKE_INSTALL_FULL_LIBEXECDIR})
-+install(FILES vncserver.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man8 RENAME vncserver.8)
-+install(FILES vncserver-config-defaults vncserver-config-mandatory DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/tigervnc)
-+
-+install(FILES vncserver.users DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/tigervnc)
-+
-+if(INSTALL_SYSTEMD_UNITS)
-+  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/vncserver@.service DESTINATION ${CMAKE_INSTALL_FULL_UNITDIR})
-+  install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/vncsession-start DESTINATION ${CMAKE_INSTALL_FULL_LIBEXECDIR})
-+endif()
-diff --git a/unix/vncserver/selinux/Makefile b/unix/vncserver/selinux/Makefile
-new file mode 100644
-index 0000000..904a2d5
---- /dev/null
-+++ b/unix/vncserver/selinux/Makefile
-@@ -0,0 +1,24 @@
-+# SELinux module for TigerVNC's vncsession
-+#
-+# This will install the policy module, but not load it. To apply
-+# it you should also run:
-+#
-+#     sudo semodule -i /usr/share/selinux/packages/vncsession.pp
-+#     sudo restorecon /usr/sbin/vncsession /usr/libexec/vncsession-start
-+#
-+
-+PREFIX=/usr
-+DATADIR=$(PREFIX)/share
-+
-+all: vncsession.pp
-+
-+%.pp: %.te
-+	make -f $(DATADIR)/selinux/devel/Makefile $@
-+
-+clean:
-+	rm -f *.pp
-+	rm -rf tmp
-+
-+install: vncsession.pp
-+	mkdir -p $(DESTDIR)$(DATADIR)/selinux/packages
-+	install vncsession.pp $(DESTDIR)$(DATADIR)/selinux/packages/vncsession.pp 
-diff --git a/unix/vncserver/selinux/vncsession.fc b/unix/vncserver/selinux/vncsession.fc
-new file mode 100644
-index 0000000..121cdd2
---- /dev/null
-+++ b/unix/vncserver/selinux/vncsession.fc
-@@ -0,0 +1,26 @@
-+#
-+#  Copyright 2018 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.
-+#
-+
-+HOME_DIR/\.vnc(/.*)?      gen_context(system_u:object_r:xdm_home_t,s0)
-+HOME_ROOT/\.vnc(/.*)?      gen_context(system_u:object_r:xdm_home_t,s0)
-+
-+/usr/sbin/vncsession			--	gen_context(system_u:object_r:vnc_session_exec_t,s0)
-+/usr/libexec/vncsession-start		--	gen_context(system_u:object_r:vnc_session_exec_t,s0)
-+
-+/var/run/vncsession-:[0-9]*\.pid	--      gen_context(system_u:object_r:vnc_session_var_run_t,s0)
-diff --git a/unix/vncserver/selinux/vncsession.if b/unix/vncserver/selinux/vncsession.if
-new file mode 100644
-index 0000000..3eb6a30
---- /dev/null
-+++ b/unix/vncserver/selinux/vncsession.if
-@@ -0,0 +1 @@
-+## <summary></summary>
-diff --git a/unix/vncserver/selinux/vncsession.te b/unix/vncserver/selinux/vncsession.te
-new file mode 100644
-index 0000000..941f28d
---- /dev/null
-+++ b/unix/vncserver/selinux/vncsession.te
-@@ -0,0 +1,67 @@
-+#
-+#  Copyright 2018-2020 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.
-+#
-+
-+policy_module(vncsession, 1.0.0);
-+
-+gen_require(`
-+    type unconfined_t;
-+    type xdm_home_t;
-+')
-+
-+type vnc_session_exec_t;
-+corecmd_executable_file(vnc_session_exec_t)
-+type vnc_session_t;
-+init_daemon_domain(vnc_session_t, vnc_session_exec_t)
-+auth_login_pgm_domain(vnc_session_t)
-+
-+type vnc_session_var_run_t;
-+files_pid_file(vnc_session_var_run_t)
-+allow vnc_session_t vnc_session_var_run_t:file manage_file_perms;
-+files_pid_filetrans(vnc_session_t, vnc_session_var_run_t, file)
-+
-+auth_write_login_records(vnc_session_t)
-+
-+can_exec(vnc_session_t, vnc_session_exec_t)
-+
-+userdom_spec_domtrans_all_users(vnc_session_t)
-+userdom_signal_all_users(vnc_session_t)
-+
-+allow vnc_session_t self:capability { kill chown dac_override dac_read_search fowner setgid setuid sys_resource };
-+allow vnc_session_t self:process { getcap setsched setexec setrlimit };
-+allow vnc_session_t self:fifo_file rw_fifo_file_perms;
-+
-+manage_files_pattern(vnc_session_t, xdm_home_t, xdm_home_t)
-+manage_fifo_files_pattern(vnc_session_t, xdm_home_t, xdm_home_t)
-+manage_sock_files_pattern(vnc_session_t, xdm_home_t, xdm_home_t)
-+manage_lnk_files_pattern(vnc_session_t, xdm_home_t, xdm_home_t)
-+
-+userdom_user_home_dir_filetrans(unconfined_t, xdm_home_t, dir, ".vnc")
-+userdom_user_home_dir_filetrans(vnc_session_t, xdm_home_t, dir, ".vnc")
-+
-+userdom_admin_home_dir_filetrans(vnc_session_t, xdm_home_t, dir, ".vnc")
-+userdom_admin_home_dir_filetrans(unconfined_t, xdm_home_t, dir, ".vnc")
-+
-+miscfiles_read_localization(vnc_session_t)
-+
-+kernel_read_kernel_sysctls(vnc_session_t)
-+
-+logging_append_all_logs(vnc_session_t)
-+
-+mcs_process_set_categories(vnc_session_t)
-+mcs_killall(vnc_session_t)
-diff --git a/unix/vncserver/tigervnc.pam b/unix/vncserver/tigervnc.pam
-new file mode 100644
-index 0000000..0f4cb3a
---- /dev/null
-+++ b/unix/vncserver/tigervnc.pam
-@@ -0,0 +1,11 @@
-+#%PAM-1.0
-+# pam_selinux.so close should be the first session rule
-+-session   required     pam_selinux.so close
-+session    required     pam_loginuid.so
-+-session   required     pam_selinux.so open
-+session    required     pam_namespace.so
-+session    optional     pam_keyinit.so force revoke
-+session    required     pam_limits.so
-+-session   optional     pam_systemd.so
-+session    required     pam_unix.so
-+-session   optional     pam_reauthorize.so prepare
-diff --git a/unix/vncserver/vncserver-config-defaults b/unix/vncserver/vncserver-config-defaults
-new file mode 100644
-index 0000000..0c217bf
---- /dev/null
-+++ b/unix/vncserver/vncserver-config-defaults
-@@ -0,0 +1,15 @@
-+## Default settings for VNC servers started by the vncserver service
-+#
-+# Any settings given here will override the builtin defaults, but can
-+# also be overriden by ~/.vnc/config and vncserver-config-mandatory.
-+#
-+# See the following manpages for more details: vncserver(1) Xvnc(1)
-+#
-+# Several common settings are shown below. Uncomment and modify to your
-+# liking.
-+
-+# securitytypes=vncauth,tlsvnc
-+# desktop=sandbox
-+# geometry=2000x1200
-+# localhost
-+# alwaysshared
-diff --git a/unix/vncserver/vncserver-config-mandatory b/unix/vncserver/vncserver-config-mandatory
-new file mode 100644
-index 0000000..98c32f6
---- /dev/null
-+++ b/unix/vncserver/vncserver-config-mandatory
-@@ -0,0 +1,15 @@
-+## Mandatory settings for VNC servers started by the vncserver service
-+#
-+# Any settings given here will override the builtin defaults and
-+# settings specified in ~/.vnc/config or vnc-config-defaults.
-+#
-+# See the following manpages for more details: vncserver(1) Xvnc(1)
-+#
-+# Several common settings are shown below. Uncomment and modify to your
-+# liking.
-+
-+# securitytypes=vncauth,tlsvnc
-+# desktop=sandbox
-+# geometry=2000x1200
-+# localhost
-+# alwaysshared
-diff --git a/unix/vncserver/vncserver.in b/unix/vncserver/vncserver.in
-new file mode 100755
-index 0000000..8e05b72
---- /dev/null
-+++ b/unix/vncserver/vncserver.in
-@@ -0,0 +1,485 @@
-+#!/usr/bin/perl
-+#
-+#  Copyright (C) 2015-2019 Pierre Ossman for Cendio AB
-+#  Copyright (C) 2009-2010 D. R. Commander.  All Rights Reserved.
-+#  Copyright (C) 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
-+#  Copyright (C) 2002-2003 Constantin Kaplinsky.  All Rights Reserved.
-+#  Copyright (C) 2002-2005 RealVNC Ltd.
-+#  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
-+#
-+#  This is free software; you can redistribute it and/or modify
-+#  it under the terms of the GNU General Public License as published by
-+#  the Free Software Foundation; either version 2 of the License, or
-+#  (at your option) any later version.
-+#
-+#  This software is distributed in the hope that it will be useful,
-+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+#  GNU General Public License for more details.
-+#
-+#  You should have received a copy of the GNU General Public License
-+#  along with this software; if not, write to the Free Software
-+#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
-+#  USA.
-+#
-+
-+#
-+# vncserver - wrapper script to start an X VNC server.
-+#
-+
-+&SanityCheck();
-+
-+#
-+# Global variables.  You may want to configure some of these for
-+# your site
-+#
-+
-+$vncUserDir = "$ENV{HOME}/.vnc";
-+$vncUserConfig = "$vncUserDir/config";
-+
-+$vncSystemConfigDir = "/etc/tigervnc";
-+$vncSystemConfigDefaultsFile = "$vncSystemConfigDir/vncserver-config-defaults";
-+$vncSystemConfigMandatoryFile = "$vncSystemConfigDir/vncserver-config-mandatory";
-+
-+$xauthorityFile = "$ENV{XAUTHORITY}" || "$ENV{HOME}/.Xauthority";
-+
-+chop($host = `uname -n`);
-+
-+if (-d "/etc/X11/fontpath.d") {
-+    $fontPath = "catalogue:/etc/X11/fontpath.d";
-+}
-+
-+@fontpaths = ('/usr/share/X11/fonts', '/usr/share/fonts', '/usr/share/fonts/X11/');
-+if (! -l "/usr/lib/X11") {push(@fontpaths, '/usr/lib/X11/fonts');}
-+if (! -l "/usr/X11") {push(@fontpaths, '/usr/X11/lib/X11/fonts');}
-+if (! -l "/usr/X11R6") {push(@fontpaths, '/usr/X11R6/lib/X11/fonts');}
-+push(@fontpaths, '/usr/share/fonts/default');
-+
-+@fonttypes = ('misc',
-+             '75dpi',
-+             '100dpi',
-+             'Speedo',
-+             'Type1');
-+
-+foreach $_fpath (@fontpaths) {
-+    foreach $_ftype (@fonttypes) {
-+        if (-f "$_fpath/$_ftype/fonts.dir") {
-+            if (! -l "$_fpath/$_ftype") {
-+                $defFontPath .= "$_fpath/$_ftype,";
-+            }
-+        }
-+    }
-+}
-+
-+if ($defFontPath) {
-+    if (substr($defFontPath, -1, 1) == ',') {
-+        chop $defFontPath;
-+    }
-+}
-+
-+if ($fontPath eq "") {
-+    $fontPath = $defFontPath;
-+}
-+
-+# Find display number.
-+if ((@ARGV == 1) && ($ARGV[0] =~ /^:(\d+)$/)) {
-+    $displayNumber = $1;
-+    if (!&CheckDisplayNumber($displayNumber)) {
-+	die "A VNC server is already running as :$displayNumber\n";
-+    }
-+} else {
-+    &Usage();
-+}
-+
-+$vncPort = 5900 + $displayNumber;
-+
-+$desktopName = "$host:$displayNumber ($ENV{USER})";
-+
-+my %default_opts;
-+my %config;
-+
-+# We set some reasonable defaults. Config file settings
-+# override these where present.
-+$default_opts{desktop} = $desktopName;
-+$default_opts{auth} = $xauthorityFile;
-+$default_opts{rfbwait} = 30000;
-+$default_opts{rfbauth} = "$vncUserDir/passwd";
-+$default_opts{rfbport} = $vncPort;
-+$default_opts{fp} = $fontPath if ($fontPath);
-+$default_opts{pn} = "";
-+
-+# Load user-overrideable system defaults
-+LoadConfig($vncSystemConfigDefaultsFile);
-+
-+# Then the user's settings
-+LoadConfig($vncUserConfig);
-+
-+# And then override anything set above if mandatory settings exist.
-+# WARNING: "Mandatory" is used loosely here! As the man page says,
-+# there is nothing stopping someone from EASILY subverting the
-+# settings in $vncSystemConfigMandatoryFile by simply passing
-+# CLI args to vncserver, which trump config files! To properly
-+# hard force policy in a non-subvertible way would require major
-+# development work that touches Xvnc itself.
-+LoadConfig($vncSystemConfigMandatoryFile, 1);
-+
-+#
-+# Check whether VNC authentication is enabled, and if so, check that
-+# a VNC password has been created.
-+#
-+
-+$securityTypeArgSpecified = 0;
-+$vncAuthEnabled = 0;
-+$passwordArgSpecified = 0;
-+@vncAuthStrings = ("vncauth", "tlsvnc", "x509vnc");
-+
-+# ...first we check our configuration files' settings
-+if ($config{'securitytypes'}) {
-+  $securityTypeArgSpecified = 1;
-+  foreach $arg2 (split(',', $config{'securitytypes'})) {
-+    if (grep {$_ eq lc($arg2)} @vncAuthStrings) {
-+      $vncAuthEnabled = 1;
-+    }
-+  }
-+}
-+
-+if ($config{'password'} ||
-+    $config{'passwordfile'} ||
-+    $config{'rfbauth'}) {
-+    $passwordArgSpecified = 1;
-+}
-+
-+if ((!$securityTypeArgSpecified || $vncAuthEnabled) && !$passwordArgSpecified) {
-+    ($z,$z,$mode) = stat("$vncUserDir/passwd");
-+    if (!(-e "$vncUserDir/passwd") || ($mode & 077)) {
-+        die "VNC authentication enabled, but no password file created.\n";
-+    }
-+}
-+
-+#
-+# Find a desktop session to run
-+#
-+
-+my $sessionname;
-+my %session;
-+
-+$sessionname = delete $config{'session'};
-+
-+if ($sessionname) {
-+  %session = LoadXSession($sessionname);
-+  if (!%session) {
-+    warn "Could not load configured desktop session $sessionname\n";
-+    $sessionname = undef;
-+  }
-+}
-+
-+if (!$sessionname) {
-+  foreach $file (glob("/usr/share/xsessions/*.desktop")) {
-+    ($name) = $file =~ /^.*\/(.*)[.]desktop$/;
-+    %session = LoadXSession($name);
-+    if (%session) {
-+      $sessionname = $name;
-+      last;
-+    }
-+  }
-+}
-+
-+if (!$sessionname) {
-+  die "Could not find a desktop session to run\n";
-+}
-+
-+warn "Using desktop session $sessionname\n";
-+
-+if (!$session{'Exec'}) {
-+  die "No command specified for desktop session\n";
-+}
-+
-+$ENV{GDMSESSION} = $sessionname;
-+$ENV{DESKTOP_SESSION} = $sessionname;
-+$ENV{XDG_SESSION_DESKTOP} = $sessionname;
-+
-+if ($session{'DesktopNames'}) {
-+    $ENV{XDG_DESKTOP_NAMES} = $session{'DesktopNames'} =~ s/;/:/gr;
-+}
-+
-+
-+# Make an X server cookie and set up the Xauthority file
-+# mcookie is a part of util-linux, usually only GNU/Linux systems have it.
-+$cookie = `mcookie`;
-+# Fallback for non GNU/Linux OS - use /dev/urandom on systems that have it,
-+# otherwise use perl's random number generator, seeded with the sum
-+# of the current time, our PID and part of the encrypted form of the password.
-+if ($cookie eq "" && open(URANDOM, '<', '/dev/urandom')) {
-+  my $randata;
-+  if (sysread(URANDOM, $randata, 16) == 16) {
-+    $cookie = unpack 'h*', $randata;
-+  }
-+  close(URANDOM);
-+}
-+if ($cookie eq "") {
-+  srand(time+$$+unpack("L",`cat $vncUserDir/passwd`));
-+  for (1..16) {
-+    $cookie .= sprintf("%02x", int(rand(256)) % 256);
-+  }
-+}
-+
-+open(XAUTH, "|xauth -f $xauthorityFile source -");
-+print XAUTH "add $host:$displayNumber . $cookie\n";
-+print XAUTH "add $host/unix:$displayNumber . $cookie\n";
-+close(XAUTH);
-+
-+$ENV{XAUTHORITY} = $xauthorityFile;
-+
-+# Now start the X VNC Server
-+
-+@cmd = ("xinit");
-+
-+push(@cmd, $Xsession, $session{'Exec'});
-+
-+push(@cmd, '--');
-+
-+
-+# We build up our Xvnc command with options
-+push(@cmd, "@CMAKE_INSTALL_FULL_BINDIR@/Xvnc", ":$displayNumber");
-+
-+foreach my $k (sort keys %config) {
-+  push(@cmd, "-$k");
-+  push(@cmd, $config{$k}) if $config{$k};
-+  delete $default_opts{$k}; # file options take precedence
-+}
-+
-+foreach my $k (sort keys %default_opts) {
-+  push(@cmd, "-$k");
-+  push(@cmd, $default_opts{$k}) if $default_opts{$k};
-+}
-+
-+warn "\nNew '$desktopName' desktop is $host:$displayNumber\n\n";
-+
-+warn "Starting desktop session $sessionname\n";
-+
-+exec(@cmd);
-+
-+die "Failed to start session.\n";
-+
-+###############################################################################
-+# Functions
-+###############################################################################
-+
-+#
-+# Populate the global %config hash with settings from a specified
-+# vncserver configuration file if it exists
-+#
-+# Args: 1. file path
-+#       2. optional boolean flag to enable warning when a previously
-+#          set configuration setting is being overridden
-+#
-+sub LoadConfig {
-+  local ($configFile, $warnoverride) = @_;
-+  local ($toggle) = undef;
-+
-+  if (stat($configFile)) {
-+    if (open(IN, $configFile)) {
-+      while (<IN>) {
-+        next if /^#/;
-+        if (my ($k, $v) = /^\s*(\w+)\s*=\s*(.+)$/) {
-+          $k = lc($k); # must normalize key case
-+          if ($warnoverride && $config{$k}) {
-+            print("Warning: $configFile is overriding previously defined '$k' to be '$v'\n");
-+          }
-+          $config{$k} = $v;
-+        } elsif ($_ =~ m/^\s*(\S+)/) {
-+          # We can't reasonably warn on override of toggles (e.g. AlwaysShared)
-+          # because it would get crazy to do so. We'd have to check if the
-+          # current config file being loaded defined the logical opposite setting
-+          # (NeverShared vs. AlwaysShared, etc etc).
-+          $toggle = lc($1); # must normalize key case
-+          $config{$toggle} = $k;
-+        }
-+      }
-+      close(IN);
-+    }
-+  }
-+}
-+
-+
-+#
-+# Load a session desktop file
-+#
-+sub LoadXSession {
-+  local ($name) = @_;
-+  my $file, $found_group, %session;
-+
-+  $file = "/usr/share/xsessions/$name.desktop";
-+
-+  if (!stat($file)) {
-+    warn "Could not find session desktop file $file";
-+    return;
-+  }
-+
-+  if (!open(IN, $file)) {
-+    warn "Could not open session desktop file $file";
-+    return;
-+  }
-+
-+  $found_group = 0;
-+  while (my $line = <IN>) {
-+    next if $line =~ /^#/;
-+    next if $line =~ /^\s*$/;
-+
-+    if (!$found_group) {
-+        next if $line != "[Desktop Entry]";
-+        $found_group = 1;
-+        next;
-+    } else {
-+        last if $line =~ /^\[/;
-+    }
-+
-+    my ($key, $value) = $line =~ /^\s*([]A-Za-z0-9_@\-\[]+)\s*=\s*(.*)$/;
-+    if (!$key) {
-+        warn "Invalid session desktop file $file";
-+        close(IN);
-+        return;
-+    }
-+
-+    $value =~ s/\\s/ /g;
-+    $value =~ s/\\n/\n/g;
-+    $value =~ s/\\t/\t/g;
-+    $value =~ s/\\r/\r/g;
-+    $value =~ s/\\\\/\\/g;
-+
-+    $session{$key} = $value;
-+  }
-+
-+  close(IN);
-+
-+  return %session;
-+}
-+
-+
-+#
-+# CheckDisplayNumber checks if the given display number is available.  A
-+# display number n is taken if something is listening on the VNC server port
-+# (5900+n) or the X server port (6000+n).
-+#
-+
-+sub CheckDisplayNumber
-+{
-+    local ($n) = @_;
-+
-+    socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n";
-+    eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))';
-+    if (!bind(S, pack('S n x12', $AF_INET, 6000 + $n))) {
-+	close(S);
-+	return 0;
-+    }
-+    close(S);
-+
-+    socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n";
-+    eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))';
-+    if (!bind(S, pack('S n x12', $AF_INET, 5900 + $n))) {
-+	close(S);
-+	return 0;
-+    }
-+    close(S);
-+
-+    if (-e "/tmp/.X$n-lock") {
-+	warn "\nWarning: $host:$n is taken because of /tmp/.X$n-lock\n";
-+	warn "Remove this file if there is no X server $host:$n\n";
-+	return 0;
-+    }
-+
-+    if (-e "/tmp/.X11-unix/X$n") {
-+	warn "\nWarning: $host:$n is taken because of /tmp/.X11-unix/X$n\n";
-+	warn "Remove this file if there is no X server $host:$n\n";
-+	return 0;
-+    }
-+
-+    if (-e "/usr/spool/sockets/X11/$n") {
-+	warn("\nWarning: $host:$n is taken because of ".
-+             "/usr/spool/sockets/X11/$n\n");
-+	warn "Remove this file if there is no X server $host:$n\n";
-+	return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+#
-+# Usage
-+#
-+
-+sub Usage
-+{
-+    die("\nusage: $prog <display>\n\n");
-+}
-+
-+
-+# Routine to make sure we're operating in a sane environment.
-+sub SanityCheck
-+{
-+    local ($cmd);
-+
-+    # Get the program name
-+    ($prog) = ($0 =~ m|([^/]+)$|);
-+
-+    #
-+    # Check we have all the commands we'll need on the path.
-+    #
-+
-+ cmd:
-+    foreach $cmd ("uname","xauth","xinit") {
-+	for (split(/:/,$ENV{PATH})) {
-+	    if (-x "$_/$cmd") {
-+		next cmd;
-+	    }
-+	}
-+	die "$prog: couldn't find \"$cmd\" on your PATH.\n";
-+    }
-+    
-+    foreach $cmd ("/etc/X11/xinit/Xsession", "/etc/X11/Xsession") {
-+        if (-x "$cmd") {
-+            $Xsession = $cmd;
-+            last;
-+        }
-+    }
-+    if (not defined $Xsession) {
-+        die "$prog: Couldn't find suitable Xsession.\n";
-+    }
-+
-+
-+    if (!defined($ENV{HOME})) {
-+	die "$prog: The HOME environment variable is not set.\n";
-+    }
-+
-+    #
-+    # Find socket constants. 'use Socket' is a perl5-ism, so we wrap it in an
-+    # eval, and if it fails we try 'require "sys/socket.ph"'.  If this fails,
-+    # we just guess at the values.  If you find perl moaning here, just
-+    # hard-code the values of AF_INET and SOCK_STREAM.  You can find these out
-+    # for your platform by looking in /usr/include/sys/socket.h and related
-+    # files.
-+    #
-+
-+    chop($os = `uname`);
-+    chop($osrev = `uname -r`);
-+
-+    eval 'use Socket';
-+    if ($@) {
-+	eval 'require "sys/socket.ph"';
-+	if ($@) {
-+	    if (($os eq "SunOS") && ($osrev !~ /^4/)) {
-+		$AF_INET = 2;
-+		$SOCK_STREAM = 2;
-+	    } else {
-+		$AF_INET = 2;
-+		$SOCK_STREAM = 1;
-+	    }
-+	} else {
-+	    $AF_INET = &AF_INET;
-+	    $SOCK_STREAM = &SOCK_STREAM;
-+	}
-+    } else {
-+	$AF_INET = &AF_INET;
-+	$SOCK_STREAM = &SOCK_STREAM;
-+    }
-+}
-diff --git a/unix/vncserver/vncserver.man b/unix/vncserver/vncserver.man
-new file mode 100644
-index 0000000..f1017be
---- /dev/null
-+++ b/unix/vncserver/vncserver.man
-@@ -0,0 +1 @@
-+.so man8/vncsession.8
-diff --git a/unix/vncserver/vncserver.users b/unix/vncserver/vncserver.users
-new file mode 100644
-index 0000000..24875c8
---- /dev/null
-+++ b/unix/vncserver/vncserver.users
-@@ -0,0 +1,8 @@
-+# TigerVNC User assignment
-+#
-+# This file assigns users to specific VNC display numbers.
-+# The syntax is <display>=<username>. E.g.:
-+#
-+# :2=andrew
-+# :3=lisa
-+ 
-diff --git a/unix/vncserver/vncserver@.service.in b/unix/vncserver/vncserver@.service.in
-new file mode 100644
-index 0000000..584ecf4
---- /dev/null
-+++ b/unix/vncserver/vncserver@.service.in
-@@ -0,0 +1,43 @@
-+# The vncserver service unit file
-+#
-+# Quick HowTo:
-+# 1. Add a user mapping to /etc/tigervnc/vncserver.users.
-+# 2. Adjust the global or user configuration. See the
-+#    vncsession(8) manpage for details. (OPTIONAL)
-+# 3. Run `systemctl enable vncserver@:<display>.service`
-+# 4. Run `systemctl start vncserver@:<display>.service`
-+#
-+# DO NOT RUN THIS SERVICE if your local area network is
-+# untrusted!  For a secure way of using VNC, you should
-+# limit connections to the local host and then tunnel from
-+# the machine you want to view VNC on (host A) to the machine
-+# whose VNC output you want to view (host B)
-+#
-+# [user@hostA ~]$ ssh -v -C -L 590N:localhost:590M hostB
-+#
-+# this will open a connection on port 590N of your hostA to hostB's port 590M
-+# (in fact, it ssh-connects to hostB and then connects to localhost (on hostB).
-+# See the ssh man page for details on port forwarding)
-+#
-+# You can then point a VNC client on hostA at vncdisplay N of localhost and with
-+# the help of ssh, you end up seeing what hostB makes available on port 590M
-+#
-+# Use "nolisten=tcp" to prevent X connections to your VNC server via TCP.
-+#
-+# Use "localhost" to prevent remote VNC clients connecting except when
-+# doing so through a secure tunnel.  See the "-via" option in the
-+# `man vncviewer' manual page.
-+
-+
-+[Unit]
-+Description=Remote desktop service (VNC)
-+After=syslog.target network.target
-+
-+[Service]
-+Type=forking
-+ExecStart=@CMAKE_INSTALL_FULL_LIBEXECDIR@/vncsession-start %i
-+PIDFile=/var/run/vncsession-%i.pid
-+SELinuxContext=system_u:system_r:vnc_session_t:s0
-+
-+[Install]
-+WantedBy=multi-user.target
-diff --git a/unix/vncserver/vncsession-start.in b/unix/vncserver/vncsession-start.in
-new file mode 100644
-index 0000000..b20fcdd
---- /dev/null
-+++ b/unix/vncserver/vncsession-start.in
-@@ -0,0 +1,43 @@
-+#!/bin/bash
-+#
-+#  Copyright 2019 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.
-+#
-+
-+USERSFILE="@CMAKE_INSTALL_FULL_SYSCONFDIR@/tigervnc/vncserver.users"
-+
-+if [ $# -ne 1 ]; then
-+	echo "Syntax:" >&2
-+	echo "    $0 <display>" >&2
-+	exit 1
-+fi
-+
-+if [ ! -f "${USERSFILE}" ]; then
-+	echo "Users file ${USERSFILE} missing" >&2
-+	exit 1
-+fi
-+
-+DISPLAY="$1"
-+
-+USER=`grep "^${DISPLAY}=" "${USERSFILE}" 2>/dev/null | head -1 | cut -d = -f 2-`
-+
-+if [ -z "${USER}" ]; then
-+	echo "No user configured for display ${DISPLAY}" >&2
-+	exit 1
-+fi
-+
-+exec "@CMAKE_INSTALL_FULL_SBINDIR@/vncsession" "${USER}" "${DISPLAY}"
-diff --git a/unix/vncserver/vncsession.c b/unix/vncserver/vncsession.c
-new file mode 100644
-index 0000000..21a40f6
---- /dev/null
-+++ b/unix/vncserver/vncsession.c
-@@ -0,0 +1,592 @@
-+/* 
-+ * Copyright 2018 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.
-+ */
-+
-+#include <config.h>
-+
-+#include <dirent.h>
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <grp.h>
-+#include <limits.h>
-+#include <pwd.h>
-+#include <signal.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <sysexits.h>
-+#include <unistd.h>
-+#include <syslog.h>
-+#include <security/pam_appl.h>
-+#include <sys/stat.h>
-+#include <sys/types.h>
-+#include <sys/wait.h>
-+
-+extern char **environ;
-+
-+// PAM service name
-+const char *SERVICE_NAME = "tigervnc";
-+
-+// Main script PID
-+volatile static pid_t script = -1;
-+
-+// Daemon completion pipe
-+int daemon_pipe_fd = -1;
-+
-+static int
-+begin_daemon(void)
-+{
-+    int devnull, fds[2];
-+    pid_t pid;
-+
-+    /* Pipe to report startup success */
-+    if (pipe(fds) < 0) {
-+        perror("pipe");
-+        return -1;
-+    }
-+
-+    /* First fork */
-+    pid = fork();
-+    if (pid < 0) {
-+        perror("fork");
-+        return -1;
-+    }
-+
-+    if (pid != 0) {
-+        ssize_t len;
-+        char buf[1];
-+
-+        close(fds[1]);
-+
-+        /* Wait for child to finish startup */
-+        len = read(fds[0], buf, 1);
-+        if (len != 1) {
-+            fprintf(stderr, "Failure daemonizing\n");
-+            _exit(EX_OSERR);
-+        }
-+
-+        _exit(0);
-+    }
-+
-+    close(fds[0]);
-+    daemon_pipe_fd = fds[1];
-+
-+    /* Detach from terminal */
-+    if (setsid() < 0) {
-+        perror("setsid");
-+        return -1;
-+    }
-+
-+    /* Another fork required to fully detach */
-+    pid = fork();
-+    if (pid < 0) {
-+        perror("fork");
-+        return -1;
-+    }
-+
-+    if (pid == 0)
-+        _exit(0);
-+
-+    /* Send all stdio to /dev/null */
-+    devnull = open("/dev/null", O_RDWR);
-+    if (devnull < 0) {
-+        fprintf(stderr, "Failed to open /dev/null: %s\n", strerror(errno));
-+        return -1;
-+    }
-+    if ((dup2(devnull, 0) < 0) ||
-+        (dup2(devnull, 1) < 0) ||
-+        (dup2(devnull, 2) < 0)) {
-+        perror("dup2");
-+        return -1;
-+    }
-+    if (devnull > 2)
-+        close(devnull);
-+
-+    /* Full control of access bits */
-+    umask(0);
-+
-+    /* A safe working directory */
-+    if (chdir("/") < 0) {
-+        perror("chdir");
-+        return -1;
-+    }
-+
-+    return 0;
-+}
-+
-+static void
-+finish_daemon(void)
-+{
-+    write(daemon_pipe_fd, "+", 1);
-+    close(daemon_pipe_fd);
-+    daemon_pipe_fd = -1;
-+}
-+
-+static void
-+sighandler(int sig)
-+{
-+    if (script > 0) {
-+        kill(script, SIGTERM);
-+    }
-+}
-+
-+static void
-+setup_signals(void)
-+{
-+    struct sigaction act;
-+
-+    memset(&act, 0, sizeof(act));
-+    act.sa_handler = sighandler;
-+    sigemptyset(&act.sa_mask);
-+    act.sa_flags = 0;
-+
-+    sigaction(SIGHUP, &act, NULL);
-+    sigaction(SIGINT, &act, NULL);
-+    sigaction(SIGTERM, &act, NULL);
-+    sigaction(SIGQUIT, &act, NULL);
-+    sigaction(SIGPIPE, &act, NULL);
-+}
-+
-+static int
-+conv(int num_msg,
-+     const struct pam_message **msg,
-+     struct pam_response **resp, void *appdata_ptr)
-+{
-+    /* Opening a session should not require a conversation */
-+    return PAM_CONV_ERR;
-+}
-+
-+static pam_handle_t *
-+run_pam(int *pamret, const char *username, const char *display)
-+{
-+    pam_handle_t *pamh;
-+
-+    /* Say hello to PAM */
-+    struct pam_conv pconv;
-+    pconv.conv = conv;
-+    pconv.appdata_ptr = NULL;
-+    *pamret = pam_start(SERVICE_NAME, username, &pconv, &pamh);
-+    if (*pamret != PAM_SUCCESS) {
-+        /* pam_strerror requires a pamh argument, but if pam_start
-+           fails, pamh is invalid. In practice, at least the Linux
-+           implementation of pam_strerror does not use the pamh
-+           argument, but let's take care - avoid pam_strerror here. */
-+        syslog(LOG_CRIT, "pam_start failed: %d", *pamret);
-+        return NULL;
-+    }
-+
-+    /* ConsoleKit and systemd (and possibly others) uses this to
-+       determine if the session is local or not. It needs to be set to
-+       something that can't be interpreted as localhost. We don't know
-+       what the client's address is though, and that might change on
-+       reconnects. We also don't want to set it to some text string as
-+       that results in a DNS lookup with e.g. libaudit. Let's use a
-+       fake IPv4 address from the documentation range. */
-+    /* FIXME: This might throw an error on a IPv6-only host */
-+    *pamret = pam_set_item(pamh, PAM_RHOST, "203.0.113.20");
-+    if (*pamret != PAM_SUCCESS) {
-+        syslog(LOG_CRIT, "pam_set_item(PAM_RHOST) failed: %d (%s)",
-+               *pamret, pam_strerror(pamh, *pamret));
-+        return pamh;
-+    }
-+
-+#ifdef PAM_XDISPLAY
-+    /* Let PAM modules use this to tag the session as a graphical one */
-+    *pamret = pam_set_item(pamh, PAM_XDISPLAY, display);
-+    /* Note: PAM_XDISPLAY is only supported by modern versions of PAM */
-+    if (*pamret != PAM_BAD_ITEM && *pamret != PAM_SUCCESS) {
-+        syslog(LOG_CRIT, "pam_set_item(PAM_XDISPLAY) failed: %d (%s)",
-+               *pamret, pam_strerror(pamh, *pamret));
-+        return pamh;
-+    }
-+#endif
-+
-+    /* Open session */
-+    *pamret = pam_open_session(pamh, PAM_SILENT);
-+    if (*pamret != PAM_SUCCESS) {
-+        syslog(LOG_CRIT, "pam_open_session failed: %d (%s)",
-+               *pamret, pam_strerror(pamh, *pamret));
-+        return pamh;
-+    }
-+
-+    return pamh;
-+}
-+
-+static int
-+stop_pam(pam_handle_t * pamh, int pamret)
-+{
-+    /* Close session */
-+    if (pamret == PAM_SUCCESS) {
-+        pamret = pam_close_session(pamh, PAM_SILENT);
-+        if (pamret != PAM_SUCCESS) {
-+            syslog(LOG_ERR, "pam_close_session failed: %d (%s)",
-+                   pamret, pam_strerror(pamh, pamret));
-+        }
-+    }
-+
-+    /* If PAM was OK and we are running on a SELinux system, new
-+       processes images will be executed in the root context. */
-+
-+    /* Say goodbye */
-+    pamret = pam_end(pamh, pamret);
-+    if (pamret != PAM_SUCCESS) {
-+        /* avoid pam_strerror - we have no pamh. */
-+        syslog(LOG_ERR, "pam_end failed: %d", pamret);
-+        return EX_OSERR;
-+    }
-+    return pamret;
-+}
-+
-+static char **
-+prepare_environ(pam_handle_t * pamh)
-+{
-+    char **pam_env, **child_env, **entry;
-+    int orig_count, pam_count;
-+
-+    /* This function merges the normal environment with PAM's changes */
-+
-+    pam_env = pam_getenvlist(pamh);
-+    if (pam_env == NULL)
-+        return NULL;
-+
-+    /*
-+     * Worst case scenario is that PAM only adds variables, so allocate
-+     * based on that assumption.
-+     */
-+    orig_count = 0;
-+    for (entry = environ; *entry != NULL; entry++)
-+        orig_count++;
-+    pam_count = 0;
-+    for (entry = pam_env; *entry != NULL; entry++)
-+        pam_count++;
-+
-+    child_env = calloc(orig_count + pam_count + 1, sizeof(char *));
-+    if (child_env == NULL)
-+        return NULL;
-+
-+    memcpy(child_env, environ, sizeof(char *) * orig_count);
-+    for (entry = child_env; *entry != NULL; entry++) {
-+        *entry = strdup(*entry);
-+        if (*entry == NULL)     // FIXME: cleanup
-+            return NULL;
-+    }
-+
-+    for (entry = pam_env; *entry != NULL; entry++) {
-+        size_t varlen;
-+        char **orig_entry;
-+
-+        varlen = strcspn(*entry, "=") + 1;
-+
-+        /* Check for overwrite */
-+        for (orig_entry = child_env; *orig_entry != NULL; orig_entry++) {
-+            if (strncmp(*entry, *orig_entry, varlen) != 0)
-+                continue;
-+
-+            free(*orig_entry);
-+            *orig_entry = *entry;
-+            break;
-+        }
-+
-+        /* New variable? */
-+        if (*orig_entry == NULL) {
-+            /*
-+             * orig_entry will be pointing at the terminating entry,
-+             * so we can just tack it on here. The new NULL was already
-+             * prepared by calloc().
-+             */
-+            *orig_entry = *entry;
-+        }
-+    }
-+
-+    return child_env;
-+}
-+
-+static void
-+switch_user(const char *username, uid_t uid, gid_t gid)
-+{
-+    // We must change group stuff first, because only root can do that.
-+    if (setgid(gid) < 0) {
-+        perror(": setgid");
-+        _exit(EX_OSERR);
-+    }
-+
-+    // Supplementary groups.
-+    if (initgroups(username, gid) < 0) {
-+        perror("initgroups");
-+        _exit(EX_OSERR);
-+    }
-+
-+    // Set euid, ruid and suid
-+    if (setuid(uid) < 0) {
-+        perror("setuid");
-+        _exit(EX_OSERR);
-+    }
-+}
-+
-+static void
-+redir_stdio(const char *homedir, const char *display)
-+{
-+    int fd;
-+    char hostname[HOST_NAME_MAX+1];
-+    char logfile[PATH_MAX];
-+
-+    fd = open("/dev/null", O_RDONLY);
-+    if (fd == -1) {
-+        perror("open");
-+        _exit(EX_OSERR);
-+    }
-+    if (dup2(fd, 0) == -1) {
-+        perror("dup2");
-+        _exit(EX_OSERR);
-+    }
-+    close(fd);
-+
-+    snprintf(logfile, sizeof(logfile), "%s/.vnc", homedir);
-+    if (mkdir(logfile, 0755) == -1) {
-+        if (errno != EEXIST) {
-+            perror("mkdir");
-+            _exit(EX_OSERR);
-+        }
-+    }
-+
-+    if (gethostname(hostname, sizeof(hostname)) == -1) {
-+        perror("gethostname");
-+        _exit(EX_OSERR);
-+    }
-+
-+    snprintf(logfile, sizeof(logfile), "%s/.vnc/%s%s.log",
-+             homedir, hostname, display);
-+    fd = open(logfile, O_CREAT | O_WRONLY | O_TRUNC, 0644);
-+    if (fd == -1) {
-+        perror("open");
-+        _exit(EX_OSERR);
-+    }
-+    if ((dup2(fd, 1) == -1) || (dup2(fd, 2) == -1)) {
-+        perror("dup2");
-+        _exit(EX_OSERR);
-+    }
-+    close(fd);
-+}
-+
-+static void
-+close_fds(void)
-+{
-+    DIR *dir;
-+    struct dirent *entry;
-+
-+    dir = opendir("/proc/self/fd");
-+    if (dir == NULL) {
-+        perror("opendir");
-+        _exit(EX_OSERR);
-+    }
-+
-+    while ((entry = readdir(dir)) != NULL) {
-+        int fd;
-+        fd = atoi(entry->d_name);
-+        if (fd < 3)
-+            continue;
-+        close(fd);
-+    }
-+
-+    closedir(dir);
-+}
-+
-+static pid_t
-+run_script(const char *username, const char *display, char **envp)
-+{
-+    struct passwd *pwent;
-+    pid_t pid;
-+    const char *child_argv[3];
-+
-+    pwent = getpwnam(username);
-+    if (pwent == NULL) {
-+        syslog(LOG_CRIT, "getpwnam: %s", strerror(errno));
-+        return -1;
-+    }
-+
-+    pid = fork();
-+    if (pid < 0) {
-+        syslog(LOG_CRIT, "fork: %s", strerror(errno));
-+        return pid;
-+    }
-+
-+    /* two processes now */
-+
-+    if (pid > 0)
-+        return pid;
-+
-+    /* child */
-+
-+    switch_user(pwent->pw_name, pwent->pw_uid, pwent->pw_gid);
-+
-+    close_fds();
-+
-+    redir_stdio(pwent->pw_dir, display);
-+
-+    // execvpe() is not POSIX and is missing from older glibc
-+    // First clear out everything
-+    while ((environ != NULL) && (*environ != NULL)) {
-+        char *var, *eq;
-+        var = strdup(*environ);
-+        eq = strchr(var, '=');
-+        if (eq)
-+            *eq = '\0';
-+        unsetenv(var);
-+        free(var);
-+    }
-+
-+    // Then copy over the desired environment
-+    for (; *envp != NULL; envp++)
-+        putenv(*envp);
-+
-+    // Set up some basic environment for the script
-+    setenv("HOME", pwent->pw_dir, 1);
-+    setenv("SHELL", pwent->pw_shell, 1);
-+    setenv("LOGNAME", pwent->pw_name, 1);
-+    setenv("USER", pwent->pw_name, 1);
-+    setenv("USERNAME", pwent->pw_name, 1);
-+
-+    child_argv[0] = CMAKE_INSTALL_FULL_LIBEXECDIR "/vncserver";
-+    child_argv[1] = display;
-+    child_argv[2] = NULL;
-+
-+    execvp(child_argv[0], (char*const*)child_argv);
-+
-+    // execvp failed
-+    perror("execvp");
-+
-+    _exit(EX_OSERR);
-+}
-+
-+int
-+main(int argc, char **argv)
-+{
-+    char pid_file[PATH_MAX];
-+    FILE *f;
-+
-+    const char *username, *display;
-+
-+    if ((argc != 3) || (argv[2][0] != ':')) {
-+        fprintf(stderr, "Syntax:\n");
-+        fprintf(stderr, "    %s <username> <display>\n", argv[0]);
-+        return EX_USAGE;
-+    }
-+
-+    username = argv[1];
-+    display = argv[2];
-+
-+    if (geteuid() != 0) {
-+        fprintf(stderr, "This program needs to be run as root!\n");
-+        return EX_USAGE;
-+    }
-+
-+    if (getpwnam(username) == NULL) {
-+        if (errno == 0)
-+          fprintf(stderr, "User \"%s\" does not exist\n", username);
-+        else
-+          fprintf(stderr, "Cannot look up user \"%s\": %s\n",
-+                  username, strerror(errno));
-+        return EX_OSERR;
-+    }
-+
-+    if (begin_daemon() == -1)
-+        return EX_OSERR;
-+
-+    openlog("vncsession", LOG_PID, LOG_AUTH);
-+
-+    /* Indicate that this is a graphical user session. We need to do
-+       this here before PAM as pam_systemd.so looks at these. */
-+    if ((putenv("XDG_SESSION_CLASS=user") < 0) ||
-+        (putenv("XDG_SESSION_TYPE=x11") < 0)) {
-+        syslog(LOG_CRIT, "putenv: %s", strerror(errno));
-+        return EX_OSERR;
-+    }
-+
-+    /* Init PAM */
-+    int pamret;
-+    pam_handle_t *pamh = run_pam(&pamret, username, display);
-+    if (!pamh) {
-+        return EX_OSERR;
-+    }
-+    if (pamret != PAM_SUCCESS) {
-+        stop_pam(pamh, pamret);
-+        return EX_OSERR;
-+    }
-+
-+    char **child_env;
-+    child_env = prepare_environ(pamh);
-+    if (child_env == NULL) {
-+        syslog(LOG_CRIT, "Failure creating child process environment");
-+        stop_pam(pamh, pamret);
-+        return EX_OSERR;
-+    }
-+
-+    setup_signals();
-+
-+    script = run_script(username, display, child_env);
-+    if (script == -1) {
-+        syslog(LOG_CRIT, "Failure starting vncserver script");
-+        stop_pam(pamh, pamret);
-+        return EX_OSERR;
-+    }
-+
-+    snprintf(pid_file, sizeof(pid_file),
-+             "/var/run/vncsession-%s.pid", display);
-+    f = fopen(pid_file, "w");
-+    if (f == NULL) {
-+        syslog(LOG_ERR, "Failure creating pid file \"%s\": %s",
-+               pid_file, strerror(errno));
-+    } else {
-+        fprintf(f, "%ld\n", (long)getpid());
-+        fclose(f);
-+    }
-+
-+    finish_daemon();
-+
-+    while (1) {
-+        int status;
-+        pid_t gotpid = waitpid(script, &status, 0);
-+        if (gotpid < 0) {
-+            if (errno != EINTR) {
-+                syslog(LOG_CRIT, "waitpid: %s", strerror(errno));
-+                exit(EXIT_FAILURE);
-+            }
-+            continue;
-+        }
-+        if (WIFEXITED(status)) {
-+            if (WEXITSTATUS(status) != 0) {
-+                syslog(LOG_WARNING,
-+                        "vncsession: vncserver exited with status=%d",
-+                        WEXITSTATUS(status));
-+            }
-+            break;
-+        }
-+        else if (WIFSIGNALED(status)) {
-+            syslog(LOG_WARNING,
-+                    "vncsession: vncserver was terminated by signal %d",
-+                    WTERMSIG(status));
-+            break;
-+        }
-+    }
-+
-+    unlink(pid_file);
-+
-+    stop_pam(pamh, pamret);
-+
-+    return 0;
-+} 
-diff --git a/unix/vncserver/vncsession.man b/unix/vncserver/vncsession.man
-new file mode 100644
-index 0000000..2138209
---- /dev/null
-+++ b/unix/vncserver/vncsession.man
-@@ -0,0 +1,75 @@
-+.TH vncsession 8 "" "TigerVNC" "Virtual Network Computing"
-+.SH NAME
-+vncsession \- start a VNC server
-+.SH SYNOPSIS
-+.B vncsession
-+.RI < username >
-+.RI <: display# >
-+.SH DESCRIPTION
-+.B vncsession
-+is used to start a VNC (Virtual Network Computing) desktop.
-+.B vncsession
-+performs all the necessary steps to create a new user session, run Xvnc with
-+appropriate options and starts a window manager on the VNC desktop.
-+
-+.B vncsession
-+is rarely called directly and is normally started by the system service
-+manager.
-+
-+.SH FILES
-+Several VNC-related files are found in the directory $HOME/.vnc:
-+.TP
-+/etc/tigervnc/vncserver-config-defaults
-+The optional system-wide equivalent of $HOME/.vnc/config. If this file exists
-+and defines options to be passed to Xvnc, they will be used as defaults for
-+users. The user's $HOME/.vnc/config overrides settings configured in this file.
-+The overall configuration file load order is: this file, $HOME/.vnc/config,
-+and then /etc/tigervnc/vncserver-config-mandatory. None are required to exist.
-+.TP
-+/etc/tigervnc/vncserver-config-mandatory
-+The optional system-wide equivalent of $HOME/.vnc/config. If this file exists
-+and defines options to be passed to Xvnc, they will override any of the same
-+options defined in a user's $HOME/.vnc/config. This file offers a mechanism
-+to establish some basic form of system-wide policy. WARNING! There is
-+nothing stopping users from constructing their own vncsession-like script
-+that calls Xvnc directly to bypass any options defined in
-+/etc/tigervnc/vncserver-config-mandatory. The overall configuration file load
-+order is: /etc/tigervnc/vncserver-config-defaults, $HOME/.vnc/config, and then
-+this file. None are required to exist.
-+.TP
-+$HOME/.vnc/config
-+An optional server config file wherein options to be passed to Xvnc are listed
-+to avoid hard-coding them to the physical invocation. List options in this file
-+one per line. For those requiring an argument, simply separate the option from
-+the argument with an equal sign, for example: "geometry=2000x1200" or
-+"securitytypes=vncauth,tlsvnc". Options without an argument are simply listed
-+as a single word, for example: "localhost" or "alwaysshared".
-+
-+The special option
-+.B session
-+can be used to control which session type will be started. This should match
-+one of the files in \fI/usr/share/xsessions\fP. E.g. if there is a file called
-+"gnome.desktop", then "session=gnome" would be set to use that session type.
-+.TP
-+$HOME/.vnc/passwd
-+The VNC password file.
-+.TP
-+$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.log
-+The log file for Xvnc and the session.
-+
-+.SH SEE ALSO
-+.BR vncviewer (1),
-+.BR vncpasswd (1),
-+.BR vncconfig (1),
-+.BR Xvnc (1)
-+.br
-+https://www.tigervnc.org
-+
-+.SH AUTHOR
-+Tristan Richardson, RealVNC Ltd., D. R. Commander and others.
-+
-+VNC was originally developed by the RealVNC team while at Olivetti
-+Research Ltd / AT&T Laboratories Cambridge.  TightVNC additions were
-+implemented by Constantin Kaplinsky. Many other people have since
-+participated in development, testing and support. This manual is part
-+of the TigerVNC software suite.
-diff --git a/unix/x0vncserver/CMakeLists.txt b/unix/x0vncserver/CMakeLists.txt
-index 8beade7..af82415 100644
---- a/unix/x0vncserver/CMakeLists.txt
-+++ b/unix/x0vncserver/CMakeLists.txt
-@@ -52,5 +52,5 @@ endif()
- 
- target_link_libraries(x0vncserver ${X11_LIBRARIES})
- 
--install(TARGETS x0vncserver DESTINATION ${BIN_DIR})
--install(FILES x0vncserver.man DESTINATION ${MAN_DIR}/man1 RENAME x0vncserver.1)
-+install(TARGETS x0vncserver DESTINATION ${CMAKE_INSTALL_FULL_BINDIR})
-+install(FILES x0vncserver.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man1 RENAME x0vncserver.1)
-diff --git a/unix/xserver/hw/vnc/Xvnc.man b/unix/xserver/hw/vnc/Xvnc.man
-index 9c8a889..9559179 100644
---- a/unix/xserver/hw/vnc/Xvnc.man
-+++ b/unix/xserver/hw/vnc/Xvnc.man
-@@ -18,9 +18,9 @@ that the VNC server display number will be the same as the X server display
- number, which means you can use eg. snoopy:2 to refer to display 2 on machine
- "snoopy" in both the X world and the VNC world.
- 
--The best way of starting \fBXvnc\fP is via the \fBvncserver\fP script.  This
--sets up the environment appropriately and runs some X applications to get you
--going.  See the manual page for \fBvncserver\fP(1) for more information.
-+The best way of starting \fBXvnc\fP is via \fBvncsession\fP.  This sets up the
-+environment appropriately and starts a desktop environment. See the manual
-+page for \fBvncsession\fP(8) for more information.
- 
- .SH OPTIONS
- .B Xvnc
-@@ -383,8 +383,8 @@ created automatically the next time he connects.
- .SH SEE ALSO
- .BR vncconfig (1),
- .BR vncpasswd (1),
--.BR vncserver (1),
- .BR vncviewer (1),
-+.BR vncsession (8),
- .BR Xserver (1),
- .BR inetd (1)
- .br
-diff --git a/vncviewer/CMakeLists.txt b/vncviewer/CMakeLists.txt
-index 3c18646..7e25d45 100644
---- a/vncviewer/CMakeLists.txt
-+++ b/vncviewer/CMakeLists.txt
-@@ -60,9 +60,9 @@ if(APPLE)
-   target_link_libraries(vncviewer "-framework IOKit")
- endif()
- 
--install(TARGETS vncviewer DESTINATION ${BIN_DIR})
-+install(TARGETS vncviewer DESTINATION ${CMAKE_INSTALL_FULL_BINDIR})
- if(UNIX)
--  install(FILES vncviewer.man DESTINATION ${MAN_DIR}/man1 RENAME vncviewer.1)
-+  install(FILES vncviewer.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man1 RENAME vncviewer.1)
- 
-   configure_file(vncviewer.desktop.in.in vncviewer.desktop.in)
-   find_program(INTLTOOL_MERGE_EXECUTABLE intltool-merge)
-@@ -91,10 +91,10 @@ if(UNIX)
-     )
-   endif()
-   add_custom_target(desktop ALL DEPENDS vncviewer.desktop)
--  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/vncviewer.desktop DESTINATION ${DATA_DIR}/applications)
-+  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/vncviewer.desktop DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/applications)
- 
-   foreach(res 16 22 24 32 48)
--    install(FILES ../media/icons/tigervnc_${res}.png DESTINATION ${DATA_DIR}/icons/hicolor/${res}x${res}/apps RENAME tigervnc.png)
-+    install(FILES ../media/icons/tigervnc_${res}.png DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/${res}x${res}/apps RENAME tigervnc.png)
-   endforeach()
--  install(FILES ../media/icons/tigervnc.svg DESTINATION ${DATA_DIR}/icons/hicolor/scalable/apps)
-+  install(FILES ../media/icons/tigervnc.svg DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/scalable/apps)
- endif()
-diff --git a/vncviewer/vncviewer.cxx b/vncviewer/vncviewer.cxx
-index 4a8370b..ae4cb6f 100644
---- a/vncviewer/vncviewer.cxx
-+++ b/vncviewer/vncviewer.cxx
-@@ -227,7 +227,7 @@ static void init_fltk()
-       bool exists;
- 
-       sprintf(icon_path, "%s/icons/hicolor/%dx%d/apps/tigervnc.png",
--              DATA_DIR, icon_sizes[i], icon_sizes[i]);
-+              CMAKE_INSTALL_FULL_DATADIR, icon_sizes[i], icon_sizes[i]);
- 
- #ifndef WIN32
-       struct stat st;
-@@ -505,7 +505,7 @@ int main(int argc, char** argv)
-   argv0 = argv[0];
- 
-   setlocale(LC_ALL, "");
--  bindtextdomain(PACKAGE_NAME, LOCALE_DIR);
-+  bindtextdomain(PACKAGE_NAME, CMAKE_INSTALL_FULL_LOCALEDIR);
-   textdomain(PACKAGE_NAME);
- 
-   rfb::SecurityClient::setDefaults();
-diff --git a/vncviewer/vncviewer.desktop.in.in b/vncviewer/vncviewer.desktop.in.in
-index d775dde..9d658e4 100644
---- a/vncviewer/vncviewer.desktop.in.in
-+++ b/vncviewer/vncviewer.desktop.in.in
-@@ -2,7 +2,7 @@
- Name=TigerVNC Viewer
- GenericName=Remote Desktop Viewer
- Comment=Connect to VNC server and display remote desktop
--Exec=@BIN_DIR@/vncviewer
-+Exec=@CMAKE_INSTALL_FULL_BINDIR@/vncviewer
- Icon=tigervnc
- Terminal=false
- Type=Application
-diff --git a/vncviewer/vncviewer.man b/vncviewer/vncviewer.man
-index f93e096..a8d8c77 100644
---- a/vncviewer/vncviewer.man
-+++ b/vncviewer/vncviewer.man
-@@ -327,7 +327,7 @@ Default certificate revocation list.
- .BR Xvnc (1),
- .BR vncpasswd (1),
- .BR vncconfig (1),
--.BR vncserver (1)
-+.BR vncsession (8)
- .br
- https://www.tigervnc.org
- 
diff --git a/SOURCES/tigervnc-tolerate-specifying-boolparam.patch b/SOURCES/tigervnc-tolerate-specifying-boolparam.patch
new file mode 100644
index 0000000..70ddef3
--- /dev/null
+++ b/SOURCES/tigervnc-tolerate-specifying-boolparam.patch
@@ -0,0 +1,149 @@
+From 38c6848b30cb1908171f2b4628e345fbf6727b39 Mon Sep 17 00:00:00 2001
+From: Pierre Ossman <ossman@cendio.se>
+Date: Fri, 18 Sep 2020 10:44:32 +0200
+Subject: [PATCH] Tolerate specifying -BoolParam 0 and similar
+
+This is needed by vncserver which doesn't know which parameters are
+boolean, and it cannot use the -Param=Value form as that isn't tolerated
+by the Xorg code.
+---
+ unix/vncserver/vncserver.in    |  8 ++++----
+ unix/xserver/hw/vnc/RFBGlue.cc | 16 ++++++++++++++++
+ unix/xserver/hw/vnc/RFBGlue.h  |  1 +
+ unix/xserver/hw/vnc/xvnc.c     | 14 ++++++++++++++
+ vncviewer/vncviewer.cxx        | 20 ++++++++++++++++++++
+ 5 files changed, 55 insertions(+), 4 deletions(-)
+
+diff --git a/unix/vncserver/vncserver.in b/unix/vncserver/vncserver.in
+index 25fbbd315..261b258f1 100755
+--- a/unix/vncserver/vncserver.in
++++ b/unix/vncserver/vncserver.in
+@@ -107,7 +107,7 @@ $default_opts{rfbwait} = 30000;
+ $default_opts{rfbauth} = "$vncUserDir/passwd";
+ $default_opts{rfbport} = $vncPort;
+ $default_opts{fp} = $fontPath if ($fontPath);
+-$default_opts{pn} = "";
++$default_opts{pn} = undef;
+ 
+ # Load user-overrideable system defaults
+ LoadConfig($vncSystemConfigDefaultsFile);
+@@ -242,13 +242,13 @@ push(@cmd, "@CMAKE_INSTALL_FULL_BINDIR@/Xvnc", ":$displayNumber");
+ 
+ foreach my $k (sort keys %config) {
+   push(@cmd, "-$k");
+-  push(@cmd, $config{$k}) if $config{$k};
++  push(@cmd, $config{$k}) if defined($config{$k});
+   delete $default_opts{$k}; # file options take precedence
+ }
+ 
+ foreach my $k (sort keys %default_opts) {
+   push(@cmd, "-$k");
+-  push(@cmd, $default_opts{$k}) if $default_opts{$k};
++  push(@cmd, $default_opts{$k}) if defined($default_opts{$k});
+ }
+ 
+ warn "\nNew '$desktopName' desktop is $host:$displayNumber\n\n";
+@@ -291,7 +291,7 @@ sub LoadConfig {
+           # current config file being loaded defined the logical opposite setting
+           # (NeverShared vs. AlwaysShared, etc etc).
+           $toggle = lc($1); # must normalize key case
+-          $config{$toggle} = $k;
++          $config{$toggle} = undef;
+         }
+       }
+       close(IN);
+diff --git a/unix/xserver/hw/vnc/RFBGlue.cc b/unix/xserver/hw/vnc/RFBGlue.cc
+index f108fae43..7c32bea8f 100644
+--- a/unix/xserver/hw/vnc/RFBGlue.cc
++++ b/unix/xserver/hw/vnc/RFBGlue.cc
+@@ -143,6 +143,22 @@ const char* vncGetParamDesc(const char *name)
+   return param->getDescription();
+ }
+ 
++int vncIsParamBool(const char *name)
++{
++  VoidParameter *param;
++  BoolParameter *bparam;
++
++  param = rfb::Configuration::getParam(name);
++  if (param == NULL)
++    return false;
++
++  bparam = dynamic_cast<BoolParameter*>(param);
++  if (bparam == NULL)
++    return false;
++
++  return true;
++}
++
+ int vncGetParamCount(void)
+ {
+   int count;
+diff --git a/unix/xserver/hw/vnc/RFBGlue.h b/unix/xserver/hw/vnc/RFBGlue.h
+index 112405b84..695cea105 100644
+--- a/unix/xserver/hw/vnc/RFBGlue.h
++++ b/unix/xserver/hw/vnc/RFBGlue.h
+@@ -41,6 +41,7 @@ int vncSetParam(const char *name, const char *value);
+ int vncSetParamSimple(const char *nameAndValue);
+ char* vncGetParam(const char *name);
+ const char* vncGetParamDesc(const char *name);
++int vncIsParamBool(const char *name);
+ 
+ int vncGetParamCount(void);
+ char *vncGetParamList(void);
+diff --git a/unix/xserver/hw/vnc/xvnc.c b/unix/xserver/hw/vnc/xvnc.c
+index 4eb0b0b13..5744acac8 100644
+--- a/unix/xserver/hw/vnc/xvnc.c
++++ b/unix/xserver/hw/vnc/xvnc.c
+@@ -618,6 +618,20 @@ ddxProcessArgument(int argc, char *argv[], int i)
+         exit(0);
+     }
+ 
++    /* We need to resolve an ambiguity for booleans */
++    if (argv[i][0] == '-' && i+1 < argc &&
++        vncIsParamBool(&argv[i][1])) {
++        if ((strcasecmp(argv[i+1], "0") == 0) ||
++            (strcasecmp(argv[i+1], "1") == 0) ||
++            (strcasecmp(argv[i+1], "true") == 0) ||
++            (strcasecmp(argv[i+1], "false") == 0) ||
++            (strcasecmp(argv[i+1], "yes") == 0) ||
++            (strcasecmp(argv[i+1], "no") == 0)) {
++            vncSetParam(&argv[i][1], argv[i+1]);
++            return 2;
++        }
++    }
++
+     if (vncSetParamSimple(argv[i]))
+ 	return 1;
+     
+diff --git a/vncviewer/vncviewer.cxx b/vncviewer/vncviewer.cxx
+index d4dd3063c..77ba3d3f4 100644
+--- a/vncviewer/vncviewer.cxx
++++ b/vncviewer/vncviewer.cxx
+@@ -556,6 +556,26 @@ int main(int argc, char** argv)
+   }
+ 
+   for (int i = 1; i < argc;) {
++    /* We need to resolve an ambiguity for booleans */
++    if (argv[i][0] == '-' && i+1 < argc) {
++        VoidParameter *param;
++
++        param = Configuration::getParam(&argv[i][1]);
++        if ((param != NULL) &&
++            (dynamic_cast<BoolParameter*>(param) != NULL)) {
++          if ((strcasecmp(argv[i+1], "0") == 0) ||
++              (strcasecmp(argv[i+1], "1") == 0) ||
++              (strcasecmp(argv[i+1], "true") == 0) ||
++              (strcasecmp(argv[i+1], "false") == 0) ||
++              (strcasecmp(argv[i+1], "yes") == 0) ||
++              (strcasecmp(argv[i+1], "no") == 0)) {
++              param->setParam(argv[i+1]);
++              i += 2;
++              continue;
++          }
++      }
++    }
++
+     if (Configuration::setParam(argv[i])) {
+       i++;
+       continue;
diff --git a/SOURCES/tigervnc-use-gnome-as-default-session.patch b/SOURCES/tigervnc-use-gnome-as-default-session.patch
new file mode 100644
index 0000000..a767c40
--- /dev/null
+++ b/SOURCES/tigervnc-use-gnome-as-default-session.patch
@@ -0,0 +1,12 @@
+diff --git a/unix/vncserver/vncserver-config-defaults b/unix/vncserver/vncserver-config-defaults
+index 0c217bf..2889347 100644
+--- a/unix/vncserver/vncserver-config-defaults
++++ b/unix/vncserver/vncserver-config-defaults
+@@ -13,3 +13,7 @@
+ # geometry=2000x1200
+ # localhost
+ # alwaysshared
++
++# Default to GNOME session
++# Note: change this only when you know what are you doing
++session=gnome
diff --git a/SOURCES/vncserver b/SOURCES/vncserver
new file mode 100644
index 0000000..bd2f422
--- /dev/null
+++ b/SOURCES/vncserver
@@ -0,0 +1,890 @@
+#!/usr/bin/perl
+#
+#  Copyright (C) 2009-2010 D. R. Commander.  All Rights Reserved.
+#  Copyright (C) 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+#  Copyright (C) 2002-2003 Constantin Kaplinsky.  All Rights Reserved.
+#  Copyright (C) 2002-2005 RealVNC Ltd.
+#  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
+#
+#  This is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This software is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this software; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+#  USA.
+#
+
+#
+# vncserver - wrapper script to start an X VNC server.
+#
+
+# First make sure we're operating in a sane environment.
+$exedir = "";
+$slashndx = rindex($0, "/");
+if($slashndx>=0) {
+    $exedir = substr($0, 0, $slashndx+1);
+}
+
+&SanityCheck();
+
+&NotifyAboutDeprecation();
+
+#
+# Global variables.  You may want to configure some of these for
+# your site
+#
+
+$geometry = "1024x768";
+#$depth = 16;
+
+$vncUserDir = "$ENV{HOME}/.vnc";
+$vncUserConfig = "$vncUserDir/config";
+
+$vncSystemConfigDir = "/etc/tigervnc";
+$vncSystemConfigDefaultsFile = "$vncSystemConfigDir/vncserver-config-defaults";
+$vncSystemConfigMandatoryFile = "$vncSystemConfigDir/vncserver-config-mandatory";
+
+$skipxstartup = 0;
+$xauthorityFile = "$ENV{XAUTHORITY}" || "$ENV{HOME}/.Xauthority";
+
+$xstartupFile = $vncUserDir . "/xstartup";
+$defaultXStartup
+    = ("#!/bin/sh\n\n".
+       "unset SESSION_MANAGER\n".
+       "unset DBUS_SESSION_BUS_ADDRESS\n".
+       "exec /etc/X11/xinit/xinitrc\n");
+
+$defaultConfig
+    = ("## Supported server options to pass to vncserver upon invocation can be listed\n".
+       "## in this file. See the following manpages for more: vncserver(1) Xvnc(1).\n".
+       "## Several common ones are shown below. Uncomment and modify to your liking.\n".
+       "##\n".
+       "# securitytypes=vncauth,tlsvnc\n".
+       "# desktop=sandbox\n".
+       "# geometry=2000x1200\n".
+       "# localhost\n".
+       "# alwaysshared\n");
+
+chop($host = `uname -n`);
+
+if (-d "/etc/X11/fontpath.d") {
+    $fontPath = "catalogue:/etc/X11/fontpath.d";
+}
+
+@fontpaths = ('/usr/share/X11/fonts', '/usr/share/fonts', '/usr/share/fonts/X11/');
+if (! -l "/usr/lib/X11") {push(@fontpaths, '/usr/lib/X11/fonts');}
+if (! -l "/usr/X11") {push(@fontpaths, '/usr/X11/lib/X11/fonts');}
+if (! -l "/usr/X11R6") {push(@fontpaths, '/usr/X11R6/lib/X11/fonts');}
+push(@fontpaths, '/usr/share/fonts/default');
+
+@fonttypes = ('misc',
+             '75dpi',
+             '100dpi',
+             'Speedo',
+             'Type1');
+
+foreach $_fpath (@fontpaths) {
+    foreach $_ftype (@fonttypes) {
+        if (-f "$_fpath/$_ftype/fonts.dir") {
+            if (! -l "$_fpath/$_ftype") {
+                $defFontPath .= "$_fpath/$_ftype,";
+            }
+        }
+    }
+}
+
+if ($defFontPath) {
+    if (substr($defFontPath, -1, 1) == ',') {
+        chop $defFontPath;
+    }
+}
+
+if ($fontPath eq "") {
+    $fontPath = $defFontPath;
+}
+
+# Check command line options
+
+&ParseOptions("-geometry",1,"-depth",1,"-pixelformat",1,"-name",1,"-kill",1,
+	      "-help",0,"-h",0,"--help",0,"-fp",1,"-list",0,"-fg",0,"-autokill",0,"-noxstartup",0,"-xstartup",1);
+
+&Usage() if ($opt{'-help'} || $opt{'-h'} || $opt{'--help'});
+
+&Kill() if ($opt{'-kill'});
+
+&List() if ($opt{'-list'});
+
+# Uncomment this line if you want default geometry, depth and pixelformat
+# to match the current X display:
+# &GetXDisplayDefaults();
+
+if ($opt{'-geometry'}) {
+    $geometry = $opt{'-geometry'};
+}
+if ($opt{'-depth'}) {
+    $depth = $opt{'-depth'};
+    $pixelformat = "";
+}
+if ($opt{'-pixelformat'}) {
+    $pixelformat = $opt{'-pixelformat'};
+}
+if ($opt{'-noxstartup'}) {
+    $skipxstartup = 1;
+}
+if ($opt{'-xstartup'}) {
+    $xstartupFile = $opt{'-xstartup'};
+}
+if ($opt{'-fp'}) {
+    $fontPath = $opt{'-fp'};
+    $fpArgSpecified = 1;
+}
+
+&CheckGeometryAndDepth();
+
+# Create the user's vnc directory if necessary.
+if (!(-e $vncUserDir)) {
+    if (!mkdir($vncUserDir,0755)) {
+	die "$prog: Could not create $vncUserDir.\n";
+    }
+}
+
+# Find display number.
+if ((@ARGV > 0) && ($ARGV[0] =~ /^:(\d+)$/)) {
+    $displayNumber = $1;
+    shift(@ARGV);
+    if (!&CheckDisplayNumber($displayNumber)) {
+	die "A VNC server is already running as :$displayNumber\n";
+    }
+} elsif ((@ARGV > 0) && ($ARGV[0] !~ /^-/) && ($ARGV[0] !~ /^\+/)) {
+    &Usage();
+} else {
+    $displayNumber = &GetDisplayNumber();
+}
+
+$vncPort = 5900 + $displayNumber;
+
+if ($opt{'-name'}) {
+    $desktopName = $opt{'-name'};
+} else {
+    $desktopName = "$host:$displayNumber ($ENV{USER})";
+}
+
+my %default_opts;
+my %config;
+
+# We set some reasonable defaults. Config file settings
+# override these where present.
+$default_opts{desktop} = &quotedString($desktopName);
+$default_opts{auth} = &quotedString($xauthorityFile);
+$default_opts{geometry} = $geometry if ($geometry);
+$default_opts{depth} = $depth if ($depth);
+$default_opts{pixelformat} = $pixelformat if ($pixelformat);
+$default_opts{rfbwait} = 30000;
+$default_opts{rfbauth} = "$vncUserDir/passwd";
+$default_opts{rfbport} = $vncPort;
+$default_opts{fp} = $fontPath if ($fontPath);
+$default_opts{pn} = "";
+
+# Load user-overrideable system defaults
+LoadConfig($vncSystemConfigDefaultsFile);
+
+# Then the user's settings
+LoadConfig($vncUserConfig);
+
+# And then override anything set above if mandatory settings exist.
+# WARNING: "Mandatory" is used loosely here! As the man page says,
+# there is nothing stopping someone from EASILY subverting the
+# settings in $vncSystemConfigMandatoryFile by simply passing
+# CLI args to vncserver, which trump config files! To properly
+# hard force policy in a non-subvertible way would require major
+# development work that touches Xvnc itself.
+LoadConfig($vncSystemConfigMandatoryFile, 1);
+
+#
+# Check whether VNC authentication is enabled, and if so, prompt the user to
+# create a VNC password if they don't already have one.
+#
+
+$securityTypeArgSpecified = 0;
+$vncAuthEnabled = 0;
+$passwordArgSpecified = 0;
+@vncAuthStrings = ("vncauth", "tlsvnc", "x509vnc");
+
+# ...first we check our configuration files' settings
+if ($config{'securitytypes'}) {
+  $securityTypeArgSpecified = 1;
+  foreach $arg2 (split(',', $config{'securitytypes'})) {
+    if (grep {$_ eq lc($arg2)} @vncAuthStrings) {
+      $vncAuthEnabled = 1;
+    }
+  }
+}
+
+# ...and finally we check CLI args, which in the case of the topic at
+# hand (VNC auth or not), override anything found in configuration files
+# (even so-called "mandatory" settings).
+for ($i = 0; $i < @ARGV; ++$i) {
+    # -SecurityTypes can be followed by a space or "="
+    my @splitargs = split('=', $ARGV[$i]);
+    if (@splitargs <= 1 && $i < @ARGV - 1) {
+        push(@splitargs, $ARGV[$i + 1]);
+    }
+    if (lc(@splitargs[0]) eq "-securitytypes") {
+        if (@splitargs > 1) {
+            $securityTypeArgSpecified = 1;
+        }
+        foreach $arg2 (split(',', @splitargs[1])) {
+            if (grep {$_ eq lc($arg2)} @vncAuthStrings) {
+                $vncAuthEnabled = 1;
+            }
+        }
+    }
+    if ((lc(@splitargs[0]) eq "-password")
+     || (lc(@splitargs[0]) eq "-passwordfile"
+     || (lc(@splitargs[0]) eq "-rfbauth"))) {
+        $passwordArgSpecified = 1;
+    }
+}
+
+if ((!$securityTypeArgSpecified || $vncAuthEnabled) && !$passwordArgSpecified) {
+    ($z,$z,$mode) = stat("$vncUserDir/passwd");
+    if (!(-e "$vncUserDir/passwd") || ($mode & 077)) {
+        warn "\nYou will require a password to access your desktops.\n\n";
+        system($exedir."vncpasswd -q $vncUserDir/passwd");
+        if (($? >> 8) != 0) {
+            exit 1;
+        }
+    }
+}
+
+$desktopLog = "$vncUserDir/$host:$displayNumber.log";
+unlink($desktopLog);
+
+# Make an X server cookie and set up the Xauthority file
+# mcookie is a part of util-linux, usually only GNU/Linux systems have it.
+$cookie = `mcookie`;
+# Fallback for non GNU/Linux OS - use /dev/urandom on systems that have it,
+# otherwise use perl's random number generator, seeded with the sum
+# of the current time, our PID and part of the encrypted form of the password.
+if ($cookie eq "" && open(URANDOM, '<', '/dev/urandom')) {
+  my $randata;
+  if (sysread(URANDOM, $randata, 16) == 16) {
+    $cookie = unpack 'h*', $randata;
+  }
+  close(URANDOM);
+}
+if ($cookie eq "") {
+  srand(time+$$+unpack("L",`cat $vncUserDir/passwd`));
+  for (1..16) {
+    $cookie .= sprintf("%02x", int(rand(256)) % 256);
+  }
+}
+
+open(XAUTH, "|xauth -f $xauthorityFile source -");
+print XAUTH "add $host:$displayNumber . $cookie\n";
+print XAUTH "add $host/unix:$displayNumber . $cookie\n";
+close(XAUTH);
+
+# Now start the X VNC Server
+
+# We build up our Xvnc command with options
+$cmd = $exedir."Xvnc :$displayNumber";
+
+foreach my $k (sort keys %config) {
+  $cmd .= " -$k $config{$k}";
+  delete $default_opts{$k}; # file options take precedence
+}
+
+foreach my $k (sort keys %default_opts) {
+  $cmd .= " -$k $default_opts{$k}";
+}
+
+# Add color database stuff here, e.g.:
+# $cmd .= " -co /usr/lib/X11/rgb";
+
+foreach $arg (@ARGV) {
+  $cmd .= " " . &quotedString($arg);
+}
+$cmd .= " >> " . &quotedString($desktopLog) . " 2>&1";
+
+# Run $cmd and record the process ID.
+$pidFile = "$vncUserDir/$host:$displayNumber.pid";
+system("$cmd & echo \$! >$pidFile");
+
+# Give Xvnc a chance to start up
+
+sleep(3);
+if ($fontPath ne $defFontPath) {
+    unless (kill 0, `cat $pidFile`) {
+        if ($fpArgSpecified) {
+	    warn "\nWARNING: The first attempt to start Xvnc failed, probably because the font\n";
+	    warn "path you specified using the -fp argument is incorrect.  Attempting to\n";
+	    warn "determine an appropriate font path for this system and restart Xvnc using\n";
+	    warn "that font path ...\n";
+        } else {
+	    warn "\nWARNING: The first attempt to start Xvnc failed, possibly because the font\n";
+	    warn "catalog is not properly configured.  Attempting to determine an appropriate\n";
+	    warn "font path for this system and restart Xvnc using that font path ...\n";
+        }
+	$cmd =~ s@-fp [^ ]+@@;
+	$cmd .= " -fp $defFontPath" if ($defFontPath);
+	system("$cmd & echo \$! >$pidFile");
+	sleep(3);
+    }
+}
+unless (kill 0, `cat $pidFile`) {
+    warn "Could not start Xvnc.\n\n";
+    unlink $pidFile;
+    open(LOG, "<$desktopLog");
+    while (<LOG>) { print; }
+    close(LOG);
+    die "\n";
+}
+
+warn "\nNew '$desktopName' desktop is $host:$displayNumber\n\n";
+
+# Create the user's xstartup script if necessary.
+if (! $skipxstartup) {
+    if (!(-e "$xstartupFile")) {
+	warn "Creating default startup script $xstartupFile\n";
+	open(XSTARTUP, ">$xstartupFile");
+        print XSTARTUP $defaultXStartup;
+        close(XSTARTUP);
+        chmod 0755, "$xstartupFile";
+    }
+}
+
+# Create the user's config file if necessary.
+if (!(-e "$vncUserDir/config")) {
+    warn "Creating default config $vncUserDir/config\n";
+    open(VNCUSERCONFIG, ">$vncUserDir/config");
+    print VNCUSERCONFIG $defaultConfig;
+    close(VNCUSERCONFIG);
+    chmod 0644, "$vncUserDir/config";
+}
+
+# Run the X startup script.
+if (! $skipxstartup) {
+    warn "Starting applications specified in $xstartupFile\n";
+}
+warn "Log file is $desktopLog\n\n";
+
+# If the unix domain socket exists then use that (DISPLAY=:n) otherwise use
+# TCP (DISPLAY=host:n)
+
+if (-e "/tmp/.X11-unix/X$displayNumber" ||
+    -e "/usr/spool/sockets/X11/$displayNumber")
+{
+    $ENV{DISPLAY}= ":$displayNumber";
+} else {
+    $ENV{DISPLAY}= "$host:$displayNumber";
+}
+$ENV{VNCDESKTOP}= $desktopName;
+
+if ($opt{'-fg'}) {
+    if (! $skipxstartup) {
+        system("$xstartupFile >> " . &quotedString($desktopLog) . " 2>&1");
+    }
+    if (kill 0, `cat $pidFile`) {
+        $opt{'-kill'} = ':'.$displayNumber;
+        &Kill();
+    }
+} else {
+    if ($opt{'-autokill'}) {
+    	if (! $skipxstartup) {
+            system("($xstartupFile; $0 -kill :$displayNumber) >> "
+	     . &quotedString($desktopLog) . " 2>&1 &");
+    	}
+    } else {
+    	if (! $skipxstartup) {
+            system("$xstartupFile >> " . &quotedString($desktopLog)
+	     . " 2>&1 &");
+    	}
+    }
+}
+
+exit;
+
+###############################################################################
+# Functions
+###############################################################################
+
+#
+# Populate the global %config hash with settings from a specified
+# vncserver configuration file if it exists
+#
+# Args: 1. file path
+#       2. optional boolean flag to enable warning when a previously
+#          set configuration setting is being overridden
+#
+sub LoadConfig {
+  local ($configFile, $warnoverride) = @_;
+  local ($toggle) = undef;
+
+  if (stat($configFile)) {
+    if (open(IN, $configFile)) {
+      while (<IN>) {
+        next if /^#/;
+        if (my ($k, $v) = /^\s*(\w+)\s*=\s*(.+)$/) {
+          $k = lc($k); # must normalize key case
+          if ($k eq "session") {
+            next;
+          }
+          if ($warnoverride && $config{$k}) {
+            print("Warning: $configFile is overriding previously defined '$k' to be '$v'\n");
+          }
+          $config{$k} = $v;
+        } elsif ($_ =~ m/^\s*(\S+)/) {
+          # We can't reasonably warn on override of toggles (e.g. AlwaysShared)
+          # because it would get crazy to do so. We'd have to check if the
+          # current config file being loaded defined the logical opposite setting
+          # (NeverShared vs. AlwaysShared, etc etc).
+          $toggle = lc($1); # must normalize key case
+          $config{$toggle} = $k;
+        }
+      }
+      close(IN);
+    }
+  }
+}
+
+#
+# CheckGeometryAndDepth simply makes sure that the geometry and depth values
+# are sensible.
+#
+
+sub CheckGeometryAndDepth
+{
+    if ($geometry =~ /^(\d+)x(\d+)$/) {
+	$width = $1; $height = $2;
+
+	if (($width<1) || ($height<1)) {
+	    die "$prog: geometry $geometry is invalid\n";
+	}
+
+	$geometry = "${width}x$height";
+    } else {
+	die "$prog: geometry $geometry is invalid\n";
+    }
+
+    if ($depth && (($depth < 8) || ($depth > 32))) {
+	die "Depth must be between 8 and 32\n";
+    }
+}
+
+
+#
+# GetDisplayNumber gets the lowest available display number.  A display number
+# n is taken if something is listening on the VNC server port (5900+n) or the
+# X server port (6000+n).
+#
+
+sub GetDisplayNumber
+{
+    foreach $n (1..99) {
+	if (&CheckDisplayNumber($n)) {
+	    return $n+0; # Bruce Mah's workaround for bug in perl 5.005_02
+	}
+    }
+
+    die "$prog: no free display number on $host.\n";
+}
+
+
+#
+# CheckDisplayNumber checks if the given display number is available.  A
+# display number n is taken if something is listening on the VNC server port
+# (5900+n) or the X server port (6000+n).
+#
+
+sub CheckDisplayNumber
+{
+    local ($n) = @_;
+
+    socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n";
+    eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))';
+    if (!bind(S, pack('S n x12', $AF_INET, 6000 + $n))) {
+	close(S);
+	return 0;
+    }
+    close(S);
+
+    socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n";
+    eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))';
+    if (!bind(S, pack('S n x12', $AF_INET, 5900 + $n))) {
+	close(S);
+	return 0;
+    }
+    close(S);
+
+    if (-e "/tmp/.X$n-lock") {
+	warn "\nWarning: $host:$n is taken because of /tmp/.X$n-lock\n";
+	warn "Remove this file if there is no X server $host:$n\n";
+	return 0;
+    }
+
+    if (-e "/tmp/.X11-unix/X$n") {
+	warn "\nWarning: $host:$n is taken because of /tmp/.X11-unix/X$n\n";
+	warn "Remove this file if there is no X server $host:$n\n";
+	return 0;
+    }
+
+    if (-e "/usr/spool/sockets/X11/$n") {
+	warn("\nWarning: $host:$n is taken because of ".
+             "/usr/spool/sockets/X11/$n\n");
+	warn "Remove this file if there is no X server $host:$n\n";
+	return 0;
+    }
+
+    return 1;
+}
+
+
+#
+# GetXDisplayDefaults uses xdpyinfo to find out the geometry, depth and pixel
+# format of the current X display being used.  If successful, it sets the
+# options as appropriate so that the X VNC server will use the same settings
+# (minus an allowance for window manager decorations on the geometry).  Using
+# the same depth and pixel format means that the VNC server won't have to
+# translate pixels when the desktop is being viewed on this X display (for
+# TrueColor displays anyway).
+#
+
+sub GetXDisplayDefaults
+{
+    local (@lines, @matchlines, $width, $height, $defaultVisualId, $i,
+	   $red, $green, $blue);
+
+    $wmDecorationWidth = 4;	# a guess at typical size for window manager
+    $wmDecorationHeight = 24;	# decoration size
+
+    return if (!defined($ENV{DISPLAY}));
+
+    @lines = `xdpyinfo 2>/dev/null`;
+
+    return if ($? != 0);
+
+    @matchlines = grep(/dimensions/, @lines);
+    if (@matchlines) {
+	($width, $height) = ($matchlines[0] =~ /(\d+)x(\d+) pixels/);
+
+	$width -= $wmDecorationWidth;
+	$height -= $wmDecorationHeight;
+
+	$geometry = "${width}x$height";
+    }
+
+    @matchlines = grep(/default visual id/, @lines);
+    if (@matchlines) {
+	($defaultVisualId) = ($matchlines[0] =~ /id:\s+(\S+)/);
+
+	for ($i = 0; $i < @lines; $i++) {
+	    if ($lines[$i] =~ /^\s*visual id:\s+$defaultVisualId$/) {
+		if (($lines[$i+1] !~ /TrueColor/) ||
+		    ($lines[$i+2] !~ /depth/) ||
+		    ($lines[$i+4] !~ /red, green, blue masks/))
+		{
+		    return;
+		}
+		last;
+	    }
+	}
+
+	return if ($i >= @lines);
+
+	($depth) = ($lines[$i+2] =~ /depth:\s+(\d+)/);
+	($red,$green,$blue)
+	    = ($lines[$i+4]
+	       =~ /masks:\s+0x([0-9a-f]+), 0x([0-9a-f]+), 0x([0-9a-f]+)/);
+
+	$red = hex($red);
+	$green = hex($green);
+	$blue = hex($blue);
+
+	if ($red > $blue) {
+	    $red = int(log($red) / log(2)) - int(log($green) / log(2));
+	    $green = int(log($green) / log(2)) - int(log($blue) / log(2));
+	    $blue = int(log($blue) / log(2)) + 1;
+	    $pixelformat = "rgb$red$green$blue";
+	} else {
+	    $blue = int(log($blue) / log(2)) - int(log($green) / log(2));
+	    $green = int(log($green) / log(2)) - int(log($red) / log(2));
+	    $red = int(log($red) / log(2)) + 1;
+	    $pixelformat = "bgr$blue$green$red";
+	}
+    }
+}
+
+
+#
+# quotedString returns a string which yields the original string when parsed
+# by a shell.
+#
+
+sub quotedString
+{
+    local ($in) = @_;
+
+    $in =~ s/\'/\'\"\'\"\'/g;
+
+    return "'$in'";
+}
+
+
+#
+# removeSlashes turns slashes into underscores for use as a file name.
+#
+
+sub removeSlashes
+{
+    local ($in) = @_;
+
+    $in =~ s|/|_|g;
+
+    return "$in";
+}
+
+
+#
+# Usage
+#
+
+sub Usage
+{
+    die("\nusage: $prog [:<number>] [-name <desktop-name>] [-depth <depth>]\n".
+	"                 [-geometry <width>x<height>]\n".
+	"                 [-pixelformat rgbNNN|bgrNNN]\n".
+	"                 [-fp <font-path>]\n".
+	"                 [-cc <visual>]\n".            
+	"                 [-fg]\n".
+	"                 [-autokill]\n".
+	"                 [-noxstartup]\n".
+	"                 [-xstartup <file>]\n".
+	"                 <Xvnc-options>...\n\n".
+	"       $prog -kill <X-display>\n\n".
+	"       $prog -list\n\n");
+}
+
+
+#
+# List
+#
+
+sub List
+{
+    opendir(dir, $vncUserDir);
+    my @filelist = readdir(dir);
+    closedir(dir);
+    print "\nTigerVNC server sessions:\n\n";
+    print "X DISPLAY #\tPROCESS ID\n";
+    foreach my $file (@filelist) {
+	if ($file =~ /$host:(\d+)$\.pid/) {
+	    chop($tmp_pid = `cat $vncUserDir/$file`);
+	    if (kill 0, $tmp_pid) {
+		print ":".$1."\t\t".`cat $vncUserDir/$file`;
+	    } else {
+		unlink ($vncUserDir . "/" . $file);
+	    }
+	}
+    }
+    exit;
+}
+
+
+#
+# Kill
+#
+
+sub Kill
+{
+    $opt{'-kill'} =~ s/(:\d+)\.\d+$/$1/; # e.g. turn :1.0 into :1
+
+    if ($opt{'-kill'} =~ /^:\d+$/) {
+	$pidFile = "$vncUserDir/$host$opt{'-kill'}.pid";
+    } else {
+	if ($opt{'-kill'} !~ /^$host:/) {
+	    die "\nCan't tell if $opt{'-kill'} is on $host\n".
+		"Use -kill :<number> instead\n\n";
+	}
+	$pidFile = "$vncUserDir/$opt{'-kill'}.pid";
+    }
+
+    if (! -r $pidFile) {
+	die "\nCan't find file $pidFile\n".
+	    "You'll have to kill the Xvnc process manually\n\n";
+    }
+
+    $SIG{'HUP'} = 'IGNORE';
+    chop($pid = `cat $pidFile`);
+    warn "Killing Xvnc process ID $pid\n";
+
+    if (kill 0, $pid) {
+	system("kill $pid");
+	sleep(1);
+	if (kill 0, $pid) {
+	    print "Xvnc seems to be deadlocked.  Kill the process manually and then re-run\n";
+	    print "    ".$0." -kill ".$opt{'-kill'}."\n";
+	    print "to clean up the socket files.\n";
+	    exit
+	}
+
+    } else {
+	warn "Xvnc process ID $pid already killed\n";
+	$opt{'-kill'} =~ s/://;
+
+	if (-e "/tmp/.X11-unix/X$opt{'-kill'}") {
+	    print "Xvnc did not appear to shut down cleanly.";
+	    print " Removing /tmp/.X11-unix/X$opt{'-kill'}\n";
+	    unlink "/tmp/.X11-unix/X$opt{'-kill'}";
+	}
+	if (-e "/tmp/.X$opt{'-kill'}-lock") {
+	    print "Xvnc did not appear to shut down cleanly.";
+	    print " Removing /tmp/.X$opt{'-kill'}-lock\n";
+	    unlink "/tmp/.X$opt{'-kill'}-lock";
+	}
+    }
+
+    unlink $pidFile;
+    exit;
+}
+
+
+#
+# ParseOptions takes a list of possible options and a boolean indicating
+# whether the option has a value following, and sets up an associative array
+# %opt of the values of the options given on the command line. It removes all
+# the arguments it uses from @ARGV and returns them in @optArgs.
+#
+
+sub ParseOptions
+{
+    local (@optval) = @_;
+    local ($opt, @opts, %valFollows, @newargs);
+
+    while (@optval) {
+	$opt = shift(@optval);
+	push(@opts,$opt);
+	$valFollows{$opt} = shift(@optval);
+    }
+
+    @optArgs = ();
+    %opt = ();
+
+    arg: while (defined($arg = shift(@ARGV))) {
+	foreach $opt (@opts) {
+	    if ($arg eq $opt) {
+		push(@optArgs, $arg);
+		if ($valFollows{$opt}) {
+		    if (@ARGV == 0) {
+			&Usage();
+		    }
+		    $opt{$opt} = shift(@ARGV);
+		    push(@optArgs, $opt{$opt});
+		} else {
+		    $opt{$opt} = 1;
+		}
+		next arg;
+	    }
+	}
+	push(@newargs,$arg);
+    }
+
+    @ARGV = @newargs;
+}
+
+
+# Routine to make sure we're operating in a sane environment.
+sub SanityCheck
+{
+    local ($cmd);
+
+    # Get the program name
+    ($prog) = ($0 =~ m|([^/]+)$|);
+
+    #
+    # Check we have all the commands we'll need on the path.
+    #
+
+ cmd:
+    foreach $cmd ("uname","xauth") {
+	for (split(/:/,$ENV{PATH})) {
+	    if (-x "$_/$cmd") {
+		next cmd;
+	    }
+	}
+	die "$prog: couldn't find \"$cmd\" on your PATH.\n";
+    }
+
+    if($exedir eq "") {
+      cmd2:
+	foreach $cmd ("Xvnc","vncpasswd") {
+	    for (split(/:/,$ENV{PATH})) {
+		if (-x "$_/$cmd") {
+		    next cmd2;
+		}
+	    }
+	    die "$prog: couldn't find \"$cmd\" on your PATH.\n";
+	}
+    }
+    else {
+      cmd3:
+	foreach $cmd ($exedir."Xvnc",$exedir."vncpasswd") {
+	    for (split(/:/,$ENV{PATH})) {
+		if (-x "$cmd") {
+		    next cmd3;
+		}
+	    }
+	    die "$prog: couldn't find \"$cmd\".\n";
+	}
+    }
+
+    if (!defined($ENV{HOME})) {
+	die "$prog: The HOME environment variable is not set.\n";
+    }
+
+    #
+    # Find socket constants. 'use Socket' is a perl5-ism, so we wrap it in an
+    # eval, and if it fails we try 'require "sys/socket.ph"'.  If this fails,
+    # we just guess at the values.  If you find perl moaning here, just
+    # hard-code the values of AF_INET and SOCK_STREAM.  You can find these out
+    # for your platform by looking in /usr/include/sys/socket.h and related
+    # files.
+    #
+
+    chop($os = `uname`);
+    chop($osrev = `uname -r`);
+
+    eval 'use Socket';
+    if ($@) {
+	eval 'require "sys/socket.ph"';
+	if ($@) {
+	    if (($os eq "SunOS") && ($osrev !~ /^4/)) {
+		$AF_INET = 2;
+		$SOCK_STREAM = 2;
+	    } else {
+		$AF_INET = 2;
+		$SOCK_STREAM = 1;
+	    }
+	} else {
+	    $AF_INET = &AF_INET;
+	    $SOCK_STREAM = &SOCK_STREAM;
+	}
+    } else {
+	$AF_INET = &AF_INET;
+	$SOCK_STREAM = &SOCK_STREAM;
+    }
+} 
+
+sub NotifyAboutDeprecation
+{
+    warn "\nWARNING: vncserver has been replaced by a systemd unit and is about to be removed in future releases.\n";
+    warn "Please read /usr/share/doc/tigervnc/HOWTO.md for more information.\n";
+}
diff --git a/SOURCES/vncserver.man b/SOURCES/vncserver.man
new file mode 100644
index 0000000..2641ed1
--- /dev/null
+++ b/SOURCES/vncserver.man
@@ -0,0 +1,204 @@
+.TH vncserver 1 "" "TigerVNC" "Virtual Network Computing"
+.SH NAME
+vncserver \- start or stop a VNC server
+.SH SYNOPSIS
+.B vncserver
+.RI [: display# ]
+.RB [ \-name
+.IR desktop-name ]
+.RB [ \-geometry
+.IR width x height ]
+.RB [ \-depth
+.IR depth ]
+.RB [ \-pixelformat
+.IR format ]
+.RB [ \-fp
+.IR font-path ]
+.RB [ \-fg ]
+.RB [ \-autokill ]
+.RB [ \-noxstartup ]
+.RB [ \-xstartup
+.IR script ]
+.RI [ Xvnc-options... ]
+.br
+.BI "vncserver \-kill :" display#
+.br
+.BI "vncserver \-list"
+.SH DESCRIPTION
+.B vncserver
+is used to start a VNC (Virtual Network Computing) desktop.
+.B vncserver
+is a Perl script which simplifies the process of starting an Xvnc server.  It
+runs Xvnc with appropriate options and starts a window manager on the VNC
+desktop.
+
+.B vncserver
+can be run with no options at all. In this case it will choose the first
+available display number (usually :1), start Xvnc with that display number,
+and start the default window manager in the Xvnc session.  You can also
+specify the display number, in which case vncserver will attempt to start
+Xvnc with that display number and exit if the display number is not
+available.  For example:
+
+.RS
+vncserver :13
+.RE
+
+Editing the file $HOME/.vnc/xstartup allows you to change the applications run
+at startup (but note that this will not affect an existing VNC session.)
+
+.SH OPTIONS
+You can get a list of options by passing \fB\-h\fP as an option to vncserver.
+In addition to the options listed below, any unrecognised options will be
+passed to Xvnc - see the Xvnc man page, or "Xvnc \-help", for details.
+
+.TP
+.B \-name \fIdesktop-name\fP
+Each VNC desktop has a name which may be displayed by the viewer. The desktop
+name defaults to "\fIhost\fP:\fIdisplay#\fP (\fIusername\fP)", but you can
+change it with this option.  The desktop name option is passed to the xstartup
+script via the $VNCDESKTOP environment variable, which allows you to run a
+different set of applications depending on the name of the desktop.
+.
+.TP
+.B \-geometry \fIwidth\fPx\fIheight\fP
+Specify the size of the VNC desktop to be created. Default is 1024x768.
+.
+.TP
+.B \-depth \fIdepth\fP
+Specify the pixel depth (in bits) of the VNC desktop to be created. Default is
+24.  Other possible values are 8, 15 and 16 - anything else is likely to cause
+strange behaviour by applications.
+.
+.TP
+.B \-pixelformat \fIformat\fP
+Specify pixel format for Xvnc to use (BGRnnn or RGBnnn).  The default for
+depth 8 is BGR233 (meaning the most significant two bits represent blue, the
+next three green, and the least significant three represent red), the default
+for depth 16 is RGB565, and the default for depth 24 is RGB888.
+.
+.TP
+.B \-cc 3
+As an alternative to the default TrueColor visual, this allows you to run an
+Xvnc server with a PseudoColor visual (i.e. one which uses a color map or
+palette), which can be useful for running some old X applications which only
+work on such a display.  Values other than 3 (PseudoColor) and 4 (TrueColor)
+for the \-cc option may result in strange behaviour, and PseudoColor desktops
+must have an 8-bit depth.
+.
+.TP
+.B \-kill :\fIdisplay#\fP
+This kills a VNC desktop previously started with vncserver.  It does this by
+killing the Xvnc process, whose process ID is stored in the file
+"$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.pid".  The
+.B \-kill
+option ignores anything preceding the first colon (":") in the display
+argument.  Thus, you can invoke "vncserver \-kill $DISPLAY", for example at the
+end of your xstartup file after a particular application exits.
+.
+.TP
+.B \-fp \fIfont-path\fP
+If the vncserver script detects that the X Font Server (XFS) is running, it
+will attempt to start Xvnc and configure Xvnc to use XFS for font handling.
+Otherwise, if XFS is not running, the vncserver script will attempt to start
+Xvnc and allow Xvnc to use its own preferred method of font handling (which may
+be a hard-coded font path or, on more recent systems, a font catalog.)  In
+any case, if Xvnc fails to start, the vncserver script will then attempt to
+determine an appropriate X font path for this system and start Xvnc using
+that font path.
+
+The
+.B \-fp
+argument allows you to override the above fallback logic and specify a font
+path for Xvnc to use.
+.
+.TP
+.B \-fg
+Runs Xvnc as a foreground process.  This has two effects: (1) The VNC server
+can be aborted with CTRL-C, and (2) the VNC server will exit as soon as the
+user logs out of the window manager in the VNC session.  This may be necessary
+when launching TigerVNC from within certain grid computing environments.
+.
+.TP
+.B \-autokill
+Automatically kill Xvnc whenever the xstartup script exits.  In most cases,
+this has the effect of terminating Xvnc when the user logs out of the window
+manager.
+.
+.TP
+.B \-noxstartup
+Do not run the %HOME/.vnc/xstartup script after launching Xvnc.  This
+option allows you to manually start a window manager in your TigerVNC session.
+.
+.TP
+.B \-xstartup \fIscript\fP
+Run a custom startup script, instead of %HOME/.vnc/xstartup, after launching
+Xvnc. This is useful to run full-screen applications.
+.
+.TP
+.B \-list
+Lists all VNC desktops started by vncserver.
+
+.SH FILES
+Several VNC-related files are found in the directory $HOME/.vnc:
+.TP
+$HOME/.vnc/xstartup
+A shell script specifying X applications to be run when a VNC desktop is
+started.  If this file does not exist, then vncserver will create a default
+xstartup script which attempts to launch your chosen window manager.
+.TP
+/etc/tigervnc/vncserver-config-defaults
+The optional system-wide equivalent of $HOME/.vnc/config. If this file exists
+and defines options to be passed to Xvnc, they will be used as defaults for
+users. The user's $HOME/.vnc/config overrides settings configured in this file.
+The overall configuration file load order is: this file, $HOME/.vnc/config,
+and then /etc/tigervnc/vncserver-config-mandatory. None are required to exist.
+.TP
+/etc/tigervnc/vncserver-config-mandatory
+The optional system-wide equivalent of $HOME/.vnc/config. If this file exists
+and defines options to be passed to Xvnc, they will override any of the same
+options defined in a user's $HOME/.vnc/config. This file offers a mechanism
+to establish some basic form of system-wide policy. WARNING! There is
+nothing stopping users from constructing their own vncserver-like script
+that calls Xvnc directly to bypass any options defined in
+/etc/tigervnc/vncserver-config-mandatory.  Likewise, any CLI arguments passed
+to vncserver will override ANY config file setting of the same name. The
+overall configuration file load order is:
+/etc/tigervnc/vncserver-config-defaults, $HOME/.vnc/config, and then this file.
+None are required to exist.
+.TP
+$HOME/.vnc/config
+An optional server config file wherein options to be passed to Xvnc are listed
+to avoid hard-coding them to the physical invocation. List options in this file
+one per line. For those requiring an argument, simply separate the option from
+the argument with an equal sign, for example: "geometry=2000x1200" or
+"securitytypes=vncauth,tlsvnc". Options without an argument are simply listed
+as a single word, for example: "localhost" or "alwaysshared".
+.TP
+$HOME/.vnc/passwd
+The VNC password file.
+.TP
+$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.log
+The log file for Xvnc and applications started in xstartup.
+.TP
+$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.pid
+Identifies the Xvnc process ID, used by the
+.B \-kill
+option.
+
+.SH SEE ALSO
+.BR vncviewer (1),
+.BR vncpasswd (1),
+.BR vncconfig (1),
+.BR Xvnc (1)
+.br
+https://www.tigervnc.org
+
+.SH AUTHOR
+Tristan Richardson, RealVNC Ltd., D. R. Commander and others.
+
+VNC was originally developed by the RealVNC team while at Olivetti
+Research Ltd / AT&T Laboratories Cambridge.  TightVNC additions were
+implemented by Constantin Kaplinsky. Many other people have since
+participated in development, testing and support. This manual is part
+of the TigerVNC software suite.
diff --git a/SOURCES/xvnc.service b/SOURCES/xvnc.service
index 3471e1f..9ee468c 100644
--- a/SOURCES/xvnc.service
+++ b/SOURCES/xvnc.service
@@ -32,7 +32,7 @@
 Description=XVNC Per-Connection Daemon
 
 [Service]
-ExecStart=-/usr/bin/Xvnc -inetd -query localhost -geometry 1024x768 -depth 24 -once -SecurityTypes=None
+ExecStart=-/usr/bin/Xvnc -inetd -query localhost -geometry 1024x768 -depth 24 -once -SecurityTypes=None -Log *:syslog:30
 User=nobody
 StandardInput=socket
 StandardError=syslog
diff --git a/SPECS/tigervnc.spec b/SPECS/tigervnc.spec
index 99cd4c3..4aedc07 100644
--- a/SPECS/tigervnc.spec
+++ b/SPECS/tigervnc.spec
@@ -1,6 +1,6 @@
 Name:           tigervnc
-Version:        1.10.1
-Release:        5%{?dist}
+Version:        1.11.0
+Release:        6%{?dist}
 Summary:        A TigerVNC remote display system
 
 %global _hardened_build 1
@@ -14,6 +14,10 @@ Source2:        xvnc.socket
 Source3:        10-libvnc.conf
 Source4:        HOWTO.md
 
+# Backwards compatibility
+Source5:        vncserver
+Source6:        vncserver.man
+
 Patch2:         tigervnc-getmaster.patch
 Patch5:         tigervnc-cursor.patch
 Patch6:         tigervnc-1.3.1-CVE-2014-8240.patch
@@ -21,11 +25,12 @@ Patch8:         tigervnc-let-user-know-about-not-using-view-only-password.patch
 Patch9:         tigervnc-working-tls-on-fips-systems.patch
 Patch11:        tigervnc-utilize-system-crypto-policies.patch
 Patch12:        tigervnc-passwd-crash-with-malloc-checks.patch
-Patch13:        0001-xserver-add-no-op-input-thread-init-function.patch
-Patch14:        tigervnc-provide-correct-dimensions-for-xshm-setup.patch
+Patch13:        tigervnc-use-gnome-as-default-session.patch
 
 # Upstream patches
-Patch50:        tigervnc-systemd-support.patch
+Patch50:        tigervnc-tolerate-specifying-boolparam.patch
+Patch51:        tigervnc-systemd-service.patch
+Patch52:        tigervnc-correctly-start-vncsession-as-daemon.patch
 
 # This is tigervnc-%%{version}/unix/xserver116.patch rebased on the latest xorg
 Patch100:       tigervnc-xserver120.patch
@@ -51,9 +56,7 @@ BuildRequires:  libXfont-devel
 # TigerVNC 1.4.x requires fltk 1.3.3 for keyboard handling support
 # See https://github.com/TigerVNC/tigervnc/issues/8, also bug #1208814
 BuildRequires:  fltk-devel >= 1.3.3
-%ifnarch s390 s390x
 BuildRequires:  xorg-x11-server-devel
-%endif
 
 Requires(post): coreutils
 Requires(postun):coreutils
@@ -103,7 +106,6 @@ variety of platforms. This package contains minimal installation
 of TigerVNC server, allowing others to access the desktop on your
 machine.
 
-%ifnarch s390 s390x
 %package server-module
 Summary:        TigerVNC module to Xorg
 Requires:       xorg-x11-server-Xorg %(xserver-sdk-abi-requires ansic) %(xserver-sdk-abi-requires videodrv)
@@ -112,7 +114,6 @@ Requires:       tigervnc-license
 %description server-module
 This package contains libvnc.so module to X server, allowing others
 to access the desktop on your machine.
-%endif
 
 %package license
 Summary:        License of TigerVNC suite
@@ -172,20 +173,12 @@ popd
 %patch11 -p1 -b .utilize-system-crypto-policies.patch
 
 %patch12 -p1 -b .passwd-crash-with-malloc-checks
+%patch13 -p1 -b .use-gnome-as-default-session
 
-%patch13 -p1 -b .xserver-add-no-op-input-thread-init-function.
-
-%patch14 -p1 -b .provide-correct-dimensions-for-xshm-setup
-
-# HACK make sure we are able to successfuly apply a patch. This is because we will
-# be creating a directory under name which already exists as a file and it also seems
-# to be not possible to create a directory with a patch
-pushd unix
-rm vncserver
-mkdir vncserver
-popd
-
-%patch50 -p1 -b .tigervnc-systemd-support
+# Upstream patches
+%patch50 -p1 -b .tolerate-specifying-boolparam
+%patch51 -p1 -b .systemd-service
+%patch52 -p1 -b .correctly-start-vncsession-as-daemon
 
 %build
 %ifarch sparcv9 sparc64 s390 s390x
@@ -256,26 +249,18 @@ install -m644 tigervnc_$s.png %{buildroot}%{_datadir}/icons/hicolor/${s}x$s/apps
 done
 popd
 
-# Install a replacement for /usr/bin/vncserver which will tell the user to read the
-# HOWTO.md file
-cat <<EOF > %{buildroot}/%{_bindir}/vncserver
-#!/bin/bash
-echo "vncserver has been replaced by a systemd unit."
-echo "Please read /usr/share/doc/tigervnc/HOWTO.md for more information."
-EOF
-chmod +x %{buildroot}/%{_bindir}/vncserver
+rm -f %{buildroot}/%{_mandir}/man8/vncserver.8
+
+install -m 755 %{SOURCE5} %{buildroot}/%{_bindir}/vncserver
+install -m 644 %{SOURCE6} %{buildroot}/%{_mandir}/man8/vncserver.8
 
 %find_lang %{name} %{name}.lang
 
 # remove unwanted files
 rm -f  %{buildroot}%{_libdir}/xorg/modules/extensions/libvnc.la
 
-%ifarch s390 s390x
-rm -f %{buildroot}%{_libdir}/xorg/modules/extensions/libvnc.so
-%else
 mkdir -p %{buildroot}%{_sysconfdir}/X11/xorg.conf.d/
 install -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/X11/xorg.conf.d/10-libvnc.conf
-%endif
 
 install -m 644 %{SOURCE4} %{buildroot}/%{_docdir}/tigervnc/HOWTO.md
 
@@ -340,11 +325,9 @@ fi
 %{_mandir}/man1/vncpasswd.1*
 %{_mandir}/man1/vncconfig.1*
 
-%ifnarch s390 s390x
 %files server-module
 %{_libdir}/xorg/modules/extensions/libvnc.so
 %config %{_sysconfdir}/X11/xorg.conf.d/10-libvnc.conf
-%endif
 
 %files license
 %{_docdir}/tigervnc/LICENCE.TXT
@@ -357,6 +340,46 @@ fi
 
 
 %changelog
+* Tue Dec 15 2020 Jan Grulich <jgrulich@redhat.com> - 1.11.0-6
+- Use GNOME as default session
+  Resolves: bz#1853608
+
+* Thu Dec 03 2020 Jan Grulich <jgrulich@redhat.com> - 1.11.0-5
+- Make sure we log properly output to journal (actually log to syslog)
+  Resolves: bz#1841537
+
+* Thu Dec 03 2020 Jan Grulich <jgrulich@redhat.com> - 1.11.0-4
+- Make sure we log properly output to journal
+  Resolves: bz#1841537
+
+* Wed Nov 18 2020 Jan Grulich <jgrulich@redhat.com> - 1.11.0-3
+- vncserver: ignore new "session" parameter from the new systemd support
+  Resolves: bz#1897504
+
+* Wed Nov 18 2020 Jan Grulich <jgrulich@redhat.com> - 1.11.0-2
+- Revert removal of vncserver
+  Resolves: bz#1897504
+- Correctly start vncsession as a daemon
+  Resolves: bz#1897498
+
+* Tue Oct 20 2020 Jan Grulich <jgrulich@redhat.com> - 1.11.0-1
+- Update to 1.11.0
+  Resolves: bz#1880985
+- Backport fix to allow Tigervnc use boolean values in config files
+  Resolves: bz#1883415
+
+* Wed Sep 30 2020 Jan Grulich <jgrulich@redhat.com> - 1.10.1-8
+- Tolerate specifying -BoolParam 0 and similar
+  Resolves: bz#1883415
+
+* Wed Jul 08 2020 Jan Grulich <jgrulich@redhat.com> - 1.10.1-7
+- Enable server module on s390x
+  Resolves: bz#1854925
+
+* Fri Jul 03 2020 Jan Grulich <jgrulich@redhat.com> - 1.10.1-6
+- Remove trailing spaces in user name
+  Resolves: bz#1852432
+
 * Thu Jun 25 2020 Jan Grulich <jgrulich@redhat.com> - 1.10.1-5
 - Install the HOWTO file to correct location
 - Add /usr/bin/vncserver file informing users to read the HOWTO.md file