From 27d184c295e6a870375eae2c295cc89cc959ac35238e8b16be39974b78f5074a Mon Sep 17 00:00:00 2001 From: Stefan Dirsch Date: Fri, 9 Aug 2013 14:33:20 +0000 Subject: [PATCH] Accepting request 186594 from home:tobijk:X11:XOrg remove the unused "ancient" Xvnc third attempt OBS-URL: https://build.opensuse.org/request/show/186594 OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xorg-x11-server?expand=0&rev=454 --- n_VNC-Add-proto.diff | 27 - n_VNC-Add-support-for-VNC.patch | 23495 ---------------- ...C-access-the-framebuffer-directly-an.patch | 352 - ...f-all-keyboard-layouts-independent-o.patch | 467 - ...rash-due-to-unset-input-device-names.patch | 125 - ...hen-no-depth-translation-is-required.patch | 45 - ...ut-when-vnc-viewer-connection-breaks.patch | 74 - xorg-x11-server.changes | 15 + xorg-x11-server.spec | 76 +- 9 files changed, 18 insertions(+), 24658 deletions(-) delete mode 100644 n_VNC-Add-proto.diff delete mode 100644 n_VNC-Add-support-for-VNC.patch delete mode 100644 n_VNC-Don-t-let-VNC-access-the-framebuffer-directly-an.patch delete mode 100644 n_VNC-Enable-use-of-all-keyboard-layouts-independent-o.patch delete mode 100644 n_VNC-Fix-crash-due-to-unset-input-device-names.patch delete mode 100644 n_VNC-Fix-crash-when-no-depth-translation-is-required.patch delete mode 100644 n_VNC-Readd-timeout-when-vnc-viewer-connection-breaks.patch diff --git a/n_VNC-Add-proto.diff b/n_VNC-Add-proto.diff deleted file mode 100644 index 68acf24..0000000 --- a/n_VNC-Add-proto.diff +++ /dev/null @@ -1,27 +0,0 @@ -From: Mike Gorse -Date: Wed Apr 18 22:52:23 UTC 2012 -Subject: [PATCH] VNC: Add a missing prototype -Patch-Mainline: Currently no upstream project. ---- -diff -ur xorg-server-1.12.1.orig/hw/vnc/rfbkeyb.c xorg-server-1.12.1/hw/vnc/rfbkeyb.c ---- xorg-server-1.12.1.orig/hw/vnc/rfbkeyb.c 2012-04-18 17:38:08.302219053 -0500 -+++ xorg-server-1.12.1/hw/vnc/rfbkeyb.c 2012-04-18 16:44:12.873667473 -0500 -@@ -44,6 +44,7 @@ - #endif - #else - #include -+#include - #include - #endif - #include "rfb.h" -diff -ur xorg-server-1.12.1.orig/hw/vnc/rfbmouse.c xorg-server-1.12.1/hw/vnc/rfbmouse.c ---- xorg-server-1.12.1.orig/hw/vnc/rfbmouse.c 2012-04-18 17:38:08.302219053 -0500 -+++ xorg-server-1.12.1/hw/vnc/rfbmouse.c 2012-04-18 16:43:28.843217928 -0500 -@@ -46,6 +46,7 @@ - - #else - #include -+#include - #include - #endif - #include "rfb.h" diff --git a/n_VNC-Add-support-for-VNC.patch b/n_VNC-Add-support-for-VNC.patch deleted file mode 100644 index 6799b66..0000000 --- a/n_VNC-Add-support-for-VNC.patch +++ /dev/null @@ -1,23495 +0,0 @@ -From: Egbert Eich -Date: Tue, 6 Sep 2011 16:53:08 +0200 -Subject: [PATCH] VNC: Add support for VNC. -Patch-Mainline: Currently no upstream project. -Git-commit: f3b09280968200b06c872a96c4b490d13e7c5338 -Signed-off: Egbert Eich - -This is based upon http://people.freedesktop.org/~dbn/xorg-server-xf4vnc.patch -but has been modified heavily to apply and compile with 10.3. - -Signed-off-by: Egbert Eich - -Adapted for 1.12.1 by Mike Gorse -Adapted for 1.13.0 by Tobias Klausmann ---- -diff -pruN xorg-server-1.12.1.orig/configure.ac xorg-server-1.12.1/configure.ac ---- xorg-server-1.12.1.orig/configure.ac 2012-04-13 17:44:02.000000000 -0500 -+++ xorg-server-1.12.1/configure.ac 2012-04-18 14:45:21.568821053 -0500 -@@ -629,6 +629,8 @@ AC_ARG_ENABLE(pciaccess, AS_HELP_STRING( - - dnl DDXes. - AC_ARG_ENABLE(xorg, AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto]) -+AC_ARG_ENABLE(xcliplist, AS_HELP_STRING([--enable-xcliplist], [Build XClipList extension (default: auto)]), [XCLIPLIST=$enableval], [XCLIPLIST=auto]) -+AC_ARG_ENABLE(vnc, AS_HELP_STRING([--enable-vnc], [Build Xvnc server (default: yes)]), [VNC=$enableval], [VNC=auto]) - AC_ARG_ENABLE(dmx, AS_HELP_STRING([--enable-dmx], [Build DMX server (default: auto)]), [DMX=$enableval], [DMX=auto]) - AC_ARG_ENABLE(xvfb, AS_HELP_STRING([--enable-xvfb], [Build Xvfb server (default: yes)]), [XVFB=$enableval], [XVFB=yes]) - AC_ARG_ENABLE(xnest, AS_HELP_STRING([--enable-xnest], [Build Xnest server (default: auto)]), [XNEST=$enableval], [XNEST=auto]) -@@ -1191,6 +1193,20 @@ AM_CONDITIONAL(VGAHW, test "x$VGAHW" = x - AM_CONDITIONAL(VBE, test "x$VBE" = xyes) - AM_CONDITIONAL(INT10MODULE, test "x$INT10MODULE" = xyes) - -+if test "x$XCLIPLIST" = xauto; then -+ if test "x$XORG" = xno; then -+ XCLIPLIST=no -+ else -+ PKG_CHECK_MODULES([XCLIPLIST], [xcliplistproto xcliplist], [XCLIPLIST=yes], [XCLIPLIST=no]) -+ fi -+fi -+AM_CONDITIONAL(XCLIPLIST, [test "x$XCLIPLIST" = xyes]) -+if test "x$XCLIPLIST" = xyes; then -+ AC_DEFINE(XCLIPLIST, 1, [Support XClipList extension]) -+ REQUIRED_MODULES="$REQUIRED_MODULES xcliplistproto" -+ XCLIPLIST_LIB='$(top_builddir)/xcliplist/libxcliplist.la' -+fi -+ - AC_DEFINE(SHAPE, 1, [Support SHAPE extension]) - - AC_DEFINE_DIR(XKB_BASE_DIRECTORY, XKBPATH, [Path to XKB data]) -@@ -1480,6 +1496,40 @@ dnl ------------------------------------ - dnl DDX section. - dnl --------------------------------------------------------------------------- - -+dnl VNC DDX -+ -+AC_MSG_CHECKING([whether to build Xvnc DDX]) -+PKG_CHECK_MODULES([VNCMODULES], [xmuu xext x11 xrender xfont xi vncproto xau $XDMCP_MODULES $PIXMAN], [have_vnc=yes], [have_vnc=no]) -+if test "x$VNC" = xauto; then -+ VNC="$have_vnc" -+fi -+AC_MSG_RESULT([$VNC]) -+AM_CONDITIONAL(VNC, [test "x$VNC" = xyes]) -+ -+if test "x$VNC" = xyes; then -+ if test "x$have_vnc" = xno; then -+ AC_MSG_ERROR([Xvnc build explicitly requested, but required -+ modules not found.]) -+ fi -+ XVNC_CFLAGS="-DVNCSERVER -DHAVE_XVNC_CONFIG_H" -+ AC_SUBST([XVNC_CFLAGS]) -+ VNC_INCLUDES="$XEXT_INC $RENDER_INC $XTRAP_INC $RECORD_INC" -+ XVNC_LIBS="$XEXT_LIB $MAIN_LIB $CONFIG_LIB $XSERVER_LIBS $FB_LIB $MI_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $COMPOSITE_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB $FIXES_LIB $LIBS" -+ AC_SUBST([XVNC_LIBS]) -+ -+ if test "x$GLX" = xyes; then -+ PKG_CHECK_MODULES([GL], [glproto]) -+ fi -+ PKG_CHECK_MODULES([XVNCCONFIG_DEP], [xaw7 xmu xt xpm x11]) -+ AC_SUBST(XVNCCONFIG_DEP_CFLAGS) -+ AC_SUBST(XVNCCONFIG_DEP_LIBS) -+ ${CONFIG_SHELL-/bin/sh} $srcdir/hw/vnc/symlink-vnc.sh \ -+ $srcdir/hw/vnc $srcdir/hw/xfree86/vnc && \ -+ ${CONFIG_SHELL-/bin/sh} $srcdir/hw/vnc/symlink-vnc.sh \ -+ $srcdir/hw/vnc $srcdir/hw/dmx/vnc || \ -+ AC_MSG_ERROR([Failed symlinking VNC sources]) -+fi -+ - dnl Xvfb DDX - - AC_MSG_CHECKING([whether to build Xvfb DDX]) -@@ -2159,6 +2209,7 @@ Xext/Makefile - Xi/Makefile - xfixes/Makefile - exa/Makefile -+xcliplist/Makefile - hw/Makefile - hw/xfree86/Makefile - hw/xfree86/common/Makefile -@@ -2262,6 +2280,7 @@ hw/xfree86/ramdac/Makefile - hw/xfree86/shadowfb/Makefile - hw/xfree86/vbe/Makefile - hw/xfree86/vgahw/Makefile -+hw/xfree86/vnc/Makefile - hw/xfree86/x86emu/Makefile - hw/xfree86/utils/Makefile - hw/xfree86/utils/man/Makefile -@@ -2207,6 +2259,8 @@ hw/dmx/input/Makefile - hw/dmx/glxProxy/Makefile - hw/dmx/Makefile - hw/dmx/man/Makefile -+hw/dmx/vnc/Makefile -+hw/vnc/Makefile - hw/vfb/Makefile - hw/vfb/man/Makefile - hw/xnest/Makefile -diff -pruN xorg-server-1.12.1.orig/hw/dmx/dmxinit.c xorg-server-1.12.1/hw/dmx/dmxinit.c ---- xorg-server-1.12.1.orig/hw/dmx/dmxinit.c 2012-03-30 22:04:18.000000000 -0500 -+++ xorg-server-1.12.1/hw/dmx/dmxinit.c 2012-04-18 14:45:21.569821040 -0500 -@@ -72,6 +72,10 @@ - #include - #endif /* GLXEXT */ - -+#ifdef DMXVNC -+extern void VNCInitForDMX(void); -+#endif -+ - /* Global variables available to all Xserver/hw/dmx routines. */ - int dmxNumScreens; - DMXScreenInfo *dmxScreens; -@@ -837,6 +841,9 @@ InitOutput(ScreenInfo * pScreenInfo, int - - dmxLog(dmxInfo, "Shadow framebuffer support %s\n", - dmxShadowFB ? "enabled" : "disabled"); -+#ifdef DMXVNC -+ VNCInitForDMX(); -+#endif - } - - /* RATS: Assuming the fp string (which comes from the command-line argv -diff -pruN xorg-server-1.12.1.orig/hw/dmx/dmxsync.c xorg-server-1.12.1/hw/dmx/dmxsync.c ---- xorg-server-1.12.1.orig/hw/dmx/dmxsync.c 2012-03-29 21:57:25.000000000 -0500 -+++ xorg-server-1.12.1/hw/dmx/dmxsync.c 2012-04-18 14:45:21.569821040 -0500 -@@ -104,9 +104,16 @@ dmxSyncBlockHandler(pointer blockData, O - TimerForce(dmxSyncTimer); - } - -+#ifdef DMXVNC -+extern void rfbWakeupHandlerDMX(void); -+#endif -+ - static void - dmxSyncWakeupHandler(pointer blockData, int result, pointer pReadMask) - { -+#ifdef DMXVNC -+ rfbWakeupHandlerDMX(); -+#endif - } - - /** Request the XSync() batching optimization with the specified \a -diff -pruN xorg-server-1.12.1.orig/hw/dmx/dmxvnc.h xorg-server-1.12.1/hw/dmx/dmxvnc.h ---- xorg-server-1.12.1.orig/hw/dmx/dmxvnc.h 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/dmx/dmxvnc.h 2012-04-18 14:45:21.569821040 -0500 -@@ -0,0 +1,9 @@ -+#ifndef _DMX_VNC_H_ -+# define _DMX_VNC_H_ -+ -+int ChangePointerDevice (DeviceIntPtr old_dev, DeviceIntPtr new_dev, -+ unsigned char x, unsigned char y); -+ -+int ChangeKeyboardDevice (DeviceIntPtr old_dev, DeviceIntPtr new_dev); -+ -+#endif -diff -pruN xorg-server-1.12.1.orig/hw/dmx/input/dmxinputinit.c xorg-server-1.12.1/hw/dmx/input/dmxinputinit.c ---- xorg-server-1.12.1.orig/hw/dmx/input/dmxinputinit.c 2012-03-29 21:57:25.000000000 -0500 -+++ xorg-server-1.12.1/hw/dmx/input/dmxinputinit.c 2012-04-18 14:45:21.570821028 -0500 -@@ -376,6 +376,11 @@ static int - dmxKeyboardOn(DeviceIntPtr pDevice, DMXLocalInitInfo * info) - { - GETDMXINPUTFROMPDEVICE; -+ -+#ifdef DMXVNC -+ vncSetKeyboardDevice(pDevice); -+#endif -+ - XkbRMLVOSet rmlvo; - - rmlvo.rules = dmxConfigGetXkbRules(); -@@ -456,7 +461,9 @@ dmxDeviceOnOff(DeviceIntPtr pDevice, int - } - if (info.keyClass) { - XkbRMLVOSet rmlvo; -- -+#ifdef DMXVNC -+ vncSetKeyboardDevice(pDevice); -+#endif - rmlvo.rules = dmxConfigGetXkbRules(); - rmlvo.model = dmxConfigGetXkbModel(); - rmlvo.layout = dmxConfigGetXkbLayout(); -@@ -505,6 +512,9 @@ dmxDeviceOnOff(DeviceIntPtr pDevice, int - info.res[i], info.minres[i], - info.maxres[i], Absolute); - } -+#ifdef DMXVNC -+ vncSetPointerDevice(pDevice); -+#endif - } - if (info.focusClass) - InitFocusClassDeviceStruct(pDevice); -diff -pruN xorg-server-1.12.1.orig/hw/dmx/input/dmxinputinit.h xorg-server-1.12.1/hw/dmx/input/dmxinputinit.h ---- xorg-server-1.12.1.orig/hw/dmx/input/dmxinputinit.h 2012-03-29 21:57:25.000000000 -0500 -+++ xorg-server-1.12.1/hw/dmx/input/dmxinputinit.h 2012-04-18 14:45:21.570821028 -0500 -@@ -281,4 +281,9 @@ extern DMXInputInfo *dmxInputLocateId(in - extern int dmxInputAttachConsole(const char *name, int isCore, int *id); - extern int dmxInputAttachBackend(int physicalScreen, int isCore, int *id); - -+#ifdef DMXVNC -+extern void vncSetKeyboardDevice(DeviceIntPtr kbd); -+extern void vncSetPointerDevice(DeviceIntPtr ptr); -+#endif -+ - #endif -diff -pruN xorg-server-1.12.1.orig/hw/dmx/Makefile.am xorg-server-1.12.1/hw/dmx/Makefile.am ---- xorg-server-1.12.1.orig/hw/dmx/Makefile.am 2011-09-22 20:39:53.000000000 -0500 -+++ xorg-server-1.12.1/hw/dmx/Makefile.am 2012-04-18 14:45:21.570821028 -0500 -@@ -2,6 +2,16 @@ - SUBDIRS = input config examples doc doxygen man - bin_PROGRAMS = Xdmx - -+if VNC -+SUBDIRS += vnc -+JPEG_LIBS = -ljpeg -+CRYPT_LIBS = -lcrypt -+DMXVNC_LIBS = vnc/libdmxvnc.a \ -+ $(JPEG_LIBS) \ -+ $(CRYPT_LIBS) -+DMXVNCCGLAGS = -DDMXVNC=1 -+endif -+ - if XINERAMA - PANORAMIX_SRCS = $(top_srcdir)/Xext/panoramiX.c - endif -@@ -83,7 +93,7 @@ XDMX_LIBS = \ - - Xdmx_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) - Xdmx_DEPENDENCIES= $(XDMX_LIBS) --Xdmx_LDADD = $(XDMX_LIBS) $(XDMX_SYS_LIBS) $(XSERVER_SYS_LIBS) -+Xdmx_LDADD = $(DMXVNC_LIBS) $(XDMX_LIBS) $(XDMX_SYS_LIBS) $(XSERVER_SYS_LIBS) - - relink: - $(AM_V_at)rm -f Xdmx$(EXEEXT) && $(MAKE) Xdmx$(EXEEXT) -diff -pruN xorg-server-1.12.1.orig/hw/dmx/vnc/.gitignore xorg-server-1.12.1/hw/dmx/vnc/.gitignore ---- xorg-server-1.12.1.orig/hw/dmx/vnc/.gitignore 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/dmx/vnc/.gitignore 2012-04-18 14:45:21.570821028 -0500 -@@ -0,0 +1,36 @@ -+auth.c -+cmap.c -+corre.c -+cursor.c -+cutpaste.c -+d3des.c -+d3des.h -+dispcur.c -+draw.c -+hextile.c -+httpd.c -+kbdptr.c -+keyboard.h -+loginauth.c -+rdp.c -+rfb.h -+rfbkeyb.c -+rfbmouse.c -+rfbproto.h -+rfbserver.c -+rre.c -+sockets.c -+sprite.c -+sprite.h -+spritest.h -+stats.c -+tableinitcmtemplate.c -+tableinittctemplate.c -+tabletranstemplate.c -+tight.c -+translate.c -+vncauth.c -+vncauth.h -+vncext.c -+xistubs.c -+zlib.c -diff -pruN xorg-server-1.12.1.orig/hw/dmx/vnc/Makefile.am xorg-server-1.12.1/hw/dmx/vnc/Makefile.am ---- xorg-server-1.12.1.orig/hw/dmx/vnc/Makefile.am 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/dmx/vnc/Makefile.am 2012-04-18 14:45:21.570821028 -0500 -@@ -0,0 +1,43 @@ -+noinst_LIBRARIES = libdmxvnc.a -+ -+SRCS = \ -+ auth.c \ -+ cmap.c \ -+ corre.c \ -+ cursor.c \ -+ cutpaste.c \ -+ d3des.c \ -+ dispcur.c \ -+ draw.c \ -+ hextile.c \ -+ httpd.c \ -+ kbdptr.c \ -+ loginauth.c \ -+ rdp.c \ -+ rfbkeyb.c \ -+ rfbmouse.c \ -+ rfbserver.c \ -+ rre.c \ -+ sockets.c \ -+ sprite.c \ -+ stats.c \ -+ tight.c \ -+ translate.c \ -+ vncauth.c \ -+ vncext.c \ -+ vncInit.c \ -+ xistubs.c \ -+ zlib.c -+ -+ -+libdmxvnc_a_SOURCES = $(SRCS) -+ -+AM_CFLAGS = \ -+ -I$(top_srcdir)/hw/dmx \ -+ -I$(top_srcdir)/hw/xfree86/common \ -+ -DHAVE_DMX_CONFIG_H \ -+ $(DIX_CFLAGS) \ -+ -DDMXVNC=1 \ -+ @DMXMODULES_CFLAGS@ -+ -+###EXTRA_DIST = dmxdetach.c -diff -pruN xorg-server-1.12.1.orig/hw/dmx/vnc/vncInit.c xorg-server-1.12.1/hw/dmx/vnc/vncInit.c ---- xorg-server-1.12.1.orig/hw/dmx/vnc/vncInit.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/dmx/vnc/vncInit.c 2012-04-18 14:45:21.571821016 -0500 -@@ -0,0 +1,441 @@ -+/* -+ * Copyright (C) 2002 Alan Hourihane. 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. -+ * -+ * Author: Alan Hourihane -+ */ -+ -+#include "rfb.h" -+ -+#ifdef HAVE_DMX_CONFIG_H -+#include "dmx-config.h" -+#endif -+ -+#ifdef DMXVNC -+#include "../dmx.h" -+#include "../dmxcb.h" -+#endif -+ -+#include -+#include "fb.h" -+ -+#include "dixstruct.h" -+#include "compiler.h" -+ -+#include "mipointer.h" -+#include "mibstore.h" -+ -+#include "globals.h" -+#define DPMS_SERVER -+#include -+ -+#include -+ -+struct _DevPrivateKeyRec VNCScreenKeyRec; -+DevPrivateKey VNCScreenKey = &VNCScreenKeyRec; -+struct _DevPrivateKeyRec rfbGCKeyRec; -+DevPrivateKey rfbGCKey = &rfbGCKeyRec; -+ -+int inetdSock = -1; -+Atom VNC_LAST_CLIENT_ID = 0; -+Atom VNC_CONNECT = 0; -+char *desktopName = "x11"; -+char rfbThisHost[256]; -+ -+extern void VncExtensionInit(void); -+ -+extern void vncInitMouse(void); -+extern void vncInitKeyb(void); -+Bool VNCInit(ScreenPtr pScreen, DMXScreenInfo *dmxScreen); -+ -+#ifndef XFree86LOADER -+static unsigned long VNCGeneration = 0; -+#endif -+static void rfbWakeupHandler (int i, pointer blockData, unsigned long err, pointer pReadmask); -+ -+/* -+ * rfbLog prints a time-stamped message to the log file (stderr). -+ */ -+ -+void rfbLog(char *format, ...) -+{ -+ va_list args; -+ char buf[256]; -+ time_t clock; -+ -+ va_start(args, format); -+ -+ time(&clock); -+ strftime(buf, 255, "%d/%m/%Y %H:%M:%S ", localtime(&clock)); -+ fprintf(stderr, "%s\n", buf); -+ -+ vfprintf(stderr, format, args); -+ fflush(stderr); -+ -+ va_end(args); -+} -+ -+void rfbLogPerror(char *str) -+{ -+ rfbLog(""); -+ perror(str); -+} -+ -+ -+static ScreenPtr TheVNCScreen = NULL; -+ -+ -+static void -+nopGetImage(DrawablePtr pDrawable, int sx, int sy, -+ int w, int h, unsigned int format, -+ unsigned long planemask, char *pdstLine) -+{ -+ ScreenPtr pScreen = pDrawable->pScreen; -+ -+ (*pScreen->GetImage)(pDrawable,sx,sy,w,h,format,planemask,pdstLine); -+} -+ -+ -+static void -+SetupVNCScreen(void) -+{ -+ vncScreenPtr pScreenPriv; -+ VisualPtr v = NULL; -+ int i; -+ -+ pScreenPriv = malloc(sizeof(vncScreenRec)); -+ pScreenPriv->width = dmxGlobalWidth; -+ pScreenPriv->height = dmxGlobalHeight; -+ pScreenPriv->rfbAuthTries = 0; -+ pScreenPriv->rfbAuthTooManyTries = FALSE; -+ pScreenPriv->timer = NULL; -+ pScreenPriv->udpPort = 0; -+ pScreenPriv->rfbListenSock = -1; -+ pScreenPriv->udpSock = -1; -+ pScreenPriv->udpSockConnected = FALSE; -+ pScreenPriv->httpListenSock = -1; -+ pScreenPriv->httpSock = -1; -+ pScreenPriv->maxFd = 0; -+ pScreenPriv->rfbAuthPasswdFile = NULL; -+ pScreenPriv->httpDir = NULL; -+ pScreenPriv->rfbInstalledColormap = NULL; -+ pScreenPriv->interface.s_addr = htonl (INADDR_ANY); -+ -+ pScreenPriv->rfbPort = 0; -+ pScreenPriv->httpPort = 0; -+ pScreenPriv->rfbAuthPasswdFile = NULL; -+ pScreenPriv->httpDir = NULL; -+ pScreenPriv->rfbAlwaysShared = FALSE; -+ pScreenPriv->rfbNeverShared = FALSE; -+ pScreenPriv->rfbUserAccept = FALSE; -+ pScreenPriv->rfbViewOnly = FALSE; -+ pScreenPriv->rfbDontDisconnect = FALSE; -+ pScreenPriv->loginAuthEnabled = FALSE; -+ -+ /* Find the root window's visual. -+ * XXX this might be the wrong info to use below. -+ */ -+ for (i = 0; i < screenInfo.screens[0]->numVisuals; i++) { -+ v = screenInfo.screens[0]->visuals + i; -+ if (v->vid == screenInfo.screens[0]->rootVisual) { -+ break; -+ } -+ } -+ -+ /* XXX is this the right depth and bpp? */ -+ /* With DMX, screenInfo.screens[0]->rootDepth is 24 and that doesn't -+ * work in translate.c! We're just using 32. -+ */ -+ pScreenPriv->rfbServerFormat.bitsPerPixel = 32; -+ pScreenPriv->rfbServerFormat.depth = 32; -+ pScreenPriv->rfbServerFormat.bigEndian = 0; -+ pScreenPriv->rfbServerFormat.trueColour = (v->class == TrueColor); -+ if (pScreenPriv->rfbServerFormat.trueColour) { -+ pScreenPriv->rfbServerFormat.redMax = v->redMask >> v->offsetRed; -+ pScreenPriv->rfbServerFormat.greenMax = v->greenMask >> v->offsetGreen; -+ pScreenPriv->rfbServerFormat.blueMax = v->blueMask >> v->offsetBlue; -+ pScreenPriv->rfbServerFormat.redShift = v->offsetRed; -+ pScreenPriv->rfbServerFormat.greenShift = v->offsetGreen; -+ pScreenPriv->rfbServerFormat.blueShift = v->offsetBlue; -+ } else { -+ pScreenPriv->rfbServerFormat.redMax -+ = pScreenPriv->rfbServerFormat.greenMax -+ = pScreenPriv->rfbServerFormat.blueMax = 0; -+ pScreenPriv->rfbServerFormat.redShift -+ = pScreenPriv->rfbServerFormat.greenShift -+ = pScreenPriv->rfbServerFormat.blueShift = 0; -+ } -+ -+ TheVNCScreen = (ScreenPtr) Xcalloc(1, sizeof(struct _Screen)); -+ TheVNCScreen->GetImage = nopGetImage; -+ dixSetPrivate(&TheVNCScreen->devPrivates, VNCScreenKey, pScreenPriv); -+ -+ rfbInitSockets(TheVNCScreen); -+ if (inetdSock == -1) -+ httpInitSockets(TheVNCScreen); -+} -+ -+ -+/* -+ * Called by DMX's InitOutput() -+ * Will be called for each X server generation. -+ */ -+void -+VNCInitForDMX(void) -+{ -+ rfbLog("DMXVNC: Initializing VNC for DMX\n"); -+ ErrorF("DMXVNC: Initializing VNC for DMX\n"); -+ -+ if (TheVNCScreen) { -+ rfbLog("DMXVNC: New server generation\n"); -+ } -+ else { -+ rfbLog("DMXVNC: Set up VNC screen\n"); -+ SetupVNCScreen(); -+ } -+ -+ /* Reset the input device pointers. They'll get set later. -+ * This allows successful server regeneration. -+ */ -+ vncSetKeyboardDevice(NULL); -+ vncSetPointerDevice(NULL); -+} -+ -+ -+Bool -+VNCInit(ScreenPtr pScreen, DMXScreenInfo *pScrn) -+{ -+ VisualPtr visual; -+ vncScreenPtr pScreenPriv; -+#if 0 -+ char *interface_str = NULL; -+#endif -+#ifdef RENDER -+ PictureScreenPtr ps; -+#endif -+ -+#ifndef XFree86LOADER -+ if (VNCGeneration != serverGeneration) { -+ VNCGeneration = serverGeneration; -+ if (!dixRegisterPrivateKey(VNCScreenKey, PRIVATE_SCREEN, 0) -+ || !dixRegisterPrivateKey(rfbGCKey, PRIVATE_GC, 0)) -+ return FALSE; -+ } -+#endif -+ -+ if (!(pScreenPriv = malloc(sizeof(vncScreenRec)))) -+ return FALSE; -+ -+ dixSetPrivate(&pScreen->devPrivates, VNCScreenKey, pScreenPriv); -+ -+ pScreenPriv->rfbAuthTries = 0; -+ pScreenPriv->rfbAuthTooManyTries = FALSE; -+ pScreenPriv->timer = NULL; -+ pScreenPriv->udpPort = 0; -+ pScreenPriv->rfbListenSock = -1; -+ pScreenPriv->udpSock = -1; -+ pScreenPriv->udpSockConnected = FALSE; -+ pScreenPriv->httpListenSock = -1; -+ pScreenPriv->httpSock = -1; -+ pScreenPriv->maxFd = 0; -+ pScreenPriv->rfbAuthPasswdFile = NULL; -+ pScreenPriv->httpDir = NULL; -+ pScreenPriv->rfbInstalledColormap = NULL; -+ pScreenPriv->interface.s_addr = htonl (INADDR_ANY); -+ -+ pScreenPriv->rfbPort = 0; -+ pScreenPriv->httpPort = 0; -+ pScreenPriv->rfbAuthPasswdFile = NULL; -+ pScreenPriv->httpDir = NULL; -+ pScreenPriv->rfbAlwaysShared = FALSE; -+ pScreenPriv->rfbNeverShared = FALSE; -+ pScreenPriv->rfbUserAccept = FALSE; -+ pScreenPriv->rfbViewOnly = FALSE; -+ pScreenPriv->rfbDontDisconnect = FALSE; -+ pScreenPriv->loginAuthEnabled = FALSE; -+ -+#if 0 -+ if (xf86ReturnOptValBool(options, OPTION_LOCALHOST, FALSE)) -+ pScreenPriv->interface.s_addr = htonl (INADDR_LOOPBACK); -+ -+ interface_str = xf86GetOptValString(options, OPTION_INTERFACE); -+ -+ if (interface_str && pScreenPriv->interface.s_addr == htonl(INADDR_ANY)) { -+ Bool failed = FALSE; -+ struct in_addr got; -+ unsigned long octet; -+ char *p = interface_str, *end; -+ int q; -+ -+ for (q = 0; q < 4; q++) { -+ octet = strtoul (p, &end, 10); -+ -+ if (p == end || octet > 255) -+ failed = TRUE; -+ -+ if ((q < 3 && *end != '.') || -+ (q == 3 && *end != '\0')) -+ failed = TRUE; -+ -+ got.s_addr = (got.s_addr << 8) | octet; -+ p = end + 1; -+ } -+ -+ if (!failed) -+ pScreenPriv->interface.s_addr = htonl (got.s_addr); -+ else -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VNC interface option malformed, not using.\n"); -+ } -+#endif -+ -+ if (!VNC_LAST_CLIENT_ID) -+ VNC_LAST_CLIENT_ID = MakeAtom("VNC_LAST_CLIENT_ID", -+ strlen("VNC_LAST_CLIENT_ID"), TRUE); -+ if (!VNC_CONNECT) -+ VNC_CONNECT = MakeAtom("VNC_CONNECT", strlen("VNC_CONNECT"), TRUE); -+ -+ rfbInitSockets(pScreen); -+ if (inetdSock == -1) -+ httpInitSockets(pScreen); -+ -+#ifdef CORBA -+ initialiseCORBA(argc, argv, desktopName); -+#endif -+ -+ pScreenPriv->width = pScrn->scrnWidth; -+ pScreenPriv->height = pScrn->scrnHeight; -+ pScreenPriv->depth = pScrn->beDepth; -+ pScreenPriv->paddedWidthInBytes = PixmapBytePad(pScrn->scrnWidth, pScrn->beDepth); -+ pScreenPriv->bitsPerPixel = rfbBitsPerPixel(pScrn->beDepth); -+ pScreenPriv->pfbMemory = NULL; -+ pScreenPriv->oldpfbMemory = NULL; -+ -+ pScreenPriv->cursorIsDrawn = TRUE; -+ pScreenPriv->dontSendFramebufferUpdate = FALSE; -+ -+ pScreenPriv->CloseScreen = pScreen->CloseScreen; -+ pScreenPriv->CreateGC = pScreen->CreateGC; -+ pScreenPriv->CopyWindow = pScreen->CopyWindow; -+ pScreenPriv->ClearToBackground = pScreen->ClearToBackground; -+ pScreenPriv->WakeupHandler = pScreen->WakeupHandler; -+ pScreenPriv->InstallColormap = pScreen->InstallColormap; -+ pScreenPriv->UninstallColormap = pScreen->UninstallColormap; -+ pScreenPriv->ListInstalledColormaps = pScreen->ListInstalledColormaps; -+ pScreenPriv->StoreColors = pScreen->StoreColors; -+#ifdef CHROMIUM -+ pScreenPriv->RealizeWindow = pScreen->RealizeWindow; -+ pScreenPriv->UnrealizeWindow = pScreen->UnrealizeWindow; -+ pScreenPriv->DestroyWindow = pScreen->DestroyWindow; -+ pScreenPriv->PositionWindow = pScreen->PositionWindow; -+ pScreenPriv->ResizeWindow = pScreen->ResizeWindow; -+ pScreenPriv->ClipNotify = pScreen->ClipNotify; -+#endif -+#ifdef RENDER -+ ps = GetPictureScreenIfSet(pScreen); -+ if (ps) -+ pScreenPriv->Composite = ps->Composite; -+#endif -+ pScreen->CloseScreen = rfbCloseScreen; -+ pScreen->CreateGC = rfbCreateGC; -+ pScreen->CopyWindow = rfbCopyWindow; -+ pScreen->ClearToBackground = rfbClearToBackground; -+ pScreen->WakeupHandler = rfbWakeupHandler; -+ pScreen->InstallColormap = rfbInstallColormap; -+ pScreen->UninstallColormap = rfbUninstallColormap; -+ pScreen->ListInstalledColormaps = rfbListInstalledColormaps; -+ pScreen->StoreColors = rfbStoreColors; -+ -+#ifdef CHROMIUM -+ pScreen->RealizeWindow = rfbRealizeWindow; -+ pScreen->UnrealizeWindow = rfbUnrealizeWindow; -+ pScreen->DestroyWindow = rfbDestroyWindow; -+ pScreen->PositionWindow = rfbPositionWindow; -+ pScreen->ResizeWindow = rfbResizeWindow; -+ pScreen->ClipNotify = rfbClipNotify; -+#endif -+#ifdef RENDER -+ if (ps) -+ ps->Composite = rfbComposite; -+#endif -+ -+ for (visual = pScreen->visuals; visual->vid != pScreen->rootVisual; visual++) -+ ; -+ -+ if (!visual) { -+ ErrorF("rfbScreenInit: couldn't find root visual\n"); -+ return FALSE; -+ } -+ -+ pScreenPriv->rfbServerFormat.bitsPerPixel = pScrn->beBPP; -+ pScreenPriv->rfbServerFormat.depth = pScrn->beDepth; -+ pScreenPriv->rfbServerFormat.bigEndian = !(*(char *)&rfbEndianTest); -+ pScreenPriv->rfbServerFormat.trueColour = (visual->class == TrueColor); -+ if (pScreenPriv->rfbServerFormat.trueColour) { -+ pScreenPriv->rfbServerFormat.redMax = visual->redMask >> visual->offsetRed; -+ pScreenPriv->rfbServerFormat.greenMax = visual->greenMask >> visual->offsetGreen; -+ pScreenPriv->rfbServerFormat.blueMax = visual->blueMask >> visual->offsetBlue; -+ pScreenPriv->rfbServerFormat.redShift = visual->offsetRed; -+ pScreenPriv->rfbServerFormat.greenShift = visual->offsetGreen; -+ pScreenPriv->rfbServerFormat.blueShift = visual->offsetBlue; -+ } else { -+ pScreenPriv->rfbServerFormat.redMax -+ = pScreenPriv->rfbServerFormat.greenMax -+ = pScreenPriv->rfbServerFormat.blueMax = 0; -+ pScreenPriv->rfbServerFormat.redShift -+ = pScreenPriv->rfbServerFormat.greenShift -+ = pScreenPriv->rfbServerFormat.blueShift = 0; -+ } -+ -+ return TRUE; -+} -+ -+static void -+rfbWakeupHandler ( -+ int i, -+ pointer blockData, -+ unsigned long err, -+ pointer pReadmask -+){ -+ ScreenPtr pScreen = screenInfo.screens[i]; -+ vncScreenPtr pScreenPriv = VNCPTR(pScreen); -+ /*DMXScreenInfo *pScrn = &dmxScreens[pScreen->myNum];*/ -+ -+ rfbRootPropertyChange(pScreen); /* Check clipboard */ -+ -+ rfbCheckFds(pScreen); -+ httpCheckFds(pScreen); -+#ifdef CORBA -+ corbaCheckFds(); -+#endif -+ -+ pScreen->WakeupHandler = pScreenPriv->WakeupHandler; -+ (*pScreen->WakeupHandler) (i, blockData, err, pReadmask); -+ pScreen->WakeupHandler = rfbWakeupHandler; -+} -+ -+ -+/** -+ * The rfb wake-up handler used when we're compiled into the DMX server. -+ */ -+void -+rfbWakeupHandlerDMX(void) -+{ -+ ScreenPtr pScreen = TheVNCScreen; -+ rfbRootPropertyChange(pScreen); /* Check clipboard */ -+ rfbCheckFds(pScreen); -+ httpCheckFds(pScreen); -+} -diff -pruN xorg-server-1.12.1.orig/hw/dmx/vnc/vncint.h xorg-server-1.12.1/hw/dmx/vnc/vncint.h ---- xorg-server-1.12.1.orig/hw/dmx/vnc/vncint.h 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/dmx/vnc/vncint.h 2012-04-18 14:45:21.571821016 -0500 -@@ -0,0 +1,150 @@ -+/* -+ * Copyright (C) 2002 Alan Hourihane. 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. -+ * -+ * Author: Alan Hourihane -+ */ -+ -+#ifndef _VNCINT_H_ -+#define _VNCINT_H_ -+ -+#include -+ -+extern int vncScreenPrivateIndex; -+ -+#define VNCPTR(pScreen)\ -+ (vncScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates, VNCScreenKey)) -+ -+typedef struct { -+ int rfbPort; -+ int rdpPort; -+ int udpPort; -+ int rfbListenSock; -+ int rdpListenSock; -+ int udpSock; -+ int httpPort; -+ int httpListenSock; -+ int httpSock; -+ char * httpDir; -+ char buf[HTTP_BUF_SIZE]; -+ Bool udpSockConnected; -+ char * rfbAuthPasswdFile; -+ size_t buf_filled; -+ int maxFd; -+ fd_set allFds; -+ unsigned char * oldpfbMemory; -+ Bool rfbAlwaysShared; -+ Bool rfbNeverShared; -+ Bool rfbDontDisconnect; -+ Bool rfbUserAccept; -+ Bool rfbViewOnly; -+ unsigned char * pfbMemory; -+ int paddedWidthInBytes; -+ ColormapPtr rfbInstalledColormap; -+ ColormapPtr savedColormap; -+ rfbPixelFormat rfbServerFormat; -+ Bool rfbAuthTooManyTries; -+ int rfbAuthTries; -+ Bool loginAuthEnabled; -+ struct in_addr interface; -+ OsTimerPtr timer; -+ unsigned char updateBuf[UPDATE_BUF_SIZE]; -+ int ublen; -+ int width; -+ int height; -+ int depth; -+ int bitsPerPixel; -+ -+ /* The following two members are used to minimise the amount of unnecessary -+ drawing caused by cursor movement. Whenever any drawing affects the -+ part of the screen where the cursor is, the cursor is removed first and -+ then the drawing is done (this is what the sprite routines test for). -+ Afterwards, however, we do not replace the cursor, even when the cursor -+ is logically being moved across the screen. We only draw the cursor -+ again just as we are about to send the client a framebuffer update. -+ -+ We need to be careful when removing and drawing the cursor because of -+ their relationship with the normal drawing routines. The drawing -+ routines can invoke the cursor routines, but also the cursor routines -+ themselves end up invoking drawing routines. -+ -+ Removing the cursor (rfbSpriteRemoveCursor) is eventually achieved by -+ doing a CopyArea from a pixmap to the screen, where the pixmap contains -+ the saved contents of the screen under the cursor. Before doing this, -+ however, we set cursorIsDrawn to FALSE. Then, when CopyArea is called, -+ it sees that cursorIsDrawn is FALSE and so doesn't feel the need to -+ (recursively!) remove the cursor before doing it. -+ -+ Putting up the cursor (rfbSpriteRestoreCursor) involves a call to -+ PushPixels. While this is happening, cursorIsDrawn must be FALSE so -+ that PushPixels doesn't think it has to remove the cursor first. -+ Obviously cursorIsDrawn is set to TRUE afterwards. -+ -+ Another problem we face is that drawing routines sometimes cause a -+ framebuffer update to be sent to the RFB client. When the RFB client is -+ already waiting for a framebuffer update and some drawing to the -+ framebuffer then happens, the drawing routine sees that the client is -+ ready, so it calls rfbSendFramebufferUpdate. If the cursor is not drawn -+ at this stage, it must be put up, and so rfbSpriteRestoreCursor is -+ called. However, if the original drawing routine was actually called -+ from within rfbSpriteRestoreCursor or rfbSpriteRemoveCursor we don't -+ want this to happen. So both the cursor routines set -+ dontSendFramebufferUpdate to TRUE, and all the drawing routines check -+ this before calling rfbSendFramebufferUpdate. */ -+ -+ Bool cursorIsDrawn; /* TRUE if the cursor is currently drawn */ -+ Bool dontSendFramebufferUpdate; /* TRUE while removing or drawing the -+ cursor */ -+ -+ /* wrapped screen functions */ -+ -+ CloseScreenProcPtr CloseScreen; -+ CreateGCProcPtr CreateGC; -+ CopyWindowProcPtr CopyWindow; -+ ClearToBackgroundProcPtr ClearToBackground; -+ ScreenWakeupHandlerProcPtr WakeupHandler; -+ InstallColormapProcPtr InstallColormap; -+ UninstallColormapProcPtr UninstallColormap; -+ ListInstalledColormapsProcPtr ListInstalledColormaps; -+ StoreColorsProcPtr StoreColors; -+ DisplayCursorProcPtr DisplayCursor; -+ CursorPtr pCurs; -+ Bool (*UseHWCursor)(ScreenPtr, CursorPtr); -+ Bool (*UseHWCursorARGB)(ScreenPtr, CursorPtr); -+ Bool *SWCursor; -+#ifdef CHROMIUM -+ RealizeWindowProcPtr RealizeWindow; -+ UnrealizeWindowProcPtr UnrealizeWindow; -+ DestroyWindowProcPtr DestroyWindow; -+ ResizeWindowProcPtr ResizeWindow; -+ PositionWindowProcPtr PositionWindow; -+ ClipNotifyProcPtr ClipNotify; -+#endif -+#ifdef RENDER -+ CompositeProcPtr Composite; -+#endif -+ -+} vncScreenRec, *vncScreenPtr; -+ -+extern Bool vncUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs); -+extern Bool vncUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs); -+ -+extern void -+rfbSendChromiumStart(unsigned int ipaddress, unsigned int port); -+ -+#endif /* _VNCINT_H_ */ -+ -diff -pruN xorg-server-1.12.1.orig/hw/Makefile.am xorg-server-1.12.1/hw/Makefile.am ---- xorg-server-1.12.1.orig/hw/Makefile.am 2011-09-22 20:39:53.000000000 -0500 -+++ xorg-server-1.12.1/hw/Makefile.am 2012-04-18 14:45:21.571821016 -0500 -@@ -22,6 +22,10 @@ if KDRIVE - KDRIVE_SUBDIRS = kdrive - endif - -+if VNC -+VNC_SUBDIRS = vnc -+endif -+ - if XQUARTZ - XQUARTZ_SUBDIRS = xquartz - endif -@@ -32,10 +36,11 @@ SUBDIRS = \ - $(XVFB_SUBDIRS) \ - $(XNEST_SUBDIRS) \ - $(DMX_SUBDIRS) \ -+ $(VNC_SUBDIRS) \ - $(KDRIVE_SUBDIRS) \ - $(XQUARTZ_SUBDIRS) - --DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive -+DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive vnc - - relink: - $(AM_V_at)for i in $(SUBDIRS) ; do $(MAKE) -C $$i relink || exit 1 ; done -diff -pruN xorg-server-1.12.1.orig/hw/vnc/a xorg-server-1.12.1/hw/vnc/a ---- xorg-server-1.12.1.orig/hw/vnc/a 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/a 2012-04-18 16:12:11.152692289 -0500 -@@ -0,0 +1 @@ -+#include "extinit.h" /* needed for AssignTypeANdName */ -diff -pruN xorg-server-1.12.1.orig/hw/vnc/auth.c xorg-server-1.12.1/hw/vnc/auth.c ---- xorg-server-1.12.1.orig/hw/vnc/auth.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/auth.c 2012-04-18 14:45:21.571821016 -0500 -@@ -0,0 +1,554 @@ -+/* -+ * auth.c - deal with authentication. -+ * -+ * This file implements authentication when setting up an RFB connection. -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * Copyright (C) 2003-2004 Constantin Kaplinsky. All Rights Reserved. -+ * 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#include "rfb.h" -+#include "windowstr.h" -+ -+static void rfbSendSecurityType(rfbClientPtr cl, int securityType); -+static void rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType); -+static void rfbSendTunnelingCaps(rfbClientPtr cl); -+static void rfbSendAuthCaps(rfbClientPtr cl); -+static void rfbVncAuthSendChallenge(rfbClientPtr cl); -+ -+/* -+ * rfbAuthNewClient is called right after negotiating the protocol -+ * version. Depending on the protocol version, we send either a code -+ * for authentication scheme to be used (protocol 3.3), or a list of -+ * possible "security types" (protocol 3.7). -+ */ -+ -+void -+rfbAuthNewClient(rfbClientPtr cl) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ int securityType = rfbSecTypeInvalid; -+ -+ if ((!pVNC->rfbAuthPasswdFile && !pVNC->loginAuthEnabled) || cl->reverseConnection) { -+ securityType = rfbSecTypeNone; -+ } else { -+ if (rfbAuthIsBlocked(cl)) { -+ rfbLog("Too many authentication failures - client rejected\n"); -+ rfbClientConnFailed(cl, "Too many authentication failures"); -+ return; -+ } -+ if (pVNC->rfbAuthPasswdFile) -+ securityType = rfbSecTypeVncAuth; -+ } -+ -+ if (cl->protocol_minor_ver < 7) { -+ /* Make sure we use only RFB 3.3 compatible security types. */ -+ if (securityType == rfbSecTypeInvalid) { -+ rfbLog("VNC authentication disabled - RFB 3.3 client rejected\n"); -+ rfbClientConnFailed(cl, "Your viewer cannot handle required " -+ "authentication methods"); -+ return; -+ } -+ rfbSendSecurityType(cl, securityType); -+ } else { -+ /* Here it's ok when securityType is set to rfbSecTypeInvalid. */ -+ rfbSendSecurityTypeList(cl, securityType); -+ } -+} -+ -+ -+/* -+ * Tell the client what security type will be used (protocol 3.3). -+ */ -+ -+static void -+rfbSendSecurityType(rfbClientPtr cl, int securityType) -+{ -+ CARD32 value32; -+ -+ /* Send the value. */ -+ value32 = Swap32IfLE(securityType); -+ if (WriteExact(cl->sock, (char *)&value32, 4) < 0) { -+ rfbLogPerror("rfbSendSecurityType: write"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ /* Decide what to do next. */ -+ switch (securityType) { -+ case rfbSecTypeNone: -+ /* Dispatch client input to rfbProcessClientInitMessage. */ -+ cl->state = RFB_INITIALISATION; -+ break; -+ case rfbSecTypeVncAuth: -+ /* Begin the standard VNC authentication procedure. */ -+ rfbVncAuthSendChallenge(cl); -+ break; -+ default: -+ /* Impossible case (hopefully). */ -+ rfbLogPerror("rfbSendSecurityType: assertion failed"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ } -+} -+ -+ -+/* -+ * Advertise our supported security types (protocol 3.7). The list -+ * will include one standard security type (if primaryType is not set -+ * to rfbSecTypeInvalid), and then one more value telling the client -+ * that we support TightVNC protocol extensions. Thus, currently, -+ * there will be either 1 or 2 items in the list. -+ */ -+ -+static void -+rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType) -+{ -+ int count = 1; -+ -+ /* Fill in the list of security types in the client structure. */ -+ if (primaryType != rfbSecTypeInvalid) { -+ cl->securityTypes[count++] = (CARD8)primaryType; -+ } -+ cl->securityTypes[count] = (CARD8)rfbSecTypeTight; -+ cl->securityTypes[0] = (CARD8)count++; -+ -+ /* Send the list. */ -+ if (WriteExact(cl->sock, (char *)cl->securityTypes, count) < 0) { -+ rfbLogPerror("rfbSendSecurityTypeList: write"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ /* Dispatch client input to rfbProcessClientSecurityType. */ -+ cl->state = RFB_SECURITY_TYPE; -+} -+ -+ -+/* -+ * Read the security type chosen by the client (protocol 3.7). -+ */ -+ -+void -+rfbProcessClientSecurityType(rfbClientPtr cl) -+{ -+ int n, count, i; -+ CARD8 chosenType; -+ -+ /* Read the security type. */ -+ n = ReadExact(cl->sock, (char *)&chosenType, 1); -+ if (n <= 0) { -+ if (n == 0) -+ rfbLog("rfbProcessClientSecurityType: client gone\n"); -+ else -+ rfbLogPerror("rfbProcessClientSecurityType: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ /* Make sure it was present in the list sent by the server. */ -+ count = (int)cl->securityTypes[0]; -+ for (i = 1; i <= count; i++) { -+ if (chosenType == cl->securityTypes[i]) -+ break; -+ } -+ if (i > count) { -+ rfbLog("rfbProcessClientSecurityType: " -+ "wrong security type requested\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ /* Now go to the proper authentication procedure. */ -+ switch (chosenType) { -+ case rfbSecTypeNone: -+ /* Dispatch client input to rfbProcessClientInitMessage. */ -+ cl->state = RFB_INITIALISATION; -+ break; -+ case rfbSecTypeVncAuth: -+ /* Begin the standard VNC authentication procedure. */ -+ rfbVncAuthSendChallenge(cl); -+ break; -+ case rfbSecTypeTight: -+ /* We are lucky: the viewer supports TightVNC extensions. */ -+ rfbLog("Enabling TightVNC protocol extensions\n"); -+ /* Switch to the protocol 3.7t. */ -+ cl->protocol_tightvnc = TRUE; -+ /* Advertise our tunneling capabilities. */ -+ rfbSendTunnelingCaps(cl); -+ break; -+ default: -+ /* Impossible case (hopefully). */ -+ rfbLog("rfbProcessClientSecurityType: " -+ "unknown authentication scheme\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ } -+} -+ -+ -+/* -+ * Send the list of our tunneling capabilities (protocol 3.7t). -+ */ -+ -+static void -+rfbSendTunnelingCaps(rfbClientPtr cl) -+{ -+ rfbTunnelingCapsMsg caps; -+ CARD32 nTypes = 0; /* we don't support tunneling yet */ -+ -+ caps.nTunnelTypes = Swap32IfLE(nTypes); -+ if (WriteExact(cl->sock, (char *)&caps, sz_rfbTunnelingCapsMsg) < 0) { -+ rfbLogPerror("rfbSendTunnelingCaps: write"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ if (nTypes) { -+ /* Dispatch client input to rfbProcessClientTunnelingType(). */ -+ cl->state = RFB_TUNNELING_TYPE; -+ } else { -+ rfbSendAuthCaps(cl); -+ } -+} -+ -+ -+/* -+ * Read tunneling type requested by the client (protocol 3.7t). -+ * NOTE: Currently, we don't support tunneling, and this function -+ * can never be called. -+ */ -+ -+void -+rfbProcessClientTunnelingType(rfbClientPtr cl) -+{ -+ /* If we were called, then something's really wrong. */ -+ rfbLog("rfbProcessClientTunnelingType: not implemented\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+} -+ -+ -+/* -+ * Send the list of our authentication capabilities to the client -+ * (protocol 3.7t). -+ */ -+ -+static void -+rfbSendAuthCaps(rfbClientPtr cl) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ Bool authRequired; -+ rfbAuthenticationCapsMsg caps; -+ rfbCapabilityInfo caplist[MAX_AUTH_CAPS]; -+ int count = 0; -+ -+ authRequired = ((pVNC->rfbAuthPasswdFile != NULL || pVNC->loginAuthEnabled) && -+ !cl->reverseConnection); -+ -+ if (authRequired) { -+ if (pVNC->loginAuthEnabled) { -+ SetCapInfo(&caplist[count], rfbAuthUnixLogin, rfbTightVncVendor); -+ cl->authCaps[count++] = rfbAuthUnixLogin; -+ } -+ if (pVNC->rfbAuthPasswdFile != NULL) { -+ SetCapInfo(&caplist[count], rfbAuthVNC, rfbStandardVendor); -+ cl->authCaps[count++] = rfbAuthVNC; -+ } -+ if (count == 0) { -+ /* Should never happen. */ -+ rfbLog("rfbSendAuthCaps: assertion failed\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ } -+ -+ cl->nAuthCaps = count; -+ caps.nAuthTypes = Swap32IfLE((CARD32)count); -+ if (WriteExact(cl->sock, (char *)&caps, sz_rfbAuthenticationCapsMsg) < 0) { -+ rfbLogPerror("rfbSendAuthCaps: write"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ if (count) { -+ if (WriteExact(cl->sock, (char *)&caplist[0], -+ count * sz_rfbCapabilityInfo) < 0) { -+ rfbLogPerror("rfbSendAuthCaps: write"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ /* Dispatch client input to rfbProcessClientAuthType. */ -+ cl->state = RFB_AUTH_TYPE; -+ } else { -+ /* Dispatch client input to rfbProcessClientInitMessage. */ -+ cl->state = RFB_INITIALISATION; -+ } -+} -+ -+ -+/* -+ * Read client's preferred authentication type (protocol 3.7t). -+ */ -+ -+void -+rfbProcessClientAuthType(rfbClientPtr cl) -+{ -+ CARD32 auth_type; -+ int n, i; -+ -+ /* Read authentication type selected by the client. */ -+ n = ReadExact(cl->sock, (char *)&auth_type, sizeof(auth_type)); -+ if (n <= 0) { -+ if (n == 0) -+ rfbLog("rfbProcessClientAuthType: client gone\n"); -+ else -+ rfbLogPerror("rfbProcessClientAuthType: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ auth_type = Swap32IfLE(auth_type); -+ -+ /* Make sure it was present in the list sent by the server. */ -+ for (i = 0; i < cl->nAuthCaps; i++) { -+ if (auth_type == cl->authCaps[i]) -+ break; -+ } -+ if (i >= cl->nAuthCaps) { -+ rfbLog("rfbProcessClientAuthType: " -+ "wrong authentication type requested\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ switch (auth_type) { -+ case rfbAuthNone: -+ /* Dispatch client input to rfbProcessClientInitMessage. */ -+ cl->state = RFB_INITIALISATION; -+ break; -+ case rfbAuthVNC: -+ rfbVncAuthSendChallenge(cl); -+ break; -+ case rfbAuthUnixLogin: -+ /* FIXME: Do (cl->state = RFB_LOGIN_AUTH) instead? */ -+ rfbLoginAuthProcessClientMessage(cl); -+ break; -+ default: -+ rfbLog("rfbProcessClientAuthType: unknown authentication scheme\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ } -+} -+ -+ -+/* -+ * Send the authentication challenge. -+ */ -+ -+static void -+rfbVncAuthSendChallenge(rfbClientPtr cl) -+{ -+ vncRandomBytes(cl->authChallenge); -+ if (WriteExact(cl->sock, (char *)cl->authChallenge, CHALLENGESIZE) < 0) { -+ rfbLogPerror("rfbVncAuthSendChallenge: write"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ /* Dispatch client input to rfbVncAuthProcessResponse. */ -+ cl->state = RFB_AUTHENTICATION; -+} -+ -+/* -+ * rfbVncAuthProcessResponse is called when the client sends its -+ * authentication response. -+ */ -+ -+void -+rfbVncAuthProcessResponse(rfbClientPtr cl) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ char passwdFullControl[9]; -+ char passwdViewOnly[9]; -+ int numPasswords; -+ Bool ok; -+ int n; -+ CARD8 encryptedChallenge1[CHALLENGESIZE]; -+ CARD8 encryptedChallenge2[CHALLENGESIZE]; -+ CARD8 response[CHALLENGESIZE]; -+ CARD32 authResult; -+ -+ n = ReadExact(cl->sock, (char *)response, CHALLENGESIZE); -+ if (n <= 0) { -+ if (n != 0) -+ rfbLogPerror("rfbVncAuthProcessResponse: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ numPasswords = vncDecryptPasswdFromFile2(pVNC->rfbAuthPasswdFile, -+ passwdFullControl, -+ passwdViewOnly); -+ if (numPasswords == 0) { -+ rfbLog("rfbVncAuthProcessResponse: could not get password from %s\n", -+ pVNC->rfbAuthPasswdFile); -+ -+ authResult = Swap32IfLE(rfbVncAuthFailed); -+ -+ if (WriteExact(cl->sock, (char *)&authResult, 4) < 0) { -+ rfbLogPerror("rfbVncAuthProcessResponse: write"); -+ } -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ memcpy(encryptedChallenge1, cl->authChallenge, CHALLENGESIZE); -+ vncEncryptBytes(encryptedChallenge1, passwdFullControl); -+ memcpy(encryptedChallenge2, cl->authChallenge, CHALLENGESIZE); -+ vncEncryptBytes(encryptedChallenge2, -+ (numPasswords == 2) ? passwdViewOnly : passwdFullControl); -+ -+ /* Lose the passwords from memory */ -+ memset(passwdFullControl, 0, 9); -+ memset(passwdViewOnly, 0, 9); -+ -+ ok = FALSE; -+ if (memcmp(encryptedChallenge1, response, CHALLENGESIZE) == 0) { -+ rfbLog("Full-control authentication passed by %s\n", cl->host); -+ ok = TRUE; -+ cl->viewOnly = FALSE; -+ } else if (memcmp(encryptedChallenge2, response, CHALLENGESIZE) == 0) { -+ rfbLog("View-only authentication passed by %s\n", cl->host); -+ ok = TRUE; -+ cl->viewOnly = TRUE; -+ } -+ -+ if (!ok) { -+ rfbLog("rfbVncAuthProcessResponse: authentication failed from %s\n", -+ cl->host); -+ -+ if (rfbAuthConsiderBlocking(cl)) { -+ authResult = Swap32IfLE(rfbVncAuthTooMany); -+ } else { -+ authResult = Swap32IfLE(rfbVncAuthFailed); -+ } -+ -+ if (WriteExact(cl->sock, (char *)&authResult, 4) < 0) { -+ rfbLogPerror("rfbVncAuthProcessResponse: write"); -+ } -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ rfbAuthUnblock(cl); -+ -+ authResult = Swap32IfLE(rfbVncAuthOK); -+ -+ if (WriteExact(cl->sock, (char *)&authResult, 4) < 0) { -+ rfbLogPerror("rfbVncAuthProcessResponse: write"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ /* Dispatch client input to rfbProcessClientInitMessage(). */ -+ cl->state = RFB_INITIALISATION; -+} -+ -+ -+/* -+ * Functions to prevent too many successive authentication failures. -+ * FIXME: This should be performed separately per each client IP. -+ */ -+ -+/* Maximum authentication failures before blocking connections */ -+#define MAX_AUTH_TRIES 5 -+ -+/* Delay in ms, doubles for each failure over MAX_AUTH_TRIES */ -+#define AUTH_TOO_MANY_BASE_DELAY 10 * 1000 -+ -+/* -+ * This function should not be called directly, it is called by -+ * setting a timer in rfbAuthConsiderBlocking(). -+ */ -+ -+static CARD32 -+rfbAuthReenable(OsTimerPtr timer, CARD32 now, pointer arg) -+{ -+ rfbClientPtr cl = (rfbClientPtr) arg; -+ VNCSCREENPTR(cl->pScreen); -+ (void)cl; -+ pVNC->rfbAuthTooManyTries = FALSE; -+ return 0; -+} -+ -+/* -+ * This function should be called after each authentication failure. -+ * The return value will be true if there was too many failures. -+ */ -+ -+Bool -+rfbAuthConsiderBlocking(rfbClientPtr cl) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ int i; -+ -+ pVNC->rfbAuthTries++; -+ -+ if (pVNC->rfbAuthTries >= MAX_AUTH_TRIES) { -+ CARD32 delay = AUTH_TOO_MANY_BASE_DELAY; -+ for (i = MAX_AUTH_TRIES; i < pVNC->rfbAuthTries; i++) -+ delay *= 2; -+ pVNC->timer = TimerSet(pVNC->timer, 0, delay, rfbAuthReenable, cl); -+ pVNC->rfbAuthTooManyTries = TRUE; -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+/* -+ * This function should be called after successful authentication. -+ * It resets the counter of authentication failures. Note that it's -+ * not necessary to clear the rfbAuthTooManyTries flag as it will be -+ * reset by the timer function. -+ */ -+ -+void -+rfbAuthUnblock(rfbClientPtr cl) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ pVNC->rfbAuthTries = 0; -+} -+ -+/* -+ * This function should be called before authentication process. -+ * The return value will be true if there was too many authentication -+ * failures, and the server should not allow another try. -+ */ -+ -+Bool -+rfbAuthIsBlocked(rfbClientPtr cl) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ return pVNC->rfbAuthTooManyTries; -+} -+ -diff -pruN xorg-server-1.12.1.orig/hw/vnc/cmap.c xorg-server-1.12.1/hw/vnc/cmap.c ---- xorg-server-1.12.1.orig/hw/vnc/cmap.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/cmap.c 2012-04-18 14:45:21.572821004 -0500 -@@ -0,0 +1,159 @@ -+/* -+ * cmap.c -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+ -+/* -+ -+Copyright (c) 1993 X Consortium -+ -+Permission is hereby granted, free of charge, to any person obtaining -+a copy of this software and associated documentation files (the -+"Software"), to deal in the Software without restriction, including -+without limitation the rights to use, copy, modify, merge, publish, -+distribute, sublicense, and/or sell copies of the Software, and to -+permit persons to whom the Software is furnished to do so, subject to -+the following conditions: -+ -+The above copyright notice and this permission notice shall be included -+in all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR -+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+OTHER DEALINGS IN THE SOFTWARE. -+ -+Except as contained in this notice, the name of the X Consortium shall -+not be used in advertising or otherwise to promote the sale, use or -+other dealings in this Software without prior written authorization -+from the X Consortium. -+ -+*/ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#include "rfb.h" -+ -+int -+rfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps) -+{ -+ VNCSCREENPTR(pScreen); -+ /* By the time we are processing requests, we can guarantee that there -+ * is always a colormap installed */ -+ if (pVNC->rfbInstalledColormap) -+ *pmaps = pVNC->rfbInstalledColormap->mid; -+ -+#if XFREE86VNC -+ pScreen->ListInstalledColormaps = pVNC->ListInstalledColormaps; -+ (*pScreen->ListInstalledColormaps)(pScreen, pmaps); -+ pScreen->ListInstalledColormaps = rfbListInstalledColormaps; -+#endif -+ -+ return (1); -+} -+ -+ -+void -+rfbInstallColormap(ColormapPtr pmap) -+{ -+ VNCSCREENPTR(pmap->pScreen); -+ -+ if (pmap != pVNC->rfbInstalledColormap) { -+ -+ if(pVNC->rfbInstalledColormap != (ColormapPtr)None) -+ WalkTree(pmap->pScreen, TellLostMap, -+ (char *)&pVNC->rfbInstalledColormap->mid); -+ /* Install pmap */ -+ pVNC->rfbInstalledColormap = pmap; -+ WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid); -+ -+ rfbSetClientColourMaps(0, 0); -+ } -+#if XFREE86VNC -+ pmap->pScreen->InstallColormap = pVNC->InstallColormap; -+ (*pmap->pScreen->InstallColormap)(pmap); -+ pmap->pScreen->InstallColormap = rfbInstallColormap; -+#endif -+} -+ -+void -+rfbUninstallColormap(ColormapPtr pmap) -+{ -+ VNCSCREENPTR(pmap->pScreen); -+ -+ if(pmap == pVNC->rfbInstalledColormap) -+ { -+ if (pmap->mid != pmap->pScreen->defColormap) -+ { -+ dixLookupResourceByType((pointer)&pVNC->rfbInstalledColormap, -+ pmap->pScreen->defColormap, RT_COLORMAP, -+ NullClient, DixUnknownAccess); -+ (*pmap->pScreen->InstallColormap)(pVNC->rfbInstalledColormap); -+ } -+ } -+#if XFREE86VNC -+ pmap->pScreen->UninstallColormap = pVNC->UninstallColormap; -+ (*pmap->pScreen->UninstallColormap)(pmap); -+ pmap->pScreen->UninstallColormap = rfbUninstallColormap; -+#endif -+} -+ -+ -+/* -+ * rfbStoreColors. We have a set of pixels but they may be in any order. -+ * If some of them happen to be in continuous ascending order then we can -+ * group them together into a single call to rfbSetClientColourMaps. -+ */ -+ -+void -+rfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs) -+{ -+ VNCSCREENPTR(pmap->pScreen); -+ int i; -+ int first = -1; -+ int n = 0; -+ -+ if (pmap == pVNC->rfbInstalledColormap) { -+ for (i = 0; i < ndef; i++) { -+ if ((first != -1) && (first + n == pdefs[i].pixel)) { -+ n++; -+ } else { -+ if (first != -1) { -+ rfbSetClientColourMaps(first, n); -+ } -+ first = pdefs[i].pixel; -+ n = 1; -+ } -+ } -+ rfbSetClientColourMaps(first, n); -+ } -+#if XFREE86VNC -+ pmap->pScreen->StoreColors = pVNC->StoreColors; -+ (*pmap->pScreen->StoreColors)(pmap, ndef, pdefs); -+ pmap->pScreen->StoreColors = rfbStoreColors; -+#endif -+} -diff -pruN xorg-server-1.12.1.orig/hw/vnc/corre.c xorg-server-1.12.1/hw/vnc/corre.c ---- xorg-server-1.12.1.orig/hw/vnc/corre.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/corre.c 2012-04-18 14:45:21.572821004 -0500 -@@ -0,0 +1,343 @@ -+/* -+ * corre.c -+ * -+ * Routines to implement Compact Rise-and-Run-length Encoding (CoRRE). This -+ * code is based on krw's original javatel rfbserver. -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#include -+#include "rfb.h" -+ -+/* -+ * rreBeforeBuf contains pixel data in the client's format. -+ * rreAfterBuf contains the RRE encoded version. If the RRE encoded version is -+ * larger than the raw data or if it exceeds rreAfterBufSize then -+ * raw encoding is used instead. -+ */ -+ -+static int rreBeforeBufSize = 0; -+static unsigned char *rreBeforeBuf = NULL; -+ -+static int rreAfterBufSize = 0; -+static unsigned char *rreAfterBuf = NULL; -+static int rreAfterBufLen; -+ -+static int subrectEncode8(CARD8 *data, int w, int h); -+static int subrectEncode16(CARD16 *data, int w, int h); -+static int subrectEncode32(CARD32 *data, int w, int h); -+static CARD32 getBgColour(char *data, int size, int bpp); -+static Bool rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl, int x, int y, -+ int w, int h); -+ -+ -+/* -+ * rfbSendRectEncodingCoRRE - send an arbitrary size rectangle using CoRRE -+ * encoding. -+ */ -+ -+Bool -+rfbSendRectEncodingCoRRE(rfbClientPtr cl, int x, int y, int w, int h) -+{ -+ if (h > cl->correMaxHeight) { -+ return (rfbSendRectEncodingCoRRE(cl, x, y, w, cl->correMaxHeight) && -+ rfbSendRectEncodingCoRRE(cl, x, y + cl->correMaxHeight, -+ w, h - cl->correMaxHeight)); -+ } -+ -+ if (w > cl->correMaxWidth) { -+ return (rfbSendRectEncodingCoRRE(cl, x, y, cl->correMaxWidth, h) && -+ rfbSendRectEncodingCoRRE(cl, x + cl->correMaxWidth, y, -+ w - cl->correMaxWidth, h)); -+ } -+ -+ return rfbSendSmallRectEncodingCoRRE(cl, x, y, w, h); -+} -+ -+ -+ -+/* -+ * rfbSendSmallRectEncodingCoRRE - send a small (guaranteed < 256x256) -+ * rectangle using CoRRE encoding. -+ */ -+ -+static Bool -+rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl, int x, int y, int w, int h) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ rfbFramebufferUpdateRectHeader rect; -+ rfbRREHeader hdr; -+ int nSubrects; -+ int i; -+ int maxRawSize = (pVNC->width * pVNC->height -+ * (cl->format.bitsPerPixel / 8)); -+ -+ if (rreBeforeBufSize < maxRawSize) { -+ rreBeforeBufSize = maxRawSize; -+ if (rreBeforeBuf == NULL) -+ rreBeforeBuf = (unsigned char *)malloc(rreBeforeBufSize); -+ else -+ rreBeforeBuf = (unsigned char *)realloc(rreBeforeBuf, rreBeforeBufSize); -+ } -+ -+ if (rreAfterBufSize < maxRawSize) { -+ rreAfterBufSize = maxRawSize; -+ if (rreAfterBuf == NULL) -+ rreAfterBuf = (unsigned char *)malloc(rreAfterBufSize); -+ else -+ rreAfterBuf = (unsigned char *)realloc(rreAfterBuf, rreAfterBufSize); -+ } -+ -+ (*cl->translateFn)(cl->pScreen, cl->translateLookupTable, -+ &pVNC->rfbServerFormat, -+ &cl->format, rreBeforeBuf, -+ pVNC->paddedWidthInBytes, w, h, x, y); -+ -+ switch (cl->format.bitsPerPixel) { -+ case 8: -+ nSubrects = subrectEncode8((CARD8 *)rreBeforeBuf, w, h); -+ break; -+ case 16: -+ nSubrects = subrectEncode16((CARD16 *)rreBeforeBuf, w, h); -+ break; -+ case 32: -+ nSubrects = subrectEncode32((CARD32 *)rreBeforeBuf, w, h); -+ break; -+ default: -+ rfbLog("getBgColour: bpp %d?\n",cl->format.bitsPerPixel); -+ exit(1); -+ } -+ -+ if (nSubrects < 0) { -+ -+ /* RRE encoding was too large, use raw */ -+ -+ return rfbSendRectEncodingRaw(cl, x, y, w, h); -+ } -+ -+ cl->rfbRectanglesSent[rfbEncodingCoRRE]++; -+ cl->rfbBytesSent[rfbEncodingCoRRE] += (sz_rfbFramebufferUpdateRectHeader -+ + sz_rfbRREHeader + rreAfterBufLen); -+ -+ if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader -+ > UPDATE_BUF_SIZE) -+ { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ rect.r.x = Swap16IfLE(x); -+ rect.r.y = Swap16IfLE(y); -+ rect.r.w = Swap16IfLE(w); -+ rect.r.h = Swap16IfLE(h); -+ rect.encoding = Swap32IfLE(rfbEncodingCoRRE); -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect, -+ sz_rfbFramebufferUpdateRectHeader); -+ pVNC->ublen += sz_rfbFramebufferUpdateRectHeader; -+ -+ hdr.nSubrects = Swap32IfLE(nSubrects); -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&hdr, sz_rfbRREHeader); -+ pVNC->ublen += sz_rfbRREHeader; -+ -+ for (i = 0; i < rreAfterBufLen;) { -+ -+ int bytesToCopy = UPDATE_BUF_SIZE - pVNC->ublen; -+ -+ if (i + bytesToCopy > rreAfterBufLen) { -+ bytesToCopy = rreAfterBufLen - i; -+ } -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], &rreAfterBuf[i], bytesToCopy); -+ -+ pVNC->ublen += bytesToCopy; -+ i += bytesToCopy; -+ -+ if (pVNC->ublen == UPDATE_BUF_SIZE) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ } -+ -+ return TRUE; -+} -+ -+ -+ -+/* -+ * subrectEncode() encodes the given multicoloured rectangle as a background -+ * colour overwritten by single-coloured rectangles. It returns the number -+ * of subrectangles in the encoded buffer, or -1 if subrect encoding won't -+ * fit in the buffer. It puts the encoded rectangles in rreAfterBuf. The -+ * single-colour rectangle partition is not optimal, but does find the biggest -+ * horizontal or vertical rectangle top-left anchored to each consecutive -+ * coordinate position. -+ * -+ * The coding scheme is simply [...] where each -+ * is []. -+ */ -+ -+#define DEFINE_SUBRECT_ENCODE(bpp) \ -+static int \ -+subrectEncode##bpp(CARD##bpp *data, int w, int h) \ -+{ \ -+ CARD##bpp cl; \ -+ rfbCoRRERectangle subrect; \ -+ int x,y; \ -+ int i,j; \ -+ int hx=0,hy,vx=0,vy; \ -+ int hyflag; \ -+ CARD##bpp *seg; \ -+ CARD##bpp *line; \ -+ int hw,hh,vw,vh; \ -+ int thex,they,thew,theh; \ -+ int numsubs = 0; \ -+ int newLen; \ -+ CARD##bpp bg = (CARD##bpp)getBgColour((char*)data,w*h,bpp); \ -+ \ -+ *((CARD##bpp*)rreAfterBuf) = bg; \ -+ \ -+ rreAfterBufLen = (bpp/8); \ -+ \ -+ for (y=0; y 0) && (i >= hx)) {hy += 1;} else {hyflag = 0;} \ -+ } \ -+ vy = j-1; \ -+ \ -+ /* We now have two possible subrects: (x,y,hx,hy) and (x,y,vx,vy) \ -+ * We'll choose the bigger of the two. \ -+ */ \ -+ hw = hx-x+1; \ -+ hh = hy-y+1; \ -+ vw = vx-x+1; \ -+ vh = vy-y+1; \ -+ \ -+ thex = x; \ -+ they = y; \ -+ \ -+ if ((hw*hh) > (vw*vh)) { \ -+ thew = hw; \ -+ theh = hh; \ -+ } else { \ -+ thew = vw; \ -+ theh = vh; \ -+ } \ -+ \ -+ subrect.x = thex; \ -+ subrect.y = they; \ -+ subrect.w = thew; \ -+ subrect.h = theh; \ -+ \ -+ newLen = rreAfterBufLen + (bpp/8) + sz_rfbCoRRERectangle; \ -+ if ((newLen > (w * h * (bpp/8))) || (newLen > rreAfterBufSize)) \ -+ return -1; \ -+ \ -+ numsubs += 1; \ -+ *((CARD##bpp*)(rreAfterBuf + rreAfterBufLen)) = cl; \ -+ rreAfterBufLen += (bpp/8); \ -+ memcpy(&rreAfterBuf[rreAfterBufLen],&subrect,sz_rfbCoRRERectangle); \ -+ rreAfterBufLen += sz_rfbCoRRERectangle; \ -+ \ -+ /* \ -+ * Now mark the subrect as done. \ -+ */ \ -+ for (j=they; j < (they+theh); j++) { \ -+ for (i=thex; i < (thex+thew); i++) { \ -+ data[j*w+i] = bg; \ -+ } \ -+ } \ -+ } \ -+ } \ -+ } \ -+ \ -+ return numsubs; \ -+} -+ -+DEFINE_SUBRECT_ENCODE(8) -+DEFINE_SUBRECT_ENCODE(16) -+DEFINE_SUBRECT_ENCODE(32) -+ -+ -+/* -+ * getBgColour() gets the most prevalent colour in a byte array. -+ */ -+static CARD32 -+getBgColour(char *data, int size, int bpp) -+{ -+ -+#define NUMCLRS 256 -+ -+ static int counts[NUMCLRS]; -+ int i,j,k; -+ -+ int maxcount = 0; -+ CARD8 maxclr = 0; -+ -+ if (bpp != 8) { -+ if (bpp == 16) { -+ return ((CARD16 *)data)[0]; -+ } else if (bpp == 32) { -+ return ((CARD32 *)data)[0]; -+ } else { -+ rfbLog("getBgColour: bpp %d?\n",bpp); -+ exit(1); -+ } -+ } -+ -+ for (i=0; i= NUMCLRS) { -+ rfbLog("getBgColour: unusual colour = %d\n", k); -+ exit(1); -+ } -+ counts[k] += 1; -+ if (counts[k] > maxcount) { -+ maxcount = counts[k]; -+ maxclr = ((CARD8 *)data)[j]; -+ } -+ } -+ -+ return maxclr; -+} -diff -pruN xorg-server-1.12.1.orig/hw/vnc/cursor.c xorg-server-1.12.1/hw/vnc/cursor.c ---- xorg-server-1.12.1.orig/hw/vnc/cursor.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/cursor.c 2012-04-18 14:45:21.572821004 -0500 -@@ -0,0 +1,398 @@ -+/* -+ * cursor.c - support for cursor shape updates. -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. -+ * 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#include -+#include "rfb.h" -+#include "mipointer.h" -+#include "sprite.h" -+#include "cursorstr.h" -+#include "servermd.h" -+#include "inputstr.h" -+ -+ -+/* Copied from Xvnc/lib/font/util/utilbitmap.c */ -+static unsigned char _reverse_byte[0x100] = { -+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, -+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, -+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, -+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, -+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, -+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, -+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, -+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, -+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, -+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, -+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, -+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, -+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, -+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, -+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, -+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, -+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, -+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, -+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, -+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, -+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, -+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, -+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, -+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, -+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, -+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, -+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, -+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, -+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, -+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, -+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, -+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff -+}; -+ -+ -+static int EncodeRichCursorData8 (unsigned char *buf, rfbPixelFormat *fmt, -+ CursorPtr pCursor); -+static int EncodeRichCursorData16 (ScreenPtr pScreen, -+ unsigned char *buf, rfbPixelFormat *fmt, -+ CursorPtr pCursor); -+static int EncodeRichCursorData32 (ScreenPtr pScreen, -+ unsigned char *buf, rfbPixelFormat *fmt, -+ CursorPtr pCursor); -+ -+ -+/* -+ * Send cursor shape either in X-style format or in client pixel format. -+ */ -+ -+Bool -+rfbSendCursorShape(rfbClientPtr cl, ScreenPtr pScreen) -+{ -+ VNCSCREENPTR(pScreen); -+ CursorPtr pCursor; -+ rfbFramebufferUpdateRectHeader rect; -+ rfbXCursorColors colors; -+ int saved_ublen; -+ int bitmapRowBytes, paddedRowBytes, maskBytes, dataBytes; -+ int i, j; -+ CARD8 *bitmapData; -+ CARD8 bitmapByte; -+ -+ if (cl->useRichCursorEncoding) { -+ rect.encoding = Swap32IfLE(rfbEncodingRichCursor); -+ } else { -+ rect.encoding = Swap32IfLE(rfbEncodingXCursor); -+ } -+ -+#if XFREE86VNC -+ pCursor = pVNC->pCurs; -+#else -+ pCursor = rfbSpriteGetCursorPtr(pScreen); -+#endif -+ -+ /* If there is no cursor, send update with empty cursor data. */ -+ -+ if ( pCursor != NULL && -+ pCursor->bits->width == 1 && -+ pCursor->bits->height == 1 && -+ pCursor->bits->mask[0] == 0 ) { -+ pCursor = NULL; -+ } -+ -+ if (pCursor == NULL) { -+ if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE ) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ rect.r.x = rect.r.y = 0; -+ rect.r.w = rect.r.h = 0; -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect, -+ sz_rfbFramebufferUpdateRectHeader); -+ pVNC->ublen += sz_rfbFramebufferUpdateRectHeader; -+ -+ cl->rfbCursorShapeBytesSent += sz_rfbFramebufferUpdateRectHeader; -+ cl->rfbCursorShapeUpdatesSent++; -+ -+ return TRUE; -+ } -+ -+ /* Calculate data sizes. */ -+ -+ bitmapRowBytes = (pCursor->bits->width + 7) / 8; -+ paddedRowBytes = PixmapBytePad(pCursor->bits->width, 1); -+ maskBytes = bitmapRowBytes * pCursor->bits->height; -+ dataBytes = (cl->useRichCursorEncoding) ? -+ (pCursor->bits->width * pCursor->bits->height * -+ (cl->format.bitsPerPixel / 8)) : maskBytes; -+ -+ /* Send buffer contents if needed. */ -+ -+ if ( pVNC->ublen + sz_rfbFramebufferUpdateRectHeader + -+ sz_rfbXCursorColors + maskBytes + dataBytes > UPDATE_BUF_SIZE ) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ if ( pVNC->ublen + sz_rfbFramebufferUpdateRectHeader + -+ sz_rfbXCursorColors + maskBytes + dataBytes > UPDATE_BUF_SIZE ) { -+ return FALSE; /* FIXME. */ -+ } -+ -+ saved_ublen = pVNC->ublen; -+ -+ /* Prepare rectangle header. */ -+ -+ rect.r.x = Swap16IfLE(pCursor->bits->xhot); -+ rect.r.y = Swap16IfLE(pCursor->bits->yhot); -+ rect.r.w = Swap16IfLE(pCursor->bits->width); -+ rect.r.h = Swap16IfLE(pCursor->bits->height); -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader); -+ pVNC->ublen += sz_rfbFramebufferUpdateRectHeader; -+ -+ /* Prepare actual cursor data (depends on encoding used). */ -+ -+ if (!cl->useRichCursorEncoding) { -+ /* XCursor encoding. */ -+ colors.foreRed = (char)(pCursor->foreRed >> 8); -+ colors.foreGreen = (char)(pCursor->foreGreen >> 8); -+ colors.foreBlue = (char)(pCursor->foreBlue >> 8); -+ colors.backRed = (char)(pCursor->backRed >> 8); -+ colors.backGreen = (char)(pCursor->backGreen >> 8); -+ colors.backBlue = (char)(pCursor->backBlue >> 8); -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&colors, sz_rfbXCursorColors); -+ pVNC->ublen += sz_rfbXCursorColors; -+ -+ bitmapData = (CARD8 *)pCursor->bits->source; -+ -+ for (i = 0; i < pCursor->bits->height; i++) { -+ for (j = 0; j < bitmapRowBytes; j++) { -+ bitmapByte = bitmapData[i * paddedRowBytes + j]; -+ if (screenInfo.bitmapBitOrder == LSBFirst) { -+ bitmapByte = _reverse_byte[bitmapByte]; -+ } -+ pVNC->updateBuf[pVNC->ublen++] = (char)bitmapByte; -+ } -+ } -+ } else { -+ /* RichCursor encoding. */ -+ switch (cl->format.bitsPerPixel) { -+ case 8: -+ pVNC->ublen += EncodeRichCursorData8(&pVNC->updateBuf[pVNC->ublen], -+ &cl->format, pCursor); -+ break; -+ case 16: -+ pVNC->ublen += EncodeRichCursorData16(pScreen, &pVNC->updateBuf[pVNC->ublen], -+ &cl->format, pCursor); -+ break; -+ case 32: -+ pVNC->ublen += EncodeRichCursorData32(pScreen, &pVNC->updateBuf[pVNC->ublen], -+ &cl->format, pCursor); -+ break; -+ default: -+ return FALSE; -+ } -+ } -+ -+ /* Prepare transparency mask. */ -+ -+ bitmapData = (CARD8 *)pCursor->bits->mask; -+ -+ for (i = 0; i < pCursor->bits->height; i++) { -+ for (j = 0; j < bitmapRowBytes; j++) { -+ bitmapByte = bitmapData[i * paddedRowBytes + j]; -+ if (screenInfo.bitmapBitOrder == LSBFirst) { -+ bitmapByte = _reverse_byte[bitmapByte]; -+ } -+ pVNC->updateBuf[pVNC->ublen++] = (char)bitmapByte; -+ } -+ } -+ -+ /* Update statistics. */ -+ -+ cl->rfbCursorShapeBytesSent += (pVNC->ublen - saved_ublen); -+ cl->rfbCursorShapeUpdatesSent++; -+ -+ return TRUE; -+} -+ -+/* -+ * Send cursor position (PointerPos pseudo-encoding). -+ */ -+Bool -+rfbSendCursorPos(rfbClientPtr cl, ScreenPtr pScreen) -+{ -+ VNCSCREENPTR(pScreen); -+ rfbFramebufferUpdateRectHeader rect; -+#if XFREE86VNC -+ ScreenPtr pCursorScreen = miPointerGetScreen(inputInfo.pointer); -+#endif -+ int x, y; -+ -+ if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+#if XFREE86VNC -+ if (pScreen == pCursorScreen) -+ miPointerGetPosition(inputInfo.pointer, &x, &y); -+#else -+ rfbSpriteGetCursorPos(pScreen, &x, &y); -+#endif -+ -+ rect.encoding = Swap32IfLE(rfbEncodingPointerPos); -+ rect.r.x = Swap16IfLE((CARD16)x); -+ rect.r.y = Swap16IfLE((CARD16)y); -+ rect.r.w = 0; -+ rect.r.h = 0; -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect, -+ sz_rfbFramebufferUpdateRectHeader); -+ pVNC->ublen += sz_rfbFramebufferUpdateRectHeader; -+ -+ cl->rfbCursorPosBytesSent += sz_rfbFramebufferUpdateRectHeader; -+ cl->rfbCursorPosUpdatesSent++; -+ -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ -+ cl->cursorX = x; -+ cl->cursorY = y; -+ -+ return TRUE; -+} -+ -+/* -+ * Code to convert cursor source bitmap to the desired pixel format. -+ */ -+ -+#define RGB48_TO_PIXEL(fmt,r,g,b) \ -+ (((CARD32)(r) * ((fmt)->redMax + 1) >> 16) << (fmt)->redShift | \ -+ ((CARD32)(g) * ((fmt)->greenMax + 1) >> 16) << (fmt)->greenShift | \ -+ ((CARD32)(b) * ((fmt)->blueMax + 1) >> 16) << (fmt)->blueShift) -+ -+static int -+EncodeRichCursorData8(unsigned char *buf, rfbPixelFormat *fmt, CursorPtr pCursor) -+{ -+ int widthPixels, widthBytes; -+ int x, y, b; -+ CARD8 *src; -+ char pix[2]; -+ CARD8 bitmapByte; -+ -+ pix[0] = (char)RGB48_TO_PIXEL(fmt, pCursor->backRed, pCursor->backGreen, -+ pCursor->backBlue); -+ pix[1] = (char)RGB48_TO_PIXEL(fmt, pCursor->foreRed, pCursor->foreGreen, -+ pCursor->foreBlue); -+ -+ src = (CARD8 *)pCursor->bits->source; -+ widthPixels = pCursor->bits->width; -+ widthBytes = PixmapBytePad(widthPixels, 1); -+ -+ for (y = 0; y < pCursor->bits->height; y++) { -+ for (x = 0; x < widthPixels / 8; x++) { -+ bitmapByte = src[y * widthBytes + x]; -+ if (screenInfo.bitmapBitOrder == LSBFirst) { -+ bitmapByte = _reverse_byte[bitmapByte]; -+ } -+ for (b = 7; b >= 0; b--) { -+ *buf++ = pix[bitmapByte >> b & 1]; -+ } -+ } -+ if (widthPixels % 8) { -+ bitmapByte = src[y * widthBytes + x]; -+ if (screenInfo.bitmapBitOrder == LSBFirst) { -+ bitmapByte = _reverse_byte[bitmapByte]; -+ } -+ for (b = 7; b > 7 - widthPixels % 8; b--) { -+ *buf++ = pix[bitmapByte >> b & 1]; -+ } -+ } -+ } -+ -+ return (widthPixels * pCursor->bits->height); -+} -+ -+#define DEFINE_RICH_ENCODE(bpp) \ -+ \ -+static int \ -+EncodeRichCursorData##bpp(ScreenPtr pScreen, unsigned char *buf, \ -+ rfbPixelFormat *fmt, CursorPtr pCursor) \ -+{ \ -+ VNCSCREENPTR(pScreen); \ -+ int widthPixels, widthBytes; \ -+ int x, y, b; \ -+ CARD8 *src; \ -+ CARD##bpp pix[2]; \ -+ CARD8 bitmapByte; \ -+ \ -+ pix[0] = (CARD##bpp)RGB48_TO_PIXEL(fmt, pCursor->backRed, \ -+ pCursor->backGreen, \ -+ pCursor->backBlue); \ -+ pix[1] = (CARD##bpp)RGB48_TO_PIXEL(fmt, pCursor->foreRed, \ -+ pCursor->foreGreen, \ -+ pCursor->foreBlue); \ -+ if (!pVNC->rfbServerFormat.bigEndian != !fmt->bigEndian) { \ -+ pix[0] = Swap##bpp(pix[0]); \ -+ pix[1] = Swap##bpp(pix[1]); \ -+ } \ -+ \ -+ src = (CARD8 *)pCursor->bits->source; \ -+ widthPixels = pCursor->bits->width; \ -+ widthBytes = PixmapBytePad(widthPixels, 1); \ -+ \ -+ for (y = 0; y < pCursor->bits->height; y++) { \ -+ for (x = 0; x < widthPixels / 8; x++) { \ -+ bitmapByte = src[y * widthBytes + x]; \ -+ if (screenInfo.bitmapBitOrder == LSBFirst) { \ -+ bitmapByte = _reverse_byte[bitmapByte]; \ -+ } \ -+ for (b = 7; b >= 0; b--) { \ -+ memcpy (buf, (char *)&pix[bitmapByte >> b & 1], \ -+ sizeof(CARD##bpp)); \ -+ buf += sizeof(CARD##bpp); \ -+ } \ -+ } \ -+ if (widthPixels % 8) { \ -+ bitmapByte = src[y * widthBytes + x]; \ -+ if (screenInfo.bitmapBitOrder == LSBFirst) { \ -+ bitmapByte = _reverse_byte[bitmapByte]; \ -+ } \ -+ for (b = 7; b > 7 - widthPixels % 8; b--) { \ -+ memcpy (buf, (char *)&pix[bitmapByte >> b & 1], \ -+ sizeof(CARD##bpp)); \ -+ buf += sizeof(CARD##bpp); \ -+ } \ -+ } \ -+ } \ -+ \ -+ return (widthPixels * pCursor->bits->height * (bpp / 8)); \ -+} -+ -+DEFINE_RICH_ENCODE(16) -+DEFINE_RICH_ENCODE(32) -+ -diff -pruN xorg-server-1.12.1.orig/hw/vnc/cutpaste.c xorg-server-1.12.1/hw/vnc/cutpaste.c ---- xorg-server-1.12.1.orig/hw/vnc/cutpaste.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/cutpaste.c 2012-04-18 14:45:21.572821004 -0500 -@@ -0,0 +1,86 @@ -+/* -+ * cutpaste.c - routines to deal with cut & paste buffers / selection. -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#include -+#define NEED_EVENTS -+#include -+#include -+#include "rfb.h" -+#include "selection.h" -+#include "input.h" -+#include -+ -+extern Selection *CurrentSelections; -+extern int NumCurrentSelections; -+ -+ -+static Bool inSetXCutText = FALSE; -+ -+/* -+ * rfbSetXCutText sets the cut buffer to be the given string. We also clear -+ * the primary selection. Ideally we'd like to set it to the same thing, but I -+ * can't work out how to do that without some kind of helper X client. -+ */ -+ -+void -+rfbSetXCutText(char *str, int len) -+{ -+ Selection *pSel; -+ -+ inSetXCutText = TRUE; -+ ChangeWindowProperty(screenInfo.screens[0]->root, XA_CUT_BUFFER0, XA_STRING, -+ 8, PropModeReplace, len, -+ (pointer)str, TRUE); -+ -+ if (dixLookupSelection(&pSel, XA_PRIMARY, serverClient, DixSetAttrAccess) == Success) { -+ xEvent event; -+ -+ if (pSel->client) { -+ event.u.u.type = SelectionClear; -+ event.u.selectionClear.time = GetTimeInMillis(); -+ event.u.selectionClear.window = pSel->window; -+ event.u.selectionClear.atom = pSel->selection; -+ (void) TryClientEvents (pSel->client, NULL, &event, 1, -+ NoEventMask, NoEventMask /* CantBeFiltered */, -+ NullGrab); -+ } -+ -+ pSel->window = None; -+ pSel->pWin = NULL; -+ pSel->client = NullClient; -+ } -+ -+ inSetXCutText = FALSE; -+} -+ -+ -+void rfbGotXCutText(char *str, int len) -+{ -+ if (!inSetXCutText) -+ rfbSendServerCutText(str, len); -+} -diff -pruN xorg-server-1.12.1.orig/hw/vnc/d3des.c xorg-server-1.12.1/hw/vnc/d3des.c ---- xorg-server-1.12.1.orig/hw/vnc/d3des.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/d3des.c 2012-04-18 14:45:21.573820992 -0500 -@@ -0,0 +1,428 @@ -+/* -+ * This is D3DES (V5.09) by Richard Outerbridge with the double and -+ * triple-length support removed for use in VNC. Also the bytebit[] array -+ * has been reversed so that the most significant bit in each byte of the -+ * key is ignored, not the least significant. -+ * -+ * These changes are: -+ * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. -+ * -+ * 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. -+ */ -+ -+/* D3DES (V5.09) - -+ * -+ * A portable, public domain, version of the Data Encryption Standard. -+ * -+ * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge. -+ * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation -+ * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis -+ * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau, -+ * for humouring me on. -+ * -+ * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. -+ * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#include "d3des.h" -+ -+static void scrunch(unsigned char *, unsigned long *); -+static void unscrun(unsigned long *, unsigned char *); -+static void desfunc(unsigned long *, unsigned long *); -+static void cookey(unsigned long *); -+ -+static unsigned long KnL[32] = { 0L }; -+ -+static unsigned short bytebit[8] = { -+ 01, 02, 04, 010, 020, 040, 0100, 0200 }; -+ -+static unsigned long bigbyte[24] = { -+ 0x800000L, 0x400000L, 0x200000L, 0x100000L, -+ 0x80000L, 0x40000L, 0x20000L, 0x10000L, -+ 0x8000L, 0x4000L, 0x2000L, 0x1000L, -+ 0x800L, 0x400L, 0x200L, 0x100L, -+ 0x80L, 0x40L, 0x20L, 0x10L, -+ 0x8L, 0x4L, 0x2L, 0x1L }; -+ -+/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */ -+ -+static unsigned char pc1[56] = { -+ 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, -+ 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, -+ 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, -+ 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; -+ -+static unsigned char totrot[16] = { -+ 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 }; -+ -+static unsigned char pc2[48] = { -+ 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, -+ 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, -+ 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, -+ 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; -+ -+void deskey(unsigned char *key, int edf) /* Thanks to James Gillogly & Phil Karn! */ -+{ -+ register int i, j, l, m, n; -+ unsigned char pc1m[56], pcr[56]; -+ unsigned long kn[32]; -+ -+ for ( j = 0; j < 56; j++ ) { -+ l = pc1[j]; -+ m = l & 07; -+ pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0; -+ } -+ for( i = 0; i < 16; i++ ) { -+ if( edf == DE1 ) m = (15 - i) << 1; -+ else m = i << 1; -+ n = m + 1; -+ kn[m] = kn[n] = 0L; -+ for( j = 0; j < 28; j++ ) { -+ l = j + totrot[i]; -+ if( l < 28 ) pcr[j] = pc1m[l]; -+ else pcr[j] = pc1m[l - 28]; -+ } -+ for( j = 28; j < 56; j++ ) { -+ l = j + totrot[i]; -+ if( l < 56 ) pcr[j] = pc1m[l]; -+ else pcr[j] = pc1m[l - 28]; -+ } -+ for( j = 0; j < 24; j++ ) { -+ if( pcr[pc2[j]] ) kn[m] |= bigbyte[j]; -+ if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j]; -+ } -+ } -+ cookey(kn); -+ return; -+ } -+ -+static void cookey(register unsigned long *raw1) -+{ -+ register unsigned long *cook, *raw0; -+ unsigned long dough[32]; -+ register int i; -+ -+ cook = dough; -+ for( i = 0; i < 16; i++, raw1++ ) { -+ raw0 = raw1++; -+ *cook = (*raw0 & 0x00fc0000L) << 6; -+ *cook |= (*raw0 & 0x00000fc0L) << 10; -+ *cook |= (*raw1 & 0x00fc0000L) >> 10; -+ *cook++ |= (*raw1 & 0x00000fc0L) >> 6; -+ *cook = (*raw0 & 0x0003f000L) << 12; -+ *cook |= (*raw0 & 0x0000003fL) << 16; -+ *cook |= (*raw1 & 0x0003f000L) >> 4; -+ *cook++ |= (*raw1 & 0x0000003fL); -+ } -+ usekey(dough); -+ return; -+ } -+ -+void cpkey(register unsigned long *into) -+{ -+ register unsigned long *from, *endp; -+ -+ from = KnL, endp = &KnL[32]; -+ while( from < endp ) *into++ = *from++; -+ return; -+ } -+ -+void usekey(register unsigned long *from) -+{ -+ register unsigned long *to, *endp; -+ -+ to = KnL, endp = &KnL[32]; -+ while( to < endp ) *to++ = *from++; -+ return; -+ } -+ -+void des(unsigned char *inblock, unsigned char *outblock) -+{ -+ unsigned long work[2]; -+ -+ scrunch(inblock, work); -+ desfunc(work, KnL); -+ unscrun(work, outblock); -+ return; -+ } -+ -+static void scrunch(register unsigned char *outof, -+ register unsigned long *into) -+{ -+ *into = (*outof++ & 0xffL) << 24; -+ *into |= (*outof++ & 0xffL) << 16; -+ *into |= (*outof++ & 0xffL) << 8; -+ *into++ |= (*outof++ & 0xffL); -+ *into = (*outof++ & 0xffL) << 24; -+ *into |= (*outof++ & 0xffL) << 16; -+ *into |= (*outof++ & 0xffL) << 8; -+ *into |= (*outof & 0xffL); -+ return; -+ } -+ -+static void unscrun(register unsigned long *outof, -+ register unsigned char *into) -+{ -+ *into++ = (*outof >> 24) & 0xffL; -+ *into++ = (*outof >> 16) & 0xffL; -+ *into++ = (*outof >> 8) & 0xffL; -+ *into++ = *outof++ & 0xffL; -+ *into++ = (*outof >> 24) & 0xffL; -+ *into++ = (*outof >> 16) & 0xffL; -+ *into++ = (*outof >> 8) & 0xffL; -+ *into = *outof & 0xffL; -+ return; -+ } -+ -+static unsigned long SP1[64] = { -+ 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, -+ 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, -+ 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, -+ 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, -+ 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, -+ 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, -+ 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, -+ 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, -+ 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, -+ 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, -+ 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, -+ 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, -+ 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, -+ 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, -+ 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, -+ 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; -+ -+static unsigned long SP2[64] = { -+ 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, -+ 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, -+ 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, -+ 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, -+ 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, -+ 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, -+ 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, -+ 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, -+ 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, -+ 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, -+ 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, -+ 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, -+ 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, -+ 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, -+ 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, -+ 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; -+ -+static unsigned long SP3[64] = { -+ 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, -+ 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, -+ 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, -+ 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, -+ 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, -+ 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, -+ 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, -+ 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, -+ 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, -+ 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, -+ 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, -+ 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, -+ 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, -+ 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, -+ 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, -+ 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; -+ -+static unsigned long SP4[64] = { -+ 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, -+ 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, -+ 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, -+ 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, -+ 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, -+ 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, -+ 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, -+ 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, -+ 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, -+ 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, -+ 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, -+ 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, -+ 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, -+ 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, -+ 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, -+ 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; -+ -+static unsigned long SP5[64] = { -+ 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, -+ 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, -+ 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, -+ 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, -+ 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, -+ 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, -+ 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, -+ 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, -+ 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, -+ 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, -+ 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, -+ 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, -+ 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, -+ 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, -+ 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, -+ 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; -+ -+static unsigned long SP6[64] = { -+ 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, -+ 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, -+ 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, -+ 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, -+ 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, -+ 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, -+ 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, -+ 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, -+ 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, -+ 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, -+ 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, -+ 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, -+ 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, -+ 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, -+ 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, -+ 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; -+ -+static unsigned long SP7[64] = { -+ 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, -+ 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, -+ 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, -+ 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, -+ 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, -+ 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, -+ 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, -+ 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, -+ 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, -+ 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, -+ 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, -+ 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, -+ 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, -+ 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, -+ 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, -+ 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; -+ -+static unsigned long SP8[64] = { -+ 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, -+ 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, -+ 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, -+ 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, -+ 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, -+ 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, -+ 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, -+ 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, -+ 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, -+ 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, -+ 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, -+ 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, -+ 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, -+ 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, -+ 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, -+ 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; -+ -+static void desfunc(register unsigned long *block, register unsigned long *keys) -+{ -+ register unsigned long fval, work, right, leftt; -+ register int round; -+ -+ leftt = block[0]; -+ right = block[1]; -+ work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; -+ right ^= work; -+ leftt ^= (work << 4); -+ work = ((leftt >> 16) ^ right) & 0x0000ffffL; -+ right ^= work; -+ leftt ^= (work << 16); -+ work = ((right >> 2) ^ leftt) & 0x33333333L; -+ leftt ^= work; -+ right ^= (work << 2); -+ work = ((right >> 8) ^ leftt) & 0x00ff00ffL; -+ leftt ^= work; -+ right ^= (work << 8); -+ right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL; -+ work = (leftt ^ right) & 0xaaaaaaaaL; -+ leftt ^= work; -+ right ^= work; -+ leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL; -+ -+ for( round = 0; round < 8; round++ ) { -+ work = (right << 28) | (right >> 4); -+ work ^= *keys++; -+ fval = SP7[ work & 0x3fL]; -+ fval |= SP5[(work >> 8) & 0x3fL]; -+ fval |= SP3[(work >> 16) & 0x3fL]; -+ fval |= SP1[(work >> 24) & 0x3fL]; -+ work = right ^ *keys++; -+ fval |= SP8[ work & 0x3fL]; -+ fval |= SP6[(work >> 8) & 0x3fL]; -+ fval |= SP4[(work >> 16) & 0x3fL]; -+ fval |= SP2[(work >> 24) & 0x3fL]; -+ leftt ^= fval; -+ work = (leftt << 28) | (leftt >> 4); -+ work ^= *keys++; -+ fval = SP7[ work & 0x3fL]; -+ fval |= SP5[(work >> 8) & 0x3fL]; -+ fval |= SP3[(work >> 16) & 0x3fL]; -+ fval |= SP1[(work >> 24) & 0x3fL]; -+ work = leftt ^ *keys++; -+ fval |= SP8[ work & 0x3fL]; -+ fval |= SP6[(work >> 8) & 0x3fL]; -+ fval |= SP4[(work >> 16) & 0x3fL]; -+ fval |= SP2[(work >> 24) & 0x3fL]; -+ right ^= fval; -+ } -+ -+ right = (right << 31) | (right >> 1); -+ work = (leftt ^ right) & 0xaaaaaaaaL; -+ leftt ^= work; -+ right ^= work; -+ leftt = (leftt << 31) | (leftt >> 1); -+ work = ((leftt >> 8) ^ right) & 0x00ff00ffL; -+ right ^= work; -+ leftt ^= (work << 8); -+ work = ((leftt >> 2) ^ right) & 0x33333333L; -+ right ^= work; -+ leftt ^= (work << 2); -+ work = ((right >> 16) ^ leftt) & 0x0000ffffL; -+ leftt ^= work; -+ right ^= (work << 16); -+ work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; -+ leftt ^= work; -+ right ^= (work << 4); -+ *block++ = right; -+ *block = leftt; -+ return; -+ } -+ -+/* Validation sets: -+ * -+ * Single-length key, single-length plaintext - -+ * Key : 0123 4567 89ab cdef -+ * Plain : 0123 4567 89ab cde7 -+ * Cipher : c957 4425 6a5e d31d -+ * -+ * Double-length key, single-length plaintext - -+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 -+ * Plain : 0123 4567 89ab cde7 -+ * Cipher : 7f1d 0a77 826b 8aff -+ * -+ * Double-length key, double-length plaintext - -+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 -+ * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff -+ * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7 -+ * -+ * Triple-length key, single-length plaintext - -+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 -+ * Plain : 0123 4567 89ab cde7 -+ * Cipher : de0b 7c06 ae5e 0ed5 -+ * -+ * Triple-length key, double-length plaintext - -+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 -+ * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff -+ * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5 -+ * -+ * d3des V5.0a rwo 9208.07 18:44 Graven Imagery -+ **********************************************************************/ -diff -pruN xorg-server-1.12.1.orig/hw/vnc/d3des.h xorg-server-1.12.1/hw/vnc/d3des.h ---- xorg-server-1.12.1.orig/hw/vnc/d3des.h 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/d3des.h 2012-04-18 14:45:21.573820992 -0500 -@@ -0,0 +1,51 @@ -+/* -+ * This is D3DES (V5.09) by Richard Outerbridge with the double and -+ * triple-length support removed for use in VNC. -+ * -+ * These changes are: -+ * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. -+ * -+ * 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. -+ */ -+ -+/* d3des.h - -+ * -+ * Headers and defines for d3des.c -+ * Graven Imagery, 1992. -+ * -+ * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge -+ * (GEnie : OUTER; CIS : [71755,204]) -+ */ -+ -+#define EN0 0 /* MODE == encrypt */ -+#define DE1 1 /* MODE == decrypt */ -+ -+extern void deskey(unsigned char *, int); -+/* hexkey[8] MODE -+ * Sets the internal key register according to the hexadecimal -+ * key contained in the 8 bytes of hexkey, according to the DES, -+ * for encryption or decryption according to MODE. -+ */ -+ -+extern void usekey(unsigned long *); -+/* cookedkey[32] -+ * Loads the internal key register with the data in cookedkey. -+ */ -+ -+extern void cpkey(unsigned long *); -+/* cookedkey[32] -+ * Copies the contents of the internal key register into the storage -+ * located at &cookedkey[0]. -+ */ -+ -+extern void des(unsigned char *, unsigned char *); -+/* from[8] to[8] -+ * Encrypts/Decrypts (according to the key currently loaded in the -+ * internal key register) one block of eight bytes at address 'from' -+ * into the block at address 'to'. They can be the same. -+ */ -+ -+/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery -+ ********************************************************************/ -diff -pruN xorg-server-1.12.1.orig/hw/vnc/dispcur.c xorg-server-1.12.1/hw/vnc/dispcur.c ---- xorg-server-1.12.1.orig/hw/vnc/dispcur.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/dispcur.c 2012-04-18 14:45:21.573820992 -0500 -@@ -0,0 +1,784 @@ -+/* -+ * dispcur.c -+ * -+ * cursor display routines - based on midispcur.c -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+ -+/* -+ -+Copyright (c) 1989 X Consortium -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+Except as contained in this notice, the name of the X Consortium shall not be -+used in advertising or otherwise to promote the sale, use or other dealings -+in this Software without prior written authorization from the X Consortium. -+*/ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#define NEED_EVENTS -+# include -+# include "rfb.h" -+# include "misc.h" -+# include "input.h" -+# include "cursorstr.h" -+# include "windowstr.h" -+# include "regionstr.h" -+# include "dixstruct.h" -+# include "scrnintstr.h" -+# include "servermd.h" -+# include "sprite.h" -+# include "gcstruct.h" -+ -+#ifdef ARGB_CURSOR -+# include "picturestr.h" -+#endif -+ -+/* per-screen private data */ -+ -+static DevPrivateKeyRec rfbDCScreenKeyRec; -+#define rfbDCScreenKey (&rfbDCScreenKeyRec) -+static DevPrivateKeyRec rfbScreenKeyRec; -+#define rfbScreenKey (&rfbScreenKeyRec) -+ -+static Bool rfbDCCloseScreen(int index, ScreenPtr pScreen); -+ -+typedef struct { -+ GCPtr pSourceGC, pMaskGC; -+ GCPtr pSaveGC, pRestoreGC; -+ GCPtr pMoveGC; -+ GCPtr pPixSourceGC, pPixMaskGC; -+ CloseScreenProcPtr CloseScreen; -+ PixmapPtr pSave, pTemp; -+#ifdef ARGB_CURSOR -+ PicturePtr pRootPicture; -+ PicturePtr pTempPicture; -+#endif -+} rfbDCScreenRec, *rfbDCScreenPtr; -+ -+/* per-cursor per-screen private data */ -+typedef struct { -+ PixmapPtr sourceBits; /* source bits */ -+ PixmapPtr maskBits; /* mask bits */ -+#ifdef ARGB_CURSOR -+ PicturePtr pPicture; -+#endif -+} rfbDCCursorRec, *rfbDCCursorPtr; -+ -+/* -+ * sprite/cursor method table -+ */ -+ -+static Bool rfbDCRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor); -+static Bool rfbDCUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor); -+static Bool rfbDCPutUpCursor(ScreenPtr pScreen, CursorPtr pCursor, -+ int x, int y, unsigned long source, -+ unsigned long mask); -+static Bool rfbDCSaveUnderCursor(ScreenPtr pScreen, int x, int y, -+ int w, int h); -+static Bool rfbDCRestoreUnderCursor(ScreenPtr pScreen, int x, int y, -+ int w, int h); -+static Bool rfbDCMoveCursor(ScreenPtr pScreen, CursorPtr pCursor, -+ int x, int y, int w, int h, int dx, int dy, -+ unsigned long source, unsigned long mask); -+static Bool rfbDCChangeSave(ScreenPtr pScreen, int x, int y, int w, int h, -+ int dx, int dy); -+ -+static rfbSpriteCursorFuncRec rfbDCFuncs = { -+ rfbDCRealizeCursor, -+ rfbDCUnrealizeCursor, -+ rfbDCPutUpCursor, -+ rfbDCSaveUnderCursor, -+ rfbDCRestoreUnderCursor, -+ rfbDCMoveCursor, -+ rfbDCChangeSave, -+}; -+ -+Bool -+rfbDCInitialize (ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs) -+{ -+ rfbDCScreenPtr pScreenPriv; -+ -+ if (!dixRegisterPrivateKey(rfbDCScreenKey, PRIVATE_SCREEN, 0)) -+ return FALSE; -+ -+ if (!dixRegisterPrivateKey(rfbScreenKey, PRIVATE_CURSOR_BITS, 0)) -+ return FALSE; -+ -+ pScreenPriv = (rfbDCScreenPtr) malloc (sizeof (rfbDCScreenRec)); -+ if (!pScreenPriv) -+ return FALSE; -+ -+ /* -+ * initialize the entire private structure to zeros -+ */ -+ -+ pScreenPriv->pSourceGC = -+ pScreenPriv->pMaskGC = -+ pScreenPriv->pSaveGC = -+ pScreenPriv->pRestoreGC = -+ pScreenPriv->pMoveGC = -+ pScreenPriv->pPixSourceGC = -+ pScreenPriv->pPixMaskGC = NULL; -+#ifdef ARGB_CURSOR -+ pScreenPriv->pRootPicture = NULL; -+ pScreenPriv->pTempPicture = NULL; -+#endif -+ -+ pScreenPriv->pSave = pScreenPriv->pTemp = NULL; -+ -+ pScreenPriv->CloseScreen = pScreen->CloseScreen; -+ pScreen->CloseScreen = rfbDCCloseScreen; -+ -+ dixSetPrivate(&pScreen->devPrivates, rfbDCScreenKey, pScreenPriv); -+ -+ if (!rfbSpriteInitialize (pScreen, &rfbDCFuncs, screenFuncs)) -+ { -+ free ((pointer) pScreenPriv); -+ return FALSE; -+ } -+ return TRUE; -+} -+ -+#define tossGC(gc) (gc ? FreeGC (gc, (GContext) 0) : 0) -+#define tossPix(pix) (pix ? (*pScreen->DestroyPixmap) (pix) : TRUE) -+#define tossPict(pict) (pict ? FreePicture (pict, 0) : 0) -+ -+static Bool -+rfbDCCloseScreen (int index, ScreenPtr pScreen) -+{ -+ rfbDCScreenPtr pScreenPriv; -+ -+ pScreenPriv = (rfbDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbDCScreenKey); -+ pScreen->CloseScreen = pScreenPriv->CloseScreen; -+ tossGC (pScreenPriv->pSourceGC); -+ tossGC (pScreenPriv->pMaskGC); -+ tossGC (pScreenPriv->pSaveGC); -+ tossGC (pScreenPriv->pRestoreGC); -+ tossGC (pScreenPriv->pMoveGC); -+ tossGC (pScreenPriv->pPixSourceGC); -+ tossGC (pScreenPriv->pPixMaskGC); -+ tossPix (pScreenPriv->pSave); -+ tossPix (pScreenPriv->pTemp); -+#ifdef ARGB_CURSOR -+ tossPict (pScreenPriv->pRootPicture); -+ tossPict (pScreenPriv->pTempPicture); -+#endif -+ free ((pointer) pScreenPriv); -+ return (*pScreen->CloseScreen) (pScreen); -+} -+ -+static Bool -+rfbDCRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) -+{ -+ if (pCursor->bits->refcnt <= 1) -+ dixSetPrivate(&pCursor->bits->devPrivates, rfbScreenKey, NULL); -+ return TRUE; -+} -+ -+#ifdef ARGB_CURSOR -+#define EnsurePicture(picture,draw,win) (picture || rfbDCMakePicture(&picture,draw,win)) -+ -+static VisualPtr -+rfbDCGetWindowVisual (WindowPtr pWin) -+{ -+ ScreenPtr pScreen = pWin->drawable.pScreen; -+ VisualID vid = wVisual (pWin); -+ int i; -+ -+ for (i = 0; i < pScreen->numVisuals; i++) -+ if (pScreen->visuals[i].vid == vid) -+ return &pScreen->visuals[i]; -+ return 0; -+} -+ -+static PicturePtr -+rfbDCMakePicture (PicturePtr *ppPicture, DrawablePtr pDraw, WindowPtr pWin) -+{ -+ ScreenPtr pScreen = pDraw->pScreen; -+ VisualPtr pVisual; -+ PictFormatPtr pFormat; -+ XID subwindow_mode = IncludeInferiors; -+ PicturePtr pPicture; -+ int error; -+ -+ pVisual = rfbDCGetWindowVisual (pWin); -+ if (!pVisual) -+ return 0; -+ pFormat = PictureMatchVisual (pScreen, pDraw->depth, pVisual); -+ if (!pFormat) -+ return 0; -+ pPicture = CreatePicture (0, pDraw, pFormat, -+ CPSubwindowMode, &subwindow_mode, -+ serverClient, &error); -+ *ppPicture = pPicture; -+ return pPicture; -+} -+#endif -+ -+static rfbDCCursorPtr -+rfbDCRealize (ScreenPtr pScreen, CursorPtr pCursor) -+{ -+ rfbDCCursorPtr pPriv; -+ GCPtr pGC; -+ XID gcvals[3]; -+ -+ pPriv = (rfbDCCursorPtr) malloc (sizeof (rfbDCCursorRec)); -+ if (!pPriv) -+ return (rfbDCCursorPtr)NULL; -+#ifdef ARGB_CURSOR -+ if (pCursor->bits->argb) -+ { -+ PixmapPtr pPixmap; -+ PictFormatPtr pFormat; -+ int error; -+ -+ pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8); -+ if (!pFormat) -+ { -+ free ((pointer) pPriv); -+ return (rfbDCCursorPtr)NULL; -+ } -+ -+ pPriv->sourceBits = 0; -+ pPriv->maskBits = 0; -+ pPixmap = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, -+ pCursor->bits->height, 32, 0); -+ if (!pPixmap) -+ { -+ free ((pointer) pPriv); -+ return (rfbDCCursorPtr)NULL; -+ } -+ pGC = GetScratchGC (32, pScreen); -+ if (!pGC) -+ { -+ (*pScreen->DestroyPixmap) (pPixmap); -+ free ((pointer) pPriv); -+ return (rfbDCCursorPtr)NULL; -+ } -+ ValidateGC (&pPixmap->drawable, pGC); -+ (*pGC->ops->PutImage) (&pPixmap->drawable, pGC, 32, -+ 0, 0, pCursor->bits->width, -+ pCursor->bits->height, -+ 0, ZPixmap, (char *) pCursor->bits->argb); -+ FreeScratchGC (pGC); -+ pPriv->pPicture = CreatePicture (0, &pPixmap->drawable, -+ pFormat, 0, 0, serverClient, &error); -+ (*pScreen->DestroyPixmap) (pPixmap); -+ if (!pPriv->pPicture) -+ { -+ free ((pointer) pPriv); -+ return (rfbDCCursorPtr)NULL; -+ } -+ dixSetPrivate(&pCursor->bits->devPrivates, rfbScreenKey, pPriv); -+ return pPriv; -+ } -+ pPriv->pPicture = 0; -+#endif -+ pPriv->sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1, 0); -+ if (!pPriv->sourceBits) -+ { -+ free ((pointer) pPriv); -+ return (rfbDCCursorPtr)NULL; -+ } -+ pPriv->maskBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1, 0); -+ if (!pPriv->maskBits) -+ { -+ (*pScreen->DestroyPixmap) (pPriv->sourceBits); -+ free ((pointer) pPriv); -+ return (rfbDCCursorPtr)NULL; -+ } -+ dixSetPrivate(&pCursor->bits->devPrivates, rfbScreenKey, pPriv); -+ -+ /* create the two sets of bits, clipping as appropriate */ -+ -+ pGC = GetScratchGC (1, pScreen); -+ if (!pGC) -+ { -+ (void) rfbDCUnrealizeCursor (pScreen, pCursor); -+ return (rfbDCCursorPtr)NULL; -+ } -+ -+ ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC); -+ (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1, -+ 0, 0, pCursor->bits->width, pCursor->bits->height, -+ 0, XYPixmap, (char *)pCursor->bits->source); -+ gcvals[0] = GXand; -+ ChangeGCXIDs (NullClient, pGC, GCFunction, gcvals); -+ ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC); -+ (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1, -+ 0, 0, pCursor->bits->width, pCursor->bits->height, -+ 0, XYPixmap, (char *)pCursor->bits->mask); -+ -+ /* mask bits -- pCursor->mask & ~pCursor->source */ -+ gcvals[0] = GXcopy; -+ ChangeGCXIDs (NullClient, pGC, GCFunction, gcvals); -+ ValidateGC ((DrawablePtr)pPriv->maskBits, pGC); -+ (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1, -+ 0, 0, pCursor->bits->width, pCursor->bits->height, -+ 0, XYPixmap, (char *)pCursor->bits->mask); -+ gcvals[0] = GXandInverted; -+ ChangeGCXIDs (NullClient, pGC, GCFunction, gcvals); -+ ValidateGC ((DrawablePtr)pPriv->maskBits, pGC); -+ (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1, -+ 0, 0, pCursor->bits->width, pCursor->bits->height, -+ 0, XYPixmap, (char *)pCursor->bits->source); -+ FreeScratchGC (pGC); -+ return pPriv; -+} -+ -+static Bool -+rfbDCUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) -+{ -+ rfbDCCursorPtr pPriv; -+ -+ pPriv = (rfbDCCursorPtr)dixLookupPrivate(&pCursor->bits->devPrivates, -+ rfbScreenKey); -+ if (pPriv && (pCursor->bits->refcnt <= 1)) -+ { -+ if (pPriv->sourceBits) -+ (*pScreen->DestroyPixmap) (pPriv->sourceBits); -+ if (pPriv->maskBits) -+ (*pScreen->DestroyPixmap) (pPriv->maskBits); -+#ifdef ARGB_CURSOR -+ if (pPriv->pPicture) -+ FreePicture (pPriv->pPicture, 0); -+#endif -+ free ((pointer) pPriv); -+ dixSetPrivate(&pCursor->bits->devPrivates, rfbScreenKey, NULL); -+ } -+ return TRUE; -+} -+ -+static void -+rfbDCPutBits (DrawablePtr pDrawable, rfbDCCursorPtr pPriv, GCPtr sourceGC, GCPtr maskGC, int x, int y, unsigned w, unsigned h, unsigned long source, unsigned long mask) -+{ -+ XID gcvals[1]; -+ -+ if (sourceGC->fgPixel != source) -+ { -+ gcvals[0] = source; -+ ChangeGCXIDs (NullClient, sourceGC, GCForeground, gcvals); -+ } -+ if (sourceGC->serialNumber != pDrawable->serialNumber) -+ ValidateGC (pDrawable, sourceGC); -+ (*sourceGC->ops->PushPixels) (sourceGC, pPriv->sourceBits, pDrawable, w, h, x, y); -+ if (maskGC->fgPixel != mask) -+ { -+ gcvals[0] = mask; -+ ChangeGCXIDs (NullClient, maskGC, GCForeground, gcvals); -+ } -+ if (maskGC->serialNumber != pDrawable->serialNumber) -+ ValidateGC (pDrawable, maskGC); -+ (*maskGC->ops->PushPixels) (maskGC, pPriv->maskBits, pDrawable, w, h, x, y); -+} -+ -+#define EnsureGC(gc,win) (gc || rfbDCMakeGC(&gc, win)) -+ -+static GCPtr -+rfbDCMakeGC(GCPtr *ppGC, WindowPtr pWin) -+{ -+ GCPtr pGC; -+ int status; -+ XID gcvals[2]; -+ -+ gcvals[0] = IncludeInferiors; -+ gcvals[1] = FALSE; -+ pGC = CreateGC((DrawablePtr)pWin, -+ GCSubwindowMode|GCGraphicsExposures, gcvals, &status, (XID)0, serverClient); -+ *ppGC = pGC; -+ return pGC; -+} -+ -+static Bool -+rfbDCPutUpCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y, unsigned long source, -+ unsigned long mask) -+{ -+ rfbDCScreenPtr pScreenPriv; -+ rfbDCCursorPtr pPriv; -+ WindowPtr pWin; -+ -+ pPriv = (rfbDCCursorPtr)dixLookupPrivate(&pCursor->bits->devPrivates, -+ rfbScreenKey); -+ if (!pPriv) -+ { -+ pPriv = rfbDCRealize(pScreen, pCursor); -+ if (!pPriv) -+ return FALSE; -+ } -+ pScreenPriv = (rfbDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbDCScreenKey); -+ pWin = pScreen->root; -+#ifdef ARGB_CURSOR -+ if (pPriv->pPicture) -+ { -+ if (!EnsurePicture(pScreenPriv->pRootPicture, &pWin->drawable, pWin)) -+ return FALSE; -+ CompositePicture (PictOpOver, -+ pPriv->pPicture, -+ NULL, -+ pScreenPriv->pRootPicture, -+ 0, 0, 0, 0, -+ x, y, -+ pCursor->bits->width, -+ pCursor->bits->height); -+ } -+ else -+#endif -+ { -+ if (!EnsureGC(pScreenPriv->pSourceGC, pWin)) -+ return FALSE; -+ if (!EnsureGC(pScreenPriv->pMaskGC, pWin)) -+ { -+ FreeGC (pScreenPriv->pSourceGC, (GContext) 0); -+ pScreenPriv->pSourceGC = 0; -+ return FALSE; -+ } -+ rfbDCPutBits ((DrawablePtr)pWin, pPriv, -+ pScreenPriv->pSourceGC, pScreenPriv->pMaskGC, -+ x, y, pCursor->bits->width, pCursor->bits->height, -+ source, mask); -+ } -+ return TRUE; -+} -+ -+static Bool -+rfbDCSaveUnderCursor (ScreenPtr pScreen, int x, int y, int w, int h) -+{ -+ rfbDCScreenPtr pScreenPriv; -+ PixmapPtr pSave; -+ WindowPtr pWin; -+ GCPtr pGC; -+ -+ pScreenPriv = (rfbDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbDCScreenKey); -+ pSave = pScreenPriv->pSave; -+ pWin = pScreen->root; -+ if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h) -+ { -+ if (pSave) -+ (*pScreen->DestroyPixmap) (pSave); -+ pScreenPriv->pSave = pSave = -+ (*pScreen->CreatePixmap) (pScreen, w, h, pScreen->rootDepth, 0); -+ if (!pSave) -+ return FALSE; -+ } -+ if (!EnsureGC(pScreenPriv->pSaveGC, pWin)) -+ return FALSE; -+ pGC = pScreenPriv->pSaveGC; -+ if (pSave->drawable.serialNumber != pGC->serialNumber) -+ ValidateGC ((DrawablePtr) pSave, pGC); -+ (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC, -+ x, y, w, h, 0, 0); -+ return TRUE; -+} -+ -+static Bool -+rfbDCRestoreUnderCursor (ScreenPtr pScreen, int x, int y, int w, int h) -+{ -+ rfbDCScreenPtr pScreenPriv; -+ PixmapPtr pSave; -+ WindowPtr pWin; -+ GCPtr pGC; -+ -+ pScreenPriv = (rfbDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbDCScreenKey); -+ pSave = pScreenPriv->pSave; -+ pWin = pScreen->root; -+ if (!pSave) -+ return FALSE; -+ if (!EnsureGC(pScreenPriv->pRestoreGC, pWin)) -+ return FALSE; -+ pGC = pScreenPriv->pRestoreGC; -+ if (pWin->drawable.serialNumber != pGC->serialNumber) -+ ValidateGC ((DrawablePtr) pWin, pGC); -+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC, -+ 0, 0, w, h, x, y); -+ return TRUE; -+} -+ -+static Bool -+rfbDCChangeSave (ScreenPtr pScreen, -+ int x, int y, int w, int h, int dx, int dy) -+{ -+ rfbDCScreenPtr pScreenPriv; -+ PixmapPtr pSave; -+ WindowPtr pWin; -+ GCPtr pGC; -+ int sourcex, sourcey, destx, desty, copyw, copyh; -+ -+ pScreenPriv = (rfbDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbDCScreenKey); -+ pSave = pScreenPriv->pSave; -+ pWin = pScreen->root; -+ /* -+ * restore the bits which are about to get trashed -+ */ -+ if (!pSave) -+ return FALSE; -+ if (!EnsureGC(pScreenPriv->pRestoreGC, pWin)) -+ return FALSE; -+ pGC = pScreenPriv->pRestoreGC; -+ if (pWin->drawable.serialNumber != pGC->serialNumber) -+ ValidateGC ((DrawablePtr) pWin, pGC); -+ /* -+ * copy the old bits to the screen. -+ */ -+ if (dy > 0) -+ { -+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC, -+ 0, h - dy, w, dy, x + dx, y + h); -+ } -+ else if (dy < 0) -+ { -+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC, -+ 0, 0, w, -dy, x + dx, y + dy); -+ } -+ if (dy >= 0) -+ { -+ desty = y + dy; -+ sourcey = 0; -+ copyh = h - dy; -+ } -+ else -+ { -+ desty = y; -+ sourcey = - dy; -+ copyh = h + dy; -+ } -+ if (dx > 0) -+ { -+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC, -+ w - dx, sourcey, dx, copyh, x + w, desty); -+ } -+ else if (dx < 0) -+ { -+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC, -+ 0, sourcey, -dx, copyh, x + dx, desty); -+ } -+ if (!EnsureGC(pScreenPriv->pSaveGC, pWin)) -+ return FALSE; -+ pGC = pScreenPriv->pSaveGC; -+ if (pSave->drawable.serialNumber != pGC->serialNumber) -+ ValidateGC ((DrawablePtr) pSave, pGC); -+ /* -+ * move the bits that are still valid within the pixmap -+ */ -+ if (dx >= 0) -+ { -+ sourcex = 0; -+ destx = dx; -+ copyw = w - dx; -+ } -+ else -+ { -+ destx = 0; -+ sourcex = - dx; -+ copyw = w + dx; -+ } -+ if (dy >= 0) -+ { -+ sourcey = 0; -+ desty = dy; -+ copyh = h - dy; -+ } -+ else -+ { -+ desty = 0; -+ sourcey = -dy; -+ copyh = h + dy; -+ } -+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pSave, pGC, -+ sourcex, sourcey, copyw, copyh, destx, desty); -+ /* -+ * copy the new bits from the screen into the remaining areas of the -+ * pixmap -+ */ -+ if (dy > 0) -+ { -+ (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC, -+ x, y, w, dy, 0, 0); -+ } -+ else if (dy < 0) -+ { -+ (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC, -+ x, y + h + dy, w, -dy, 0, h + dy); -+ } -+ if (dy >= 0) -+ { -+ desty = dy; -+ sourcey = y + dy; -+ copyh = h - dy; -+ } -+ else -+ { -+ desty = 0; -+ sourcey = y; -+ copyh = h + dy; -+ } -+ if (dx > 0) -+ { -+ (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC, -+ x, sourcey, dx, copyh, 0, desty); -+ } -+ else if (dx < 0) -+ { -+ (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC, -+ x + w + dx, sourcey, -dx, copyh, w + dx, desty); -+ } -+ return TRUE; -+} -+ -+static Bool -+rfbDCMoveCursor (ScreenPtr pScreen, CursorPtr pCursor, -+ int x, int y, int w, int h, int dx, int dy, -+ unsigned long source, unsigned long mask) -+{ -+ rfbDCCursorPtr pPriv; -+ rfbDCScreenPtr pScreenPriv; -+ int status; -+ WindowPtr pWin; -+ GCPtr pGC; -+ XID gcval = FALSE; -+ PixmapPtr pTemp; -+ -+ pPriv = (rfbDCCursorPtr)dixLookupPrivate(&pCursor->bits->devPrivates, -+ rfbScreenKey); -+ if (!pPriv) -+ { -+ pPriv = rfbDCRealize(pScreen, pCursor); -+ if (!pPriv) -+ return FALSE; -+ } -+ pScreenPriv = (rfbDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbDCScreenKey); -+ pWin = pScreen->root; -+ pTemp = pScreenPriv->pTemp; -+ if (!pTemp || -+ pTemp->drawable.width != pScreenPriv->pSave->drawable.width || -+ pTemp->drawable.height != pScreenPriv->pSave->drawable.height) -+ { -+ if (pTemp) -+ (*pScreen->DestroyPixmap) (pTemp); -+#ifdef ARGB_CURSOR -+ if (pScreenPriv->pTempPicture) -+ { -+ FreePicture (pScreenPriv->pTempPicture, 0); -+ pScreenPriv->pTempPicture = 0; -+ } -+#endif -+ pScreenPriv->pTemp = pTemp = (*pScreen->CreatePixmap) -+ (pScreen, w, h, pScreenPriv->pSave->drawable.depth, 0); -+ if (!pTemp) -+ return FALSE; -+ } -+ if (!pScreenPriv->pMoveGC) -+ { -+ pScreenPriv->pMoveGC = CreateGC ((DrawablePtr)pTemp, -+ GCGraphicsExposures, &gcval, &status, (XID)0, serverClient); -+ if (!pScreenPriv->pMoveGC) -+ return FALSE; -+ } -+ /* -+ * copy the saved area to a temporary pixmap -+ */ -+ pGC = pScreenPriv->pMoveGC; -+ if (pGC->serialNumber != pTemp->drawable.serialNumber) -+ ValidateGC ((DrawablePtr) pTemp, pGC); -+ (*pGC->ops->CopyArea)((DrawablePtr)pScreenPriv->pSave, -+ (DrawablePtr)pTemp, pGC, 0, 0, w, h, 0, 0); -+ -+ /* -+ * draw the cursor in the temporary pixmap -+ */ -+#ifdef ARGB_CURSOR -+ if (pPriv->pPicture) -+ { -+ if (!EnsurePicture(pScreenPriv->pTempPicture, &pTemp->drawable, pWin)) -+ return FALSE; -+ CompositePicture (PictOpOver, -+ pPriv->pPicture, -+ NULL, -+ pScreenPriv->pTempPicture, -+ 0, 0, 0, 0, -+ dx, dy, -+ pCursor->bits->width, -+ pCursor->bits->height); -+ } -+ else -+#endif -+ { -+ if (!pScreenPriv->pPixSourceGC) -+ { -+ pScreenPriv->pPixSourceGC = CreateGC ((DrawablePtr)pTemp, -+ GCGraphicsExposures, &gcval, &status, (XID)0, serverClient); -+ if (!pScreenPriv->pPixSourceGC) -+ return FALSE; -+ } -+ if (!pScreenPriv->pPixMaskGC) -+ { -+ pScreenPriv->pPixMaskGC = CreateGC ((DrawablePtr)pTemp, -+ GCGraphicsExposures, &gcval, &status, (XID)0, serverClient); -+ if (!pScreenPriv->pPixMaskGC) -+ return FALSE; -+ } -+ rfbDCPutBits ((DrawablePtr)pTemp, pPriv, -+ pScreenPriv->pPixSourceGC, pScreenPriv->pPixMaskGC, -+ dx, dy, pCursor->bits->width, pCursor->bits->height, -+ source, mask); -+ } -+ -+ /* -+ * copy the temporary pixmap onto the screen -+ */ -+ -+ if (!EnsureGC(pScreenPriv->pRestoreGC, pWin)) -+ return FALSE; -+ pGC = pScreenPriv->pRestoreGC; -+ if (pWin->drawable.serialNumber != pGC->serialNumber) -+ ValidateGC ((DrawablePtr) pWin, pGC); -+ -+ (*pGC->ops->CopyArea) ((DrawablePtr) pTemp, (DrawablePtr) pWin, -+ pGC, -+ 0, 0, w, h, x, y); -+ return TRUE; -+} -diff -pruN xorg-server-1.12.1.orig/hw/vnc/dpmsstubs.c xorg-server-1.12.1/hw/vnc/dpmsstubs.c ---- xorg-server-1.12.1.orig/hw/vnc/dpmsstubs.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/dpmsstubs.c 2012-04-18 14:45:21.574820980 -0500 -@@ -0,0 +1,52 @@ -+/* $Xorg: dpmsstubs.c,v 1.3 2000/08/17 19:47:56 cpqbld Exp $ */ -+/***************************************************************** -+ -+Copyright (c) 1996 Digital Equipment Corporation, Maynard, Massachusetts. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software. -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, -+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, -+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+Except as contained in this notice, the name of Digital Equipment Corporation -+shall not be used in advertising or otherwise to promote the sale, use or other -+dealings in this Software without prior written authorization from Digital -+Equipment Corporation. -+ -+******************************************************************/ -+/* $XFree86: xc/programs/Xserver/Xext/dpmsstubs.c,v 3.3 1999/12/16 02:26:23 robin Exp $ */ -+ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#include "rfb.h" -+ -+#define FALSE 0 -+ -+Bool DPMSSupported(void) -+{ -+ return FALSE; -+} -+ -+int DPSMGet(int *level) -+{ -+ return -1; -+} -+ -+int DPMSSet(ClientPtr client, int level) -+{ -+ return FALSE; -+} -diff -pruN xorg-server-1.12.1.orig/hw/vnc/draw.c xorg-server-1.12.1/hw/vnc/draw.c ---- xorg-server-1.12.1.orig/hw/vnc/draw.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/draw.c 2012-04-18 14:45:21.575820967 -0500 -@@ -0,0 +1,1942 @@ -+/* -+ * draw.c - drawing routines for the RFB X server. This is a set of -+ * wrappers around the standard MI/MFB/CFB drawing routines which work out -+ * to a fair approximation the region of the screen being modified by the -+ * drawing. If the RFB client is ready then the modified region of the screen -+ * is sent to the client, otherwise the modified region will simply grow with -+ * each drawing request until the client is ready. -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+ -+/* -+ -+Copyright (c) 1989 X Consortium -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+Except as contained in this notice, the name of the X Consortium shall not be -+used in advertising or otherwise to promote the sale, use or other dealings -+in this Software without prior written authorization from the X Consortium. -+*/ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#include "rfb.h" -+ -+int rfbDeferUpdateTime = 40; /* ms */ -+ -+extern DevPrivateKeyRec rfbGCKeyRec; -+#define rfbGCKey (&rfbGCKeyRec) -+ -+ -+ -+/****************************************************************************/ -+/* -+ * Macro definitions -+ */ -+/****************************************************************************/ -+ -+#define TRC(x) /* (rfbLog x) */ -+ -+/* ADD_TO_MODIFIED_REGION adds the given region to the modified region for each -+ client */ -+ -+#define ADD_TO_MODIFIED_REGION(pScreen,reg) \ -+ { \ -+ rfbClientPtr cl; \ -+ for (cl = rfbClientHead; cl; cl = cl->next) { \ -+ REGION_UNION((pScreen),&cl->modifiedRegion,&cl->modifiedRegion,reg);\ -+ } \ -+ } -+ -+/* SCHEDULE_FB_UPDATE is used at the end of each drawing routine to schedule an -+ update to be sent to each client if there is one pending and the client is -+ ready for it. */ -+ -+#define SCHEDULE_FB_UPDATE(pScreen,pVNC) \ -+ if (!pVNC->dontSendFramebufferUpdate) { \ -+ rfbClientPtr cl, nextCl; \ -+ for (cl = rfbClientHead; cl; cl = nextCl) { \ -+ nextCl = cl->next; \ -+ if (!cl->deferredUpdateScheduled && FB_UPDATE_PENDING(cl) && \ -+ REGION_NOTEMPTY(pScreen,&cl->requestedRegion)) \ -+ { \ -+ rfbScheduleDeferredUpdate(pScreen, cl); \ -+ } \ -+ } \ -+ } -+ -+/* function prototypes */ -+ -+static void rfbScheduleDeferredUpdate(ScreenPtr pScreen, rfbClientPtr cl); -+static void rfbCopyRegion(ScreenPtr pScreen, rfbClientPtr cl, -+ RegionPtr src, RegionPtr dst, int dx, int dy); -+#ifdef DEBUG -+static void PrintRegion(ScreenPtr pScreen, RegionPtr reg); -+#endif -+ -+/* GC funcs */ -+ -+static void rfbValidateGC(GCPtr, unsigned long /*changes*/, DrawablePtr); -+static void rfbChangeGC(GCPtr, unsigned long /*mask*/); -+static void rfbCopyGC(GCPtr /*src*/, unsigned long /*mask*/, GCPtr /*dst*/); -+static void rfbDestroyGC(GCPtr); -+static void rfbChangeClip(GCPtr, int /*type*/, pointer /*pValue*/, -+ int /*nrects*/); -+static void rfbDestroyClip(GCPtr); -+static void rfbCopyClip(GCPtr /*dst*/, GCPtr /*src*/); -+ -+/* GC ops */ -+ -+static void rfbFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit, DDXPointPtr pptInit, int *pwidthInit, int fSorted); -+static void rfbSetSpans(DrawablePtr pDrawable, -+ GCPtr pGC, -+ char *psrc, -+ register DDXPointPtr ppt, -+ int *pwidth, -+ int nspans, -+ int fSorted); -+static void rfbPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *pBits); -+static RegionPtr rfbCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty); -+static RegionPtr rfbCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, register GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long plane); -+static void rfbPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, xPoint *pts); -+static void rfbPolylines (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppts); -+static void rfbPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *segs); -+static void rfbPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, xRectangle *rects); -+static void rfbPolyArc(DrawablePtr pDrawable, register GCPtr pGC, int narcs, xArc *arcs); -+static void rfbFillPolygon(register DrawablePtr pDrawable, register GCPtr pGC, int shape, int mode, int count, DDXPointPtr pts); -+static void rfbPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrects, xRectangle *rects); -+static void rfbPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *arcs); -+static int rfbPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars); -+static int rfbPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars); -+static void rfbImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars); -+static void rfbImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars); -+static void rfbImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase); -+static void rfbPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase); -+static void rfbPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, int w, int h, int x, int y); -+ -+ -+static GCFuncs rfbGCFuncs = { -+ rfbValidateGC, -+ rfbChangeGC, -+ rfbCopyGC, -+ rfbDestroyGC, -+ rfbChangeClip, -+ rfbDestroyClip, -+ rfbCopyClip, -+}; -+ -+ -+static GCOps rfbGCOps = { -+ rfbFillSpans, rfbSetSpans, rfbPutImage, -+ rfbCopyArea, rfbCopyPlane, rfbPolyPoint, -+ rfbPolylines, rfbPolySegment, rfbPolyRectangle, -+ rfbPolyArc, rfbFillPolygon, rfbPolyFillRect, -+ rfbPolyFillArc, rfbPolyText8, rfbPolyText16, -+ rfbImageText8, rfbImageText16, rfbImageGlyphBlt, -+ rfbPolyGlyphBlt, rfbPushPixels -+}; -+ -+ -+ -+/****************************************************************************/ -+/* -+ * Screen functions wrapper stuff -+ */ -+/****************************************************************************/ -+ -+#define SCREEN_PROLOGUE(scrn, field) \ -+ ScreenPtr pScreen = scrn; \ -+ VNCSCREENPTR(pScreen); \ -+ pScreen->field = pVNC->field; -+ -+#define SCREEN_EPILOGUE(field, wrapper) \ -+ pScreen->field = wrapper; -+ -+ -+/* -+ * CloseScreen wrapper -- unwrap everything, free the private data -+ * and call the wrapped CloseScreen function. -+ */ -+ -+Bool -+rfbCloseScreen (int i, ScreenPtr pScreen) -+{ -+ VNCSCREENPTR(pScreen); -+#if XFREE86VNC -+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; -+#endif -+ int sock; -+ -+ for (sock = 0; sock <= pVNC->maxFd; sock++) { -+ if (FD_ISSET(sock, &pVNC->allFds)) -+ if (sock != pVNC->rfbListenSock && sock != pVNC->httpListenSock) { -+ rfbCloseSock(pScreen, sock); -+ } -+ } -+ -+ if (pVNC->rfbListenSock > 0) -+ if (close(pVNC->rfbListenSock)) -+ ErrorF("Close of port %d failed\n",pVNC->rfbPort); -+ -+ if (pVNC->httpListenSock > 0) -+ if (close(pVNC->httpListenSock)) -+ ErrorF("Close of port %d failed\n",pVNC->httpPort); -+ -+ pScreen->CloseScreen = pVNC->CloseScreen; -+ pScreen->CreateGC = pVNC->CreateGC; -+ pScreen->CopyWindow = pVNC->CopyWindow; -+ pScreen->ClearToBackground = pVNC->ClearToBackground; -+ pScreen->WakeupHandler = pVNC->WakeupHandler; -+ -+#if XFREE86VNC -+ pScreen->InstallColormap = pVNC->InstallColormap; -+ pScreen->UninstallColormap = pVNC->UninstallColormap; -+ pScreen->ListInstalledColormaps = pVNC->ListInstalledColormaps; -+ pScreen->StoreColors = pVNC->StoreColors; -+ pScrn->EnableDisableFBAccess = pVNC->EnableDisableFBAccess; -+ -+ free(pVNC); -+#endif -+ -+ TRC((stderr,"Unwrapped screen functions\n")); -+ -+ return (*pScreen->CloseScreen) (pScreen); -+} -+ -+#if XFREE86VNC -+void -+rfbEnableDisableFBAccess (int index, Bool enable) -+{ -+ ScrnInfoPtr pScrn = xf86Screens[index]; -+ VNCSCREENPTR(pScrn->pScreen); -+ -+ /* -+ * Blank the screen for security while inputs are disabled. -+ * When VT switching is fixed, we might be able to allow -+ * control even when switched away. -+ */ -+ if (!enable) { -+ WindowPtr pWin = pScrn->pScreen->root; -+ ScreenPtr pScreen = pWin->drawable.pScreen; -+ GCPtr pGC; -+ xRectangle rect; -+ -+ rect.x = 0; -+ rect.y = 0; -+ rect.width = pScrn->virtualX; -+ rect.height = pScrn->virtualY; -+ -+ if (!(pGC = GetScratchGC(pScreen->rootDepth, pScreen))) { -+ ErrorF("Couldn't blank screen"); -+ } else { -+ ChangeGCVal attributes[2]; -+ attributes[0].val = pScreen->whitePixel; -+ attributes[1].val = pScreen->blackPixel; -+ (void)ChangeGC(NullClient, pGC, GCForeground | GCBackground, attributes); -+ -+ ValidateGC((DrawablePtr)pWin, pGC); -+ -+ (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, 1, &rect); -+ -+ FreeScratchGC(pGC); -+ -+ /* Flush pending packets */ -+ rfbCheckFds(pScreen); -+ httpCheckFds(pScreen); -+ } -+ } -+ -+ pScrn->EnableDisableFBAccess = pVNC->EnableDisableFBAccess; -+ (*pScrn->EnableDisableFBAccess)(index, enable); -+ pScrn->EnableDisableFBAccess = rfbEnableDisableFBAccess; -+} -+#endif -+ -+/* -+ * CreateGC - wrap the GC funcs (the GC ops will be wrapped when the GC -+ * func "ValidateGC" is called). -+ */ -+ -+Bool -+rfbCreateGC (GCPtr pGC) -+{ -+ Bool ret; -+ rfbGCPtr pGCPriv; -+ -+ SCREEN_PROLOGUE(pGC->pScreen,CreateGC); -+ -+ pGCPriv = (rfbGCPtr) -+ dixLookupPrivate(&(pGC)->devPrivates, rfbGCKey); -+ -+ ret = (*pScreen->CreateGC) (pGC); -+ -+ TRC((stderr,"rfbCreateGC called\n")); -+ -+ pGCPriv->wrapOps = NULL; -+ pGCPriv->wrapFuncs = pGC->funcs; -+ pGC->funcs = &rfbGCFuncs; -+ -+ SCREEN_EPILOGUE(CreateGC,rfbCreateGC); -+ -+ return ret; -+} -+ -+#ifdef CHROMIUM -+Bool -+rfbRealizeWindow(WindowPtr pWin) -+{ -+ CRWindowTable *wt = NULL, *nextWt = NULL; -+ Bool ret; -+ SCREEN_PROLOGUE(pWin->drawable.pScreen,RealizeWindow); -+ -+ for (wt = windowTable; wt; wt = nextWt) { -+ nextWt = wt->next; -+ if (wt->XwinId == pWin->drawable.id) { -+ rfbSendChromiumWindowShow(wt->CRwinId, 1); -+ } -+ } -+ -+ ret = (*pScreen->RealizeWindow)(pWin); -+ -+ SCREEN_EPILOGUE(RealizeWindow,rfbRealizeWindow); -+ -+ return ret; -+} -+ -+Bool -+rfbUnrealizeWindow(WindowPtr pWin) -+{ -+ CRWindowTable *wt = NULL, *nextWt = NULL; -+ Bool ret; -+ SCREEN_PROLOGUE(pWin->drawable.pScreen,UnrealizeWindow); -+ -+ for (wt = windowTable; wt; wt = nextWt) { -+ nextWt = wt->next; -+ if (wt->XwinId == pWin->drawable.id) { -+ rfbSendChromiumWindowShow(wt->CRwinId, 0); -+ } -+ } -+ -+ ret = (*pScreen->UnrealizeWindow)(pWin); -+ -+ SCREEN_EPILOGUE(UnrealizeWindow,rfbUnrealizeWindow); -+ -+ return ret; -+} -+ -+Bool -+rfbDestroyWindow(WindowPtr pWin) -+{ -+ CRWindowTable *wt = NULL, *nextWt = NULL, *prevWt = NULL; -+ Bool ret; -+ SCREEN_PROLOGUE(pWin->drawable.pScreen,DestroyWindow); -+ -+ /* loop over monitored windows */ -+ for (wt = windowTable; wt; wt = nextWt) { -+ nextWt = wt->next; -+ if (wt->XwinId == pWin->drawable.id) { -+ rfbSendChromiumWindowDestroy(wt->CRwinId); -+ /* also remove from list */ -+ if (prevWt) -+ prevWt->next = wt->next; -+ else -+ windowTable = wt->next; -+ free(wt); -+ } -+ else { -+ prevWt = wt; -+ } -+ } -+ -+ ret = (*pScreen->DestroyWindow)(pWin); -+ -+ SCREEN_EPILOGUE(DestroyWindow,rfbDestroyWindow); -+ -+ return ret; -+} -+ -+void -+rfbResizeWindow(WindowPtr pWin, int x, int y, unsigned int w, unsigned int h, WindowPtr pSib) -+{ -+ CRWindowTable *wt = NULL, *nextWt = NULL; -+ SCREEN_PROLOGUE(pWin->drawable.pScreen,ResizeWindow); -+ -+ for (wt = windowTable; wt; wt = nextWt) { -+ nextWt = wt->next; -+ if (wt->XwinId == pWin->drawable.id) { -+ rfbSendChromiumMoveResizeWindow(wt->CRwinId, pWin->drawable.x, pWin->drawable.y, w, h); -+ } -+ } -+ -+ (*pScreen->ResizeWindow)(pWin, x, y, w, h, pSib); -+ -+ SCREEN_EPILOGUE(ResizeWindow,rfbResizeWindow); -+} -+ -+Bool -+rfbPositionWindow(WindowPtr pWin, int x, int y) -+{ -+ Bool ret; -+ CRWindowTable *wt, *nextWt; -+ SCREEN_PROLOGUE(pWin->drawable.pScreen,PositionWindow); -+ -+ for (wt = windowTable; wt; wt = nextWt) { -+ nextWt = wt->next; -+ if (wt->XwinId == pWin->drawable.id) { -+ rfbSendChromiumMoveResizeWindow(wt->CRwinId, x, y, pWin->drawable.width, pWin->drawable.height); -+ } -+ } -+ -+ ret = (*pScreen->PositionWindow)(pWin, x, y); -+ -+ SCREEN_EPILOGUE(PositionWindow,rfbPositionWindow); -+ -+ return ret; -+} -+ -+void -+rfbClipNotify(WindowPtr pWin, int x, int y) -+{ -+ CRWindowTable *wt, *nextWt; -+ SCREEN_PROLOGUE(pWin->drawable.pScreen,ClipNotify); -+ -+ for (wt = windowTable; wt; wt = nextWt) { -+ nextWt = wt->next; -+ if (wt->XwinId == pWin->drawable.id) { -+ int numClipRects = REGION_NUM_RECTS(&pWin->clipList); -+ BoxPtr pClipRects = REGION_RECTS(&pWin->clipList); -+ -+ /* Possible optimization - has the cliplist really? changed */ -+ -+ rfbSendChromiumClipList(wt->CRwinId, pClipRects, numClipRects); -+ } -+ } -+ -+ if (*pScreen->ClipNotify) -+ (*pScreen->ClipNotify)(pWin, x, y); -+ -+ SCREEN_EPILOGUE(ClipNotify,rfbClipNotify); -+} -+#endif /* CHROMIUM */ -+ -+/* -+ * CopyWindow - the region being modified is the translation of the old -+ * region, clipped to the border clip region of the window. Note that any -+ * parts of the window which have become newly-visible will not be affected by -+ * this call - a separate PaintWindowBackground/Border will be called to do -+ * that. If the client will accept CopyRect messages then use rfbCopyRegion to -+ * optimise the pending screen changes into a single "copy region" plus the -+ * ordinary modified region. -+ */ -+ -+void -+rfbCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion) -+{ -+ rfbClientPtr cl; -+ RegionRec srcRegion, dstRegion; -+ SCREEN_PROLOGUE(pWin->drawable.pScreen,CopyWindow); -+ -+ TRC((stderr,"rfbCopyWindow called\n")); -+ -+ REGION_NULL(pScreen,&dstRegion); -+ REGION_COPY(pScreen,&dstRegion,pOldRegion); -+ REGION_TRANSLATE(pWin->drawable.pScreen, &dstRegion, -+ pWin->drawable.x - ptOldOrg.x, -+ pWin->drawable.y - ptOldOrg.y); -+ REGION_INTERSECT(pWin->drawable.pScreen, &dstRegion, &dstRegion, -+ &pWin->borderClip); -+ -+ for (cl = rfbClientHead; cl; cl = cl->next) { -+ if (cl->useCopyRect) { -+ REGION_NULL(pScreen,&srcRegion); -+ REGION_COPY(pScreen,&srcRegion,pOldRegion); -+ -+ rfbCopyRegion(pScreen, cl, &srcRegion, &dstRegion, -+ pWin->drawable.x - ptOldOrg.x, -+ pWin->drawable.y - ptOldOrg.y); -+ -+ REGION_UNINIT(pScreen, &srcRegion); -+ -+ } else { -+ -+ REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, -+ &dstRegion); -+ } -+ } -+ -+ REGION_UNINIT(pScreen, &dstRegion); -+ -+ (*pScreen->CopyWindow) (pWin, ptOldOrg, pOldRegion); -+ -+ SCHEDULE_FB_UPDATE(pScreen, pVNC); -+ -+ SCREEN_EPILOGUE(CopyWindow,rfbCopyWindow); -+} -+ -+/* -+ * ClearToBackground - when generateExposures is false, the region being -+ * modified is the given rectangle (clipped to the "window clip region"). -+ */ -+ -+void -+rfbClearToBackground (WindowPtr pWin, int x, int y, int w, int h, -+ Bool generateExposures) -+{ -+ RegionRec tmpRegion; -+ BoxRec box; -+ SCREEN_PROLOGUE(pWin->drawable.pScreen,ClearToBackground); -+ -+ TRC((stderr,"rfbClearToBackground called\n")); -+ -+ if (!generateExposures) { -+ box.x1 = x + pWin->drawable.x; -+ box.y1 = y + pWin->drawable.y; -+ box.x2 = w ? (box.x1 + w) : (pWin->drawable.x + pWin->drawable.width); -+ box.y2 = h ? (box.y1 + h) : (pWin->drawable.y + pWin->drawable.height); -+ -+ SAFE_REGION_INIT(pScreen, &tmpRegion, &box, 0); -+ -+ REGION_INTERSECT(pScreen, &tmpRegion, &tmpRegion, &pWin->clipList); -+ -+ ADD_TO_MODIFIED_REGION(pScreen, &tmpRegion); -+ -+ REGION_UNINIT(pScreen, &tmpRegion); -+ } -+ -+ (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures); -+ -+ if (!generateExposures) { -+ SCHEDULE_FB_UPDATE(pScreen, pVNC); -+ } -+ -+ SCREEN_EPILOGUE(ClearToBackground,rfbClearToBackground); -+} -+ -+ -+/****************************************************************************/ -+/* -+ * GC funcs wrapper stuff -+ * -+ * We only really want to wrap the GC ops, but to do this we need to wrap -+ * ValidateGC and so all the other GC funcs must be wrapped as well. -+ */ -+/****************************************************************************/ -+ -+#define GC_FUNC_PROLOGUE(pGC) \ -+ rfbGCPtr pGCPriv = (rfbGCPtr)dixLookupPrivate(&(pGC)->devPrivates, rfbGCKey); \ -+ (pGC)->funcs = pGCPriv->wrapFuncs; \ -+ if (pGCPriv->wrapOps) \ -+ (pGC)->ops = pGCPriv->wrapOps; -+ -+#define GC_FUNC_EPILOGUE(pGC) \ -+ pGCPriv->wrapFuncs = (pGC)->funcs; \ -+ (pGC)->funcs = &rfbGCFuncs; \ -+ if (pGCPriv->wrapOps) { \ -+ pGCPriv->wrapOps = (pGC)->ops; \ -+ (pGC)->ops = &rfbGCOps; \ -+ } -+ -+ -+/* -+ * ValidateGC - call the wrapped ValidateGC, then wrap the resulting GC ops if -+ * the drawing will be to a viewable window. -+ */ -+ -+static void -+rfbValidateGC (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) -+{ -+ GC_FUNC_PROLOGUE(pGC); -+ -+ TRC((stderr,"rfbValidateGC called\n")); -+ -+ (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable); -+ -+ pGCPriv->wrapOps = NULL; -+ if (pDrawable->type == DRAWABLE_WINDOW && ((WindowPtr)pDrawable)->viewable) -+ { -+ WindowPtr pWin = (WindowPtr) pDrawable; -+ RegionPtr pRegion = &pWin->clipList; -+ -+ if (pGC->subWindowMode == IncludeInferiors) -+ pRegion = &pWin->borderClip; -+ if (REGION_NOTEMPTY(pDrawable->pScreen, pRegion)) { -+ pGCPriv->wrapOps = pGC->ops; -+ TRC((stderr,"rfbValidateGC: wrapped GC ops\n")); -+ } -+ } -+ -+ GC_FUNC_EPILOGUE(pGC); -+} -+ -+/* -+ * All other GC funcs simply unwrap the GC funcs and ops, call the wrapped -+ * function and then rewrap the funcs and ops. -+ */ -+ -+static void -+rfbChangeGC (GCPtr pGC, unsigned long mask) -+{ -+ GC_FUNC_PROLOGUE(pGC); -+ (*pGC->funcs->ChangeGC) (pGC, mask); -+ GC_FUNC_EPILOGUE(pGC); -+} -+ -+static void -+rfbCopyGC (GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) -+{ -+ GC_FUNC_PROLOGUE(pGCDst); -+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); -+ GC_FUNC_EPILOGUE(pGCDst); -+} -+ -+static void -+rfbDestroyGC (GCPtr pGC) -+{ -+ GC_FUNC_PROLOGUE(pGC); -+ (*pGC->funcs->DestroyGC) (pGC); -+ GC_FUNC_EPILOGUE(pGC); -+} -+ -+static void -+rfbChangeClip (GCPtr pGC, int type, pointer pvalue, int nrects) -+{ -+ GC_FUNC_PROLOGUE(pGC); -+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); -+ GC_FUNC_EPILOGUE(pGC); -+} -+ -+static void -+rfbDestroyClip(GCPtr pGC) -+{ -+ GC_FUNC_PROLOGUE(pGC); -+ (* pGC->funcs->DestroyClip)(pGC); -+ GC_FUNC_EPILOGUE(pGC); -+} -+ -+static void -+rfbCopyClip(GCPtr pgcDst, GCPtr pgcSrc) -+{ -+ GC_FUNC_PROLOGUE(pgcDst); -+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); -+ GC_FUNC_EPILOGUE(pgcDst); -+} -+ -+ -+/****************************************************************************/ -+/* -+ * GC ops wrapper stuff -+ * -+ * Note that these routines will only have been wrapped for drawing to -+ * viewable windows so we don't need to check each time that the drawable -+ * is a viewable window. -+ */ -+/****************************************************************************/ -+ -+#define GC_OP_PROLOGUE(pDrawable,pGC) \ -+ ScreenPtr pScreen = pGC->pScreen; \ -+ VNCSCREENPTR(pScreen); \ -+ rfbGCPtr pGCPrivate = (rfbGCPtr)dixLookupPrivate(&(pGC)->devPrivates, rfbGCKey); \ -+ GCFuncs *oldFuncs = pGC->funcs; \ -+ (void) pScreen; /* silence compiler */ \ -+ (pGC)->funcs = pGCPrivate->wrapFuncs; \ -+ (pGC)->ops = pGCPrivate->wrapOps; -+ -+#define GC_OP_EPILOGUE(pGC) \ -+ pGCPrivate->wrapOps = (pGC)->ops; \ -+ (pGC)->funcs = oldFuncs; \ -+ (pGC)->ops = &rfbGCOps; -+ -+ -+/* -+ * FillSpans - being very safe - the region being modified is the border clip -+ * region of the window. -+ */ -+ -+static void -+rfbFillSpans(DrawablePtr pDrawable, -+ GCPtr pGC, -+ int nInit, /* number of spans to fill */ -+ DDXPointPtr pptInit, /* pointer to list of start points */ -+ int *pwidthInit, /* pointer to list of n widths */ -+ int fSorted ) -+{ -+ GC_OP_PROLOGUE(pDrawable,pGC); -+ -+ TRC((stderr,"rfbFillSpans called\n")); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, -+ &((WindowPtr)pDrawable)->borderClip); -+ -+ (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit,pwidthInit,fSorted); -+ -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+/* -+ * SetSpans - being very safe - the region being modified is the border clip -+ * region of the window. -+ */ -+ -+static void -+rfbSetSpans(DrawablePtr pDrawable, -+ GCPtr pGC, -+ char *psrc, -+ register DDXPointPtr ppt, -+ int *pwidth, -+ int nspans, -+ int fSorted) -+{ -+ GC_OP_PROLOGUE(pDrawable,pGC); -+ -+ TRC((stderr,"rfbSetSpans called\n")); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, -+ &((WindowPtr)pDrawable)->borderClip); -+ -+ (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); -+ -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+/* -+ * PutImage - the region being modified is the rectangle of the -+ * PutImage (clipped to the window clip region). -+ */ -+ -+static void -+rfbPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *pBits) -+{ -+ RegionRec tmpRegion; -+ BoxRec box; -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbPutImage called\n")); -+ -+ box.x1 = x + pDrawable->x; -+ box.y1 = y + pDrawable->y; -+ box.x2 = box.x1 + w; -+ box.y2 = box.y1 + h; -+ -+ SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0); -+ -+ REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion); -+ -+ REGION_UNINIT(pDrawable->pScreen, &tmpRegion); -+ -+ (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, -+ leftPad, format, pBits); -+ -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+/* -+ * CopyArea - the region being modified is the destination rectangle (clipped -+ * to the window clip region). -+ * If the client will accept CopyRect messages then use rfbCopyRegion -+ * to optimise the pending screen changes into a single "copy region" plus -+ * the ordinary modified region. -+ */ -+ -+static RegionPtr -+rfbCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty) -+{ -+ rfbClientPtr cl; -+ RegionPtr rgn; -+ RegionRec srcRegion, dstRegion; -+ BoxRec box; -+ GC_OP_PROLOGUE(pDst, pGC); -+ -+ TRC((stderr,"rfbCopyArea called\n")); -+ -+ box.x1 = dstx + pDst->x; -+ box.y1 = dsty + pDst->y; -+ box.x2 = box.x1 + w; -+ box.y2 = box.y1 + h; -+ -+ SAFE_REGION_INIT(pDst->pScreen, &dstRegion, &box, 0); -+ REGION_INTERSECT(pDst->pScreen, &dstRegion, &dstRegion, -+ pGC->pCompositeClip); -+ -+ if ((pSrc->type == DRAWABLE_WINDOW) && (pSrc->pScreen == pDst->pScreen)) { -+ box.x1 = srcx + pSrc->x; -+ box.y1 = srcy + pSrc->y; -+ box.x2 = box.x1 + w; -+ box.y2 = box.y1 + h; -+ -+ for (cl = rfbClientHead; cl; cl = cl->next) { -+ if (cl->useCopyRect) { -+ SAFE_REGION_INIT(pSrc->pScreen, &srcRegion, &box, 0); -+ REGION_INTERSECT(pSrc->pScreen, &srcRegion, &srcRegion, -+ &((WindowPtr)pSrc)->clipList); -+ -+ rfbCopyRegion(pSrc->pScreen, cl, &srcRegion, &dstRegion, -+ dstx + pDst->x - srcx - pSrc->x, -+ dsty + pDst->y - srcy - pSrc->y); -+ -+ REGION_UNINIT(pSrc->pScreen, &srcRegion); -+ -+ } else { -+ -+ REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, -+ &dstRegion); -+ } -+ } -+ -+ } else { -+ -+ ADD_TO_MODIFIED_REGION(pDst->pScreen, &dstRegion); -+ } -+ -+ REGION_UNINIT(pDst->pScreen, &dstRegion); -+ -+ rgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h, -+ dstx, dsty); -+ -+ SCHEDULE_FB_UPDATE(pDst->pScreen, pVNC); -+ -+ GC_OP_EPILOGUE(pGC); -+ -+ return rgn; -+} -+ -+ -+/* -+ * CopyPlane - the region being modified is the destination rectangle (clipped -+ * to the window clip region). -+ */ -+ -+static RegionPtr -+rfbCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, register GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long plane) -+{ -+ RegionPtr rgn; -+ RegionRec tmpRegion; -+ BoxRec box; -+ GC_OP_PROLOGUE(pDst, pGC); -+ -+ TRC((stderr,"rfbCopyPlane called\n")); -+ -+ box.x1 = dstx + pDst->x; -+ box.y1 = dsty + pDst->y; -+ box.x2 = box.x1 + w; -+ box.y2 = box.y1 + h; -+ -+ SAFE_REGION_INIT(pDst->pScreen, &tmpRegion, &box, 0); -+ -+ REGION_INTERSECT(pDst->pScreen, &tmpRegion, &tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDst->pScreen, &tmpRegion); -+ -+ REGION_UNINIT(pDst->pScreen, &tmpRegion); -+ -+ rgn = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h, -+ dstx, dsty, plane); -+ -+ SCHEDULE_FB_UPDATE(pDst->pScreen, pVNC); -+ -+ GC_OP_EPILOGUE(pGC); -+ -+ return rgn; -+} -+ -+/* -+ * PolyPoint - find the smallest rectangle which encloses the points drawn -+ * (and clip). -+ */ -+ -+static void -+rfbPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, xPoint *pts) -+{ -+ int i; -+ RegionRec tmpRegion; -+ BoxRec box; -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbPolyPoint called\n")); -+ -+ if (npt) { -+ int minX = pts[0].x, maxX = pts[0].x; -+ int minY = pts[0].y, maxY = pts[0].y; -+ -+ if (mode == CoordModePrevious) -+ { -+ int x = pts[0].x, y = pts[0].y; -+ -+ for (i = 1; i < npt; i++) { -+ x += pts[i].x; -+ y += pts[i].y; -+ if (x < minX) minX = x; -+ if (x > maxX) maxX = x; -+ if (y < minY) minY = y; -+ if (y > maxY) maxY = y; -+ } -+ } -+ else -+ { -+ for (i = 1; i < npt; i++) { -+ if (pts[i].x < minX) minX = pts[i].x; -+ if (pts[i].x > maxX) maxX = pts[i].x; -+ if (pts[i].y < minY) minY = pts[i].y; -+ if (pts[i].y > maxY) maxY = pts[i].y; -+ } -+ } -+ -+ box.x1 = minX + pDrawable->x; -+ box.y1 = minY + pDrawable->y; -+ box.x2 = maxX + 1 + pDrawable->x; -+ box.y2 = maxY + 1 + pDrawable->y; -+ -+ SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0); -+ -+ REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion); -+ -+ REGION_UNINIT(pDrawable->pScreen, &tmpRegion); -+ } -+ -+ (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pts); -+ -+ if (npt) { -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ } -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+/* -+ * PolyLines - take the union of bounding boxes around each line (and clip). -+ */ -+ -+static void -+rfbPolylines (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppts) -+{ -+ RegionPtr tmpRegion; -+ xRectangle *rects; -+ int i, extra, nlines, lw; -+ int x1, x2, y1, y2; -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbPolylines called\n")); -+ -+ if (npt) { -+ lw = pGC->lineWidth; -+ if (lw == 0) -+ lw = 1; -+ -+ if (npt == 1) -+ { -+ nlines = 1; -+ rects = (xRectangle *)malloc(sizeof(xRectangle)); -+ if (!rects) { -+ FatalError("rfbPolylines: malloc failed\n"); -+ } -+ -+ rects[0].x = ppts[0].x - lw + pDrawable->x; /* being safe here */ -+ rects[0].y = ppts[0].y - lw + pDrawable->y; -+ rects[0].width = 2*lw; -+ rects[0].height = 2*lw; -+ } -+ else -+ { -+ nlines = npt - 1; -+ rects = (xRectangle *)malloc(nlines*sizeof(xRectangle)); -+ if (!rects) { -+ FatalError("rfbPolylines: malloc failed\n"); -+ } -+ -+ /* -+ * mitered joins can project quite a way from -+ * the line end; the 11 degree miter limit limits -+ * this extension to lw / (2 * tan(11/2)), rounded up -+ * and converted to int yields 6 * lw -+ */ -+ -+ if (pGC->joinStyle == JoinMiter) { -+ extra = 6 * lw; -+ } else { -+ extra = lw / 2; -+ } -+ -+ x1 = ppts[0].x + pDrawable->x; -+ y1 = ppts[0].y + pDrawable->y; -+ -+ for (i = 0; i < nlines; i++) { -+ if (mode == CoordModeOrigin) { -+ x2 = pDrawable->x + ppts[i+1].x; -+ y2 = pDrawable->y + ppts[i+1].y; -+ } else { -+ x2 = x1 + ppts[i+1].x; -+ y2 = y1 + ppts[i+1].y; -+ } -+ -+ if (x1 > x2) { -+ rects[i].x = x2 - extra; -+ rects[i].width = x1 - x2 + 1 + 2 * extra; -+ } else { -+ rects[i].x = x1 - extra; -+ rects[i].width = x2 - x1 + 1 + 2 * extra; -+ } -+ -+ if (y1 > y2) { -+ rects[i].y = y2 - extra; -+ rects[i].height = y1 - y2 + 1 + 2 * extra; -+ } else { -+ rects[i].y = y1 - extra; -+ rects[i].height = y2 - y1 + 1 + 2 * extra; -+ } -+ -+ x1 = x2; -+ y1 = y2; -+ } -+ } -+ tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, nlines, rects,CT_NONE); -+ REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion); -+ -+ REGION_DESTROY(pDrawable->pScreen, tmpRegion); -+ free((char *)rects); -+ } -+ -+ (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, ppts); -+ -+ if (npt) { -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ } -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+/* -+ * PolySegment - take the union of bounding boxes around each segment (and -+ * clip). -+ */ -+ -+static void -+rfbPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *segs) -+{ -+ RegionPtr tmpRegion; -+ xRectangle *rects; -+ int i, extra, lw; -+ -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbPolySegment called\n")); -+ -+ if (nseg) { -+ rects = (xRectangle *)malloc(nseg*sizeof(xRectangle)); -+ if (!rects) { -+ FatalError("rfbPolySegment: malloc failed\n"); -+ } -+ -+ lw = pGC->lineWidth; -+ if (lw == 0) -+ lw = 1; -+ -+ extra = lw / 2; -+ -+ for (i = 0; i < nseg; i++) -+ { -+ if (segs[i].x1 > segs[i].x2) { -+ rects[i].x = segs[i].x2 - extra + pDrawable->x; -+ rects[i].width = segs[i].x1 - segs[i].x2 + 1 + 2 * extra; -+ } else { -+ rects[i].x = segs[i].x1 - extra + pDrawable->x; -+ rects[i].width = segs[i].x2 - segs[i].x1 + 1 + 2 * extra; -+ } -+ -+ if (segs[i].y1 > segs[i].y2) { -+ rects[i].y = segs[i].y2 - extra + pDrawable->y; -+ rects[i].height = segs[i].y1 - segs[i].y2 + 1 + 2 * extra; -+ } else { -+ rects[i].y = segs[i].y1 - extra + pDrawable->y; -+ rects[i].height = segs[i].y2 - segs[i].y1 + 1 + 2 * extra; -+ } -+ } -+ -+ tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, nseg, rects, CT_NONE); -+ REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion); -+ -+ REGION_DESTROY(pDrawable->pScreen, tmpRegion); -+ free((char *)rects); -+ } -+ -+ (*pGC->ops->PolySegment) (pDrawable, pGC, nseg, segs); -+ -+ if (nseg) { -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ } -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+/* -+ * PolyRectangle (rectangle outlines) - take the union of bounding boxes -+ * around each line (and clip). -+ */ -+ -+static void -+rfbPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, xRectangle *rects) -+{ -+ int i, extra, lw; -+ RegionPtr tmpRegion; -+ xRectangle *regRects; -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbPolyRectangle called\n")); -+ -+ if (nrects) { -+ regRects = (xRectangle *)malloc(nrects*4*sizeof(xRectangle)); -+ if (!regRects) { -+ FatalError("rfbPolyRectangle: malloc failed\n"); -+ } -+ -+ lw = pGC->lineWidth; -+ if (lw == 0) -+ lw = 1; -+ -+ extra = lw / 2; -+ -+ for (i = 0; i < nrects; i++) -+ { -+ regRects[i*4].x = rects[i].x - extra + pDrawable->x; -+ regRects[i*4].y = rects[i].y - extra + pDrawable->y; -+ regRects[i*4].width = rects[i].width + 1 + 2 * extra; -+ regRects[i*4].height = 1 + 2 * extra; -+ -+ regRects[i*4+1].x = rects[i].x - extra + pDrawable->x; -+ regRects[i*4+1].y = rects[i].y - extra + pDrawable->y; -+ regRects[i*4+1].width = 1 + 2 * extra; -+ regRects[i*4+1].height = rects[i].height + 1 + 2 * extra; -+ -+ regRects[i*4+2].x -+ = rects[i].x + rects[i].width - extra + pDrawable->x; -+ regRects[i*4+2].y = rects[i].y - extra + pDrawable->y; -+ regRects[i*4+2].width = 1 + 2 * extra; -+ regRects[i*4+2].height = rects[i].height + 1 + 2 * extra; -+ -+ regRects[i*4+3].x = rects[i].x - extra + pDrawable->x; -+ regRects[i*4+3].y -+ = rects[i].y + rects[i].height - extra + pDrawable->y; -+ regRects[i*4+3].width = rects[i].width + 1 + 2 * extra; -+ regRects[i*4+3].height = 1 + 2 * extra; -+ } -+ -+ tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, nrects*4, -+ regRects, CT_NONE); -+ REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion); -+ -+ REGION_DESTROY(pDrawable->pScreen, tmpRegion); -+ free((char *)regRects); -+ } -+ -+ (*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, rects); -+ -+ if (nrects) { -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ } -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+/* -+ * PolyArc - take the union of bounding boxes around each arc (and clip). -+ * Bounding boxes assume each is a full circle / ellipse. -+ */ -+ -+static void -+rfbPolyArc(DrawablePtr pDrawable, register GCPtr pGC, int narcs, xArc *arcs) -+{ -+ int i, extra, lw; -+ RegionPtr tmpRegion; -+ xRectangle *rects; -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbPolyArc called\n")); -+ -+ if (narcs) { -+ rects = (xRectangle *)malloc(narcs*sizeof(xRectangle)); -+ if (!rects) { -+ FatalError("rfbPolyArc: malloc failed\n"); -+ } -+ -+ lw = pGC->lineWidth; -+ if (lw == 0) -+ lw = 1; -+ -+ extra = lw / 2; -+ -+ for (i = 0; i < narcs; i++) -+ { -+ rects[i].x = arcs[i].x - extra + pDrawable->x; -+ rects[i].y = arcs[i].y - extra + pDrawable->y; -+ rects[i].width = arcs[i].width + lw; -+ rects[i].height = arcs[i].height + lw; -+ } -+ -+ tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, narcs, rects, CT_NONE); -+ REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion); -+ -+ REGION_DESTROY(pDrawable->pScreen, tmpRegion); -+ free((char *)rects); -+ } -+ -+ (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, arcs); -+ -+ if (narcs) { -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ } -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+/* -+ * FillPolygon - take bounding box around polygon (and clip). -+ */ -+ -+static void -+rfbFillPolygon(register DrawablePtr pDrawable, register GCPtr pGC, int shape, int mode, int count, DDXPointPtr pts) -+{ -+ int i; -+ RegionRec tmpRegion; -+ BoxRec box; -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbFillPolygon called\n")); -+ -+ if (count) { -+ int minX = pts[0].x, maxX = pts[0].x; -+ int minY = pts[0].y, maxY = pts[0].y; -+ -+ if (mode == CoordModePrevious) -+ { -+ int x = pts[0].x, y = pts[0].y; -+ -+ for (i = 1; i < count; i++) { -+ x += pts[i].x; -+ y += pts[i].y; -+ if (x < minX) minX = x; -+ if (x > maxX) maxX = x; -+ if (y < minY) minY = y; -+ if (y > maxY) maxY = y; -+ } -+ } -+ else -+ { -+ for (i = 1; i < count; i++) { -+ if (pts[i].x < minX) minX = pts[i].x; -+ if (pts[i].x > maxX) maxX = pts[i].x; -+ if (pts[i].y < minY) minY = pts[i].y; -+ if (pts[i].y > maxY) maxY = pts[i].y; -+ } -+ } -+ -+ box.x1 = minX + pDrawable->x; -+ box.y1 = minY + pDrawable->y; -+ box.x2 = maxX + 1 + pDrawable->x; -+ box.y2 = maxY + 1 + pDrawable->y; -+ -+ SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0); -+ -+ REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion); -+ -+ REGION_UNINIT(pDrawable->pScreen, &tmpRegion); -+ } -+ -+ (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pts); -+ -+ if (count) { -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ } -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+/* -+ * PolyFillRect - take the union of the given rectangles (and clip). -+ */ -+ -+static void -+rfbPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrects, xRectangle *rects) -+{ -+ RegionPtr tmpRegion; -+ xRectangle *regRects; -+ int i; -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbPolyFillRect called\n")); -+ -+ if (nrects) { -+ regRects = (xRectangle *)malloc(nrects*sizeof(xRectangle)); -+ if (!regRects) { -+ FatalError("rfbPolyFillRect: malloc failed\n"); -+ } -+ -+ for (i = 0; i < nrects; i++) { -+ regRects[i].x = rects[i].x + pDrawable->x; -+ regRects[i].y = rects[i].y + pDrawable->y; -+ regRects[i].width = rects[i].width; -+ regRects[i].height = rects[i].height; -+ } -+ -+ tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, nrects, regRects, -+ CT_NONE); -+ REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion); -+ -+ REGION_DESTROY(pDrawable->pScreen, tmpRegion); -+ free((char *)regRects); -+ } -+ -+ (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrects, rects); -+ -+ if (nrects) { -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ } -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+/* -+ * PolyFillArc - take the union of bounding boxes around each arc (and clip). -+ * Bounding boxes assume each is a full circle / ellipse. -+ */ -+ -+static void -+rfbPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *arcs) -+{ -+ int i, extra, lw; -+ RegionPtr tmpRegion; -+ xRectangle *rects; -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbPolyFillArc called\n")); -+ -+ if (narcs) { -+ rects = (xRectangle *)malloc(narcs*sizeof(xRectangle)); -+ if (!rects) { -+ FatalError("rfbPolyFillArc: malloc failed\n"); -+ } -+ -+ lw = pGC->lineWidth; -+ if (lw == 0) -+ lw = 1; -+ -+ extra = lw / 2; -+ -+ for (i = 0; i < narcs; i++) -+ { -+ rects[i].x = arcs[i].x - extra + pDrawable->x; -+ rects[i].y = arcs[i].y - extra + pDrawable->y; -+ rects[i].width = arcs[i].width + lw; -+ rects[i].height = arcs[i].height + lw; -+ } -+ -+ tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, narcs, rects, CT_NONE); -+ REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion); -+ -+ REGION_DESTROY(pDrawable->pScreen, tmpRegion); -+ free((char *)rects); -+ } -+ -+ (*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, arcs); -+ -+ if (narcs) { -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ } -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+/* -+ * Get a rough bounding box around n characters of the given font. -+ */ -+ -+static void GetTextBoundingBox(DrawablePtr pDrawable, FontPtr font, int x, int y, int n, BoxPtr pbox) -+{ -+ int maxAscent, maxDescent, maxCharWidth; -+ -+ if (FONTASCENT(font) > FONTMAXBOUNDS(font,ascent)) -+ maxAscent = FONTASCENT(font); -+ else -+ maxAscent = FONTMAXBOUNDS(font,ascent); -+ -+ if (FONTDESCENT(font) > FONTMAXBOUNDS(font,descent)) -+ maxDescent = FONTDESCENT(font); -+ else -+ maxDescent = FONTMAXBOUNDS(font,descent); -+ -+ if (FONTMAXBOUNDS(font,rightSideBearing) > FONTMAXBOUNDS(font,characterWidth)) -+ maxCharWidth = FONTMAXBOUNDS(font,rightSideBearing); -+ else -+ maxCharWidth = FONTMAXBOUNDS(font,characterWidth); -+ -+ pbox->x1 = pDrawable->x + x; -+ pbox->y1 = pDrawable->y + y - maxAscent; -+ pbox->x2 = pbox->x1 + maxCharWidth * n; -+ pbox->y2 = pbox->y1 + maxAscent + maxDescent; -+ -+ if (FONTMINBOUNDS(font,leftSideBearing) < 0) { -+ pbox->x1 += FONTMINBOUNDS(font,leftSideBearing); -+ } -+} -+ -+ -+/* -+ * PolyText8 - use rough bounding box. -+ */ -+ -+static int -+rfbPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars) -+{ -+ int ret; -+ RegionRec tmpRegion; -+ BoxRec box; -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbPolyText8 called '%.*s'\n",count,chars)); -+ -+ if (count) { -+ GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); -+ -+ SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0); -+ -+ REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion); -+ -+ REGION_UNINIT(pDrawable->pScreen, &tmpRegion); -+ } -+ -+ ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars); -+ -+ if (count) { -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ } -+ -+ GC_OP_EPILOGUE(pGC); -+ return ret; -+} -+ -+/* -+ * PolyText16 - use rough bounding box. -+ */ -+ -+static int -+rfbPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars) -+{ -+ int ret; -+ RegionRec tmpRegion; -+ BoxRec box; -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbPolyText16 called\n")); -+ -+ if (count) { -+ GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); -+ -+ SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0); -+ -+ REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion); -+ -+ REGION_UNINIT(pDrawable->pScreen, &tmpRegion); -+ } -+ -+ ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars); -+ -+ if (count) { -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ } -+ -+ GC_OP_EPILOGUE(pGC); -+ return ret; -+} -+ -+/* -+ * ImageText8 - use rough bounding box. -+ */ -+ -+static void -+rfbImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars) -+{ -+ RegionRec tmpRegion; -+ BoxRec box; -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbImageText8 called '%.*s'\n",count,chars)); -+ -+ if (count) { -+ GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); -+ -+ SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0); -+ -+ REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion); -+ -+ REGION_UNINIT(pDrawable->pScreen, &tmpRegion); -+ } -+ -+ (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars); -+ -+ if (count) { -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ } -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+/* -+ * ImageText16 - use rough bounding box. -+ */ -+ -+static void -+rfbImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars) -+{ -+ RegionRec tmpRegion; -+ BoxRec box; -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbImageText16 called\n")); -+ -+ if (count) { -+ GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); -+ -+ SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0); -+ -+ REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion); -+ -+ REGION_UNINIT(pDrawable->pScreen, &tmpRegion); -+ } -+ -+ (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars); -+ -+ if (count) { -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ } -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+/* -+ * ImageGlyphBlt - use rough bounding box. -+ */ -+ -+static void -+rfbImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase) -+{ -+ RegionRec tmpRegion; -+ BoxRec box; -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbImageGlyphBlt called\n")); -+ -+ if (nglyph) { -+ GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box); -+ -+ SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0); -+ -+ REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion); -+ -+ REGION_UNINIT(pDrawable->pScreen, &tmpRegion); -+ } -+ -+ (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci,pglyphBase); -+ -+ if (nglyph) { -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ } -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+/* -+ * PolyGlyphBlt - use rough bounding box. -+ */ -+ -+static void -+rfbPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase) -+{ -+ RegionRec tmpRegion; -+ BoxRec box; -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbPolyGlyphBlt called\n")); -+ -+ if (nglyph) { -+ GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box); -+ -+ SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0); -+ -+ REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion); -+ -+ REGION_UNINIT(pDrawable->pScreen, &tmpRegion); -+ } -+ -+ (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); -+ -+ if (nglyph) { -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ } -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+/* -+ * PushPixels - be fairly safe - region modified is intersection of the given -+ * rectangle with the window clip region. -+ */ -+ -+static void -+rfbPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, int w, int h, int x, int y) -+{ -+ RegionRec tmpRegion; -+ BoxRec box; -+ GC_OP_PROLOGUE(pDrawable, pGC); -+ -+ TRC((stderr,"rfbPushPixels called\n")); -+ -+ box.x1 = x + pDrawable->x; -+ box.y1 = y + pDrawable->y; -+ box.x2 = box.x1 + w; -+ box.y2 = box.y1 + h; -+ -+ SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0); -+ -+ REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion, -+ pGC->pCompositeClip); -+ -+ ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion); -+ -+ REGION_UNINIT(pDrawable->pScreen, &tmpRegion); -+ -+ (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y); -+ -+ SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC); -+ -+ GC_OP_EPILOGUE(pGC); -+} -+ -+#ifdef RENDER -+void -+rfbComposite( -+ CARD8 op, -+ PicturePtr pSrc, -+ PicturePtr pMask, -+ PicturePtr pDst, -+ INT16 xSrc, -+ INT16 ySrc, -+ INT16 xMask, -+ INT16 yMask, -+ INT16 xDst, -+ INT16 yDst, -+ CARD16 width, -+ CARD16 height -+){ -+ ScreenPtr pScreen = pDst->pDrawable->pScreen; -+ VNCSCREENPTR(pScreen); -+ RegionRec tmpRegion; -+ BoxRec box; -+ PictureScreenPtr ps = GetPictureScreen(pScreen); -+ -+ box.x1 = pDst->pDrawable->x + xDst; -+ box.y1 = pDst->pDrawable->y + yDst; -+ box.x2 = box.x1 + width; -+ box.y2 = box.y1 + height; -+ -+ REGION_INIT(pScreen, &tmpRegion, &box, 0); -+ -+ ADD_TO_MODIFIED_REGION(pScreen, &tmpRegion); -+ -+ ps->Composite = pVNC->Composite; -+ (*ps->Composite)(op, pSrc, pMask, pDst, xSrc, ySrc, -+ xMask, yMask, xDst, yDst, width, height); -+ ps->Composite = rfbComposite; -+ -+ SCHEDULE_FB_UPDATE(pScreen, pVNC); -+ -+ REGION_UNINIT(pScreen, &tmpRegion); -+} -+#endif /* RENDER */ -+ -+/****************************************************************************/ -+/* -+ * Other functions -+ */ -+/****************************************************************************/ -+ -+/* -+ * rfbCopyRegion. Args are src and dst regions plus a translation (dx,dy). -+ * Takes these args together with the existing modified region and possibly an -+ * existing copy region and translation. Produces a combined modified region -+ * plus copy region and translation. Note that the copy region is the -+ * destination of the copy. -+ * -+ * First we trim parts of src which are invalid (ie in the modified region). -+ * Then we see if there is any overlap between the src and the existing copy -+ * region. If not then the two copies cannot be combined, so we choose -+ * whichever is bigger to form the basis of a new copy, while the other copy is -+ * just done the hard way by being added to the modified region. So if the -+ * existing copy is bigger then we simply add the destination of the new copy -+ * to the modified region and we're done. If the new copy is bigger, we add -+ * the old copy region to the modified region and behave as though there is no -+ * existing copy region. -+ * -+ * At this stage we now know that either the two copies can be combined, or -+ * that there is no existing copy. We temporarily add both the existing copy -+ * region and dst to the modified region (this is the entire area of the screen -+ * affected in any way). Finally we calculate the new copy region, and remove -+ * it from the modified region. -+ * -+ * Note: -+ * 1. The src region is modified by this routine. -+ * 2. When the copy region is empty, copyDX and copyDY MUST be set to zero. -+ */ -+ -+static void -+rfbCopyRegion(ScreenPtr pScreen, rfbClientPtr cl, -+ RegionPtr src, RegionPtr dst, -+ int dx, int dy) -+{ -+ RegionRec tmp; -+ -+ /* src = src - modifiedRegion */ -+ -+ REGION_SUBTRACT(pScreen, src, src, &cl->modifiedRegion); -+ -+ if (REGION_NOTEMPTY(pScreen, &cl->copyRegion)) { -+ -+ REGION_NULL(pScreen, &tmp); -+ REGION_INTERSECT(pScreen, &tmp, src, &cl->copyRegion); -+ -+ if (REGION_NOTEMPTY(pScreen, &tmp)) { -+ -+ /* if src and copyRegion overlap: -+ src = src intersect copyRegion */ -+ -+ REGION_COPY(pScreen, src, &tmp); -+ -+ } else { -+ -+ /* if no overlap, find bigger region */ -+ -+ int newArea = (((REGION_EXTENTS(pScreen,src))->x2 -+ - (REGION_EXTENTS(pScreen,src))->x1) -+ * ((REGION_EXTENTS(pScreen,src))->y2 -+ - (REGION_EXTENTS(pScreen,src))->y1)); -+ -+ int oldArea = (((REGION_EXTENTS(pScreen,&cl->copyRegion))->x2 -+ - (REGION_EXTENTS(pScreen,&cl->copyRegion))->x1) -+ * ((REGION_EXTENTS(pScreen,&cl->copyRegion))->y2 -+ - (REGION_EXTENTS(pScreen,&cl->copyRegion))->y1)); -+ -+ if (oldArea > newArea) { -+ -+ /* existing copy is bigger: -+ modifiedRegion = modifiedRegion union dst -+ copyRegion = copyRegion - dst -+ return */ -+ -+ REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, -+ dst); -+ REGION_SUBTRACT(pScreen, &cl->copyRegion, &cl->copyRegion, -+ dst); -+ if (!REGION_NOTEMPTY(pScreen, &cl->copyRegion)) { -+ cl->copyDX = 0; -+ cl->copyDY = 0; -+ } -+ return; -+ } -+ -+ /* new copy is bigger: -+ modifiedRegion = modifiedRegion union copyRegion -+ copyRegion = empty */ -+ -+ REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, -+ &cl->copyRegion); -+ REGION_EMPTY(pScreen, &cl->copyRegion); -+ cl->copyDX = cl->copyDY = 0; -+ } -+ } -+ -+ -+ /* modifiedRegion = modifiedRegion union dst union copyRegion */ -+ -+ REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, dst); -+ REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, -+ &cl->copyRegion); -+ -+ /* copyRegion = T(src) intersect dst */ -+ -+ REGION_TRANSLATE(pScreen, src, dx, dy); -+ REGION_INTERSECT(pScreen, &cl->copyRegion, src, dst); -+ -+ /* modifiedRegion = modifiedRegion - copyRegion */ -+ -+ REGION_SUBTRACT(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, -+ &cl->copyRegion); -+ -+ /* combine new translation T with existing translation */ -+ -+ if (REGION_NOTEMPTY(pScreen, &cl->copyRegion)) { -+ cl->copyDX += dx; -+ cl->copyDY += dy; -+ } else { -+ cl->copyDX = 0; -+ cl->copyDY = 0; -+ } -+} -+ -+ -+/* -+ * rfbDeferredUpdateCallback() is called when a client's deferredUpdateTimer -+ * goes off. -+ */ -+ -+static CARD32 -+rfbDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg) -+{ -+ rfbClientPtr cl = (rfbClientPtr)arg; -+ -+ rfbSendFramebufferUpdate(cl->pScreen, cl); -+ -+ cl->deferredUpdateScheduled = FALSE; -+ return 0; -+} -+ -+ -+/* -+ * rfbScheduleDeferredUpdate() is called from the SCHEDULE_FB_UPDATE macro -+ * to schedule an update. -+ */ -+ -+static void -+rfbScheduleDeferredUpdate(ScreenPtr pScreen, rfbClientPtr cl) -+{ -+ if (rfbDeferUpdateTime != 0) { -+ cl->deferredUpdateTimer = TimerSet(cl->deferredUpdateTimer, 0, -+ rfbDeferUpdateTime, -+ rfbDeferredUpdateCallback, cl); -+ cl->deferredUpdateScheduled = TRUE; -+ } else { -+ rfbSendFramebufferUpdate(pScreen, cl); -+ } -+} -+ -+ -+/* -+ * PrintRegion is useful for debugging. -+ */ -+ -+#ifdef DEBUG -+static void -+PrintRegion(ScreenPtr pScreen, RegionPtr reg) -+{ -+ int nrects = REGION_NUM_RECTS(reg); -+ int i; -+ -+ ErrorF("Region num rects %d extents %d,%d %d,%d\n",nrects, -+ (REGION_EXTENTS(pScreen,reg))->x1, -+ (REGION_EXTENTS(pScreen,reg))->y1, -+ (REGION_EXTENTS(pScreen,reg))->x2, -+ (REGION_EXTENTS(pScreen,reg))->y2); -+ -+ for (i = 0; i < nrects; i++) { -+ ErrorF(" rect %d,%d %dx%d\n", -+ REGION_RECTS(reg)[i].x1, -+ REGION_RECTS(reg)[i].y1, -+ REGION_RECTS(reg)[i].x2-REGION_RECTS(reg)[i].x1, -+ REGION_RECTS(reg)[i].y2-REGION_RECTS(reg)[i].y1); -+ } -+} -+#endif -+ -+/** -+ * Allow scheduling updates from other functions in other files. -+ */ -+void -+rfbScheduleUpdate(ScreenPtr pScreen) -+{ -+ VNCSCREENPTR(pScreen); -+ SCHEDULE_FB_UPDATE(pScreen, pVNC); -+} -diff -pruN xorg-server-1.12.1.orig/hw/vnc/hextile.c xorg-server-1.12.1/hw/vnc/hextile.c ---- xorg-server-1.12.1.orig/hw/vnc/hextile.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/hextile.c 2012-04-18 14:45:21.575820967 -0500 -@@ -0,0 +1,341 @@ -+/* -+ * hextile.c -+ * -+ * Routines to implement Hextile Encoding -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#include -+#include "rfb.h" -+ -+static Bool sendHextiles8(rfbClientPtr cl, int x, int y, int w, int h); -+static Bool sendHextiles16(rfbClientPtr cl, int x, int y, int w, int h); -+static Bool sendHextiles32(rfbClientPtr cl, int x, int y, int w, int h); -+ -+ -+/* -+ * rfbSendRectEncodingHextile - send a rectangle using hextile encoding. -+ */ -+ -+Bool -+rfbSendRectEncodingHextile(rfbClientPtr cl, int x, int y, int w, int h) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ rfbFramebufferUpdateRectHeader rect; -+ -+ if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ rect.r.x = Swap16IfLE(x); -+ rect.r.y = Swap16IfLE(y); -+ rect.r.w = Swap16IfLE(w); -+ rect.r.h = Swap16IfLE(h); -+ rect.encoding = Swap32IfLE(rfbEncodingHextile); -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect, -+ sz_rfbFramebufferUpdateRectHeader); -+ pVNC->ublen += sz_rfbFramebufferUpdateRectHeader; -+ -+ cl->rfbRectanglesSent[rfbEncodingHextile]++; -+ cl->rfbBytesSent[rfbEncodingHextile] += sz_rfbFramebufferUpdateRectHeader; -+ -+ switch (cl->format.bitsPerPixel) { -+ case 8: -+ return sendHextiles8(cl, x, y, w, h); -+ case 16: -+ return sendHextiles16(cl, x, y, w, h); -+ case 32: -+ return sendHextiles32(cl, x, y, w, h); -+ } -+ -+ rfbLog("rfbSendRectEncodingHextile: bpp %d?\n", cl->format.bitsPerPixel); -+ return FALSE; -+} -+ -+ -+#define PUT_PIXEL8(pix) (pVNC->updateBuf[pVNC->ublen++] = (pix)) -+ -+#define PUT_PIXEL16(pix) (pVNC->updateBuf[pVNC->ublen++] = ((char*)&(pix))[0], \ -+ pVNC->updateBuf[pVNC->ublen++] = ((char*)&(pix))[1]) -+ -+#define PUT_PIXEL32(pix) (pVNC->updateBuf[pVNC->ublen++] = ((char*)&(pix))[0], \ -+ pVNC->updateBuf[pVNC->ublen++] = ((char*)&(pix))[1], \ -+ pVNC->updateBuf[pVNC->ublen++] = ((char*)&(pix))[2], \ -+ pVNC->updateBuf[pVNC->ublen++] = ((char*)&(pix))[3]) -+ -+ -+#define DEFINE_SEND_HEXTILES(bpp) \ -+ \ -+ \ -+static Bool subrectEncode##bpp(ScreenPtr pScreen, CARD##bpp *data, int w, \ -+ int h, CARD##bpp bg, \ -+ CARD##bpp fg, Bool mono); \ -+static void testColours##bpp(CARD##bpp *data, int size, Bool *mono, \ -+ Bool *solid, CARD##bpp *bg, CARD##bpp *fg); \ -+ \ -+ \ -+/* \ -+ * rfbSendHextiles \ -+ */ \ -+ \ -+static Bool \ -+sendHextiles##bpp(rfbClientPtr cl, int rx, int ry, int rw, int rh) \ -+{ \ -+ VNCSCREENPTR(cl->pScreen); \ -+ int x, y, w, h; \ -+ int startUblen; \ -+ CARD##bpp bg = 0, fg = 0, newBg, newFg; \ -+ Bool mono, solid; \ -+ Bool validBg = FALSE; \ -+ Bool validFg = FALSE; \ -+ CARD##bpp clientPixelData[16*16*(bpp/8)]; \ -+ \ -+ for (y = ry; y < ry+rh; y += 16) { \ -+ for (x = rx; x < rx+rw; x += 16) { \ -+ w = h = 16; \ -+ if (rx+rw - x < 16) \ -+ w = rx+rw - x; \ -+ if (ry+rh - y < 16) \ -+ h = ry+rh - y; \ -+ \ -+ if ((pVNC->ublen + 1 + (2 + 16 * 16) * (bpp/8)) > UPDATE_BUF_SIZE) { \ -+ if (!rfbSendUpdateBuf(cl)) \ -+ return FALSE; \ -+ } \ -+ \ -+ (*cl->translateFn)(cl->pScreen, cl->translateLookupTable, \ -+ &pVNC->rfbServerFormat, \ -+ &cl->format, (unsigned char *)clientPixelData, \ -+ pVNC->paddedWidthInBytes, w, h, x, y); \ -+ \ -+ startUblen = pVNC->ublen; \ -+ pVNC->updateBuf[startUblen] = 0; \ -+ pVNC->ublen++; \ -+ \ -+ testColours##bpp(clientPixelData, w * h, \ -+ &mono, &solid, &newBg, &newFg); \ -+ \ -+ if (!validBg || (newBg != bg)) { \ -+ validBg = TRUE; \ -+ bg = newBg; \ -+ pVNC->updateBuf[startUblen] |= rfbHextileBackgroundSpecified; \ -+ PUT_PIXEL##bpp(bg); \ -+ } \ -+ \ -+ if (solid) { \ -+ cl->rfbBytesSent[rfbEncodingHextile] += pVNC->ublen - startUblen; \ -+ continue; \ -+ } \ -+ \ -+ pVNC->updateBuf[startUblen] |= rfbHextileAnySubrects; \ -+ \ -+ if (mono) { \ -+ if (!validFg || (newFg != fg)) { \ -+ validFg = TRUE; \ -+ fg = newFg; \ -+ pVNC->updateBuf[startUblen] |= rfbHextileForegroundSpecified; \ -+ PUT_PIXEL##bpp(fg); \ -+ } \ -+ } else { \ -+ validFg = FALSE; \ -+ pVNC->updateBuf[startUblen] |= rfbHextileSubrectsColoured; \ -+ } \ -+ \ -+ if (!subrectEncode##bpp(cl->pScreen, clientPixelData, w, h, bg, fg, mono)) { \ -+ /* encoding was too large, use raw */ \ -+ validBg = FALSE; \ -+ validFg = FALSE; \ -+ pVNC->ublen = startUblen; \ -+ pVNC->updateBuf[pVNC->ublen++] = rfbHextileRaw; \ -+ (*cl->translateFn)(cl->pScreen, cl->translateLookupTable, \ -+ &pVNC->rfbServerFormat, &cl->format, \ -+ (unsigned char *)clientPixelData, \ -+ pVNC->paddedWidthInBytes, w, h, x, y); \ -+ \ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)clientPixelData,\ -+ w * h * (bpp/8)); \ -+ \ -+ pVNC->ublen += w * h * (bpp/8); \ -+ } \ -+ \ -+ cl->rfbBytesSent[rfbEncodingHextile] += pVNC->ublen - startUblen; \ -+ } \ -+ } \ -+ \ -+ return TRUE; \ -+} \ -+ \ -+ \ -+static Bool \ -+subrectEncode##bpp(ScreenPtr pScreen, CARD##bpp *data, int w, int h, \ -+ CARD##bpp bg, CARD##bpp fg, Bool mono) \ -+{ \ -+ VNCSCREENPTR(pScreen); \ -+ CARD##bpp clientdata; \ -+ int x,y; \ -+ int i,j; \ -+ int hx=0,hy,vx=0,vy; \ -+ int hyflag; \ -+ CARD##bpp *seg; \ -+ CARD##bpp *line; \ -+ int hw,hh,vw,vh; \ -+ int thex,they,thew,theh; \ -+ int numsubs = 0; \ -+ int newLen; \ -+ int nSubrectsUblen; \ -+ \ -+ nSubrectsUblen = pVNC->ublen; \ -+ pVNC->ublen++; \ -+ \ -+ for (y=0; y 0) && (i >= hx)) { \ -+ hy += 1; \ -+ } else { \ -+ hyflag = 0; \ -+ } \ -+ } \ -+ vy = j-1; \ -+ \ -+ /* We now have two possible subrects: (x,y,hx,hy) and \ -+ * (x,y,vx,vy). We'll choose the bigger of the two. \ -+ */ \ -+ hw = hx-x+1; \ -+ hh = hy-y+1; \ -+ vw = vx-x+1; \ -+ vh = vy-y+1; \ -+ \ -+ thex = x; \ -+ they = y; \ -+ \ -+ if ((hw*hh) > (vw*vh)) { \ -+ thew = hw; \ -+ theh = hh; \ -+ } else { \ -+ thew = vw; \ -+ theh = vh; \ -+ } \ -+ \ -+ if (mono) { \ -+ newLen = pVNC->ublen - nSubrectsUblen + 2; \ -+ } else { \ -+ newLen = pVNC->ublen - nSubrectsUblen + bpp/8 + 2; \ -+ } \ -+ \ -+ if (newLen > (w * h * (bpp/8))) \ -+ return FALSE; \ -+ \ -+ numsubs += 1; \ -+ \ -+ if (!mono) PUT_PIXEL##bpp(clientdata); \ -+ \ -+ pVNC->updateBuf[pVNC->ublen++] = rfbHextilePackXY(thex,they); \ -+ pVNC->updateBuf[pVNC->ublen++] = rfbHextilePackWH(thew,theh); \ -+ \ -+ /* \ -+ * Now mark the subrect as done. \ -+ */ \ -+ for (j=they; j < (they+theh); j++) { \ -+ for (i=thex; i < (thex+thew); i++) { \ -+ data[j*w+i] = bg; \ -+ } \ -+ } \ -+ } \ -+ } \ -+ } \ -+ \ -+ pVNC->updateBuf[nSubrectsUblen] = numsubs; \ -+ \ -+ return TRUE; \ -+} \ -+ \ -+ \ -+/* \ -+ * testColours() tests if there are one (solid), two (mono) or more \ -+ * colours in a tile and gets a reasonable guess at the best background \ -+ * pixel, and the foreground pixel for mono. \ -+ */ \ -+ \ -+static void \ -+testColours##bpp(CARD##bpp *data, int size, Bool *mono, Bool *solid, \ -+ CARD##bpp *bg, CARD##bpp *fg) \ -+{ \ -+ CARD##bpp colour1 = 0, colour2 = 0; \ -+ int n1 = 0, n2 = 0; \ -+ *mono = TRUE; \ -+ *solid = TRUE; \ -+ \ -+ for (; size > 0; size--, data++) { \ -+ \ -+ if (n1 == 0) \ -+ colour1 = *data; \ -+ \ -+ if (*data == colour1) { \ -+ n1++; \ -+ continue; \ -+ } \ -+ \ -+ if (n2 == 0) { \ -+ *solid = FALSE; \ -+ colour2 = *data; \ -+ } \ -+ \ -+ if (*data == colour2) { \ -+ n2++; \ -+ continue; \ -+ } \ -+ \ -+ *mono = FALSE; \ -+ break; \ -+ } \ -+ \ -+ if (n1 > n2) { \ -+ *bg = colour1; \ -+ *fg = colour2; \ -+ } else { \ -+ *bg = colour2; \ -+ *fg = colour1; \ -+ } \ -+} -+ -+DEFINE_SEND_HEXTILES(8) -+DEFINE_SEND_HEXTILES(16) -+DEFINE_SEND_HEXTILES(32) -diff -pruN xorg-server-1.12.1.orig/hw/vnc/httpd.c xorg-server-1.12.1/hw/vnc/httpd.c ---- xorg-server-1.12.1.orig/hw/vnc/httpd.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/httpd.c 2012-04-18 14:45:21.575820967 -0500 -@@ -0,0 +1,519 @@ -+/* -+ * httpd.c - a simple HTTP server -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * Copyright (C) 2002 Constantin Kaplinsky. All Rights Reserved. -+ * 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifndef USE_LIBWRAP -+#define USE_LIBWRAP 0 -+#endif -+#if USE_LIBWRAP -+#include -+#endif -+ -+#include "rfb.h" -+ -+#define NOT_FOUND_STR "HTTP/1.0 404 Not found\r\n\r\n" \ -+ "File Not Found\n" \ -+ "

File Not Found

\n" -+ -+#define OK_STR "HTTP/1.0 200 OK\r\n\r\n" -+ -+static void httpProcessInput(ScreenPtr pScreen); -+static Bool compareAndSkip(char **ptr, const char *str); -+static Bool parseParams(const char *request, char *result, int max_bytes); -+static Bool validateString(char *str); -+ -+/* -+ * httpInitSockets sets up the TCP socket to listen for HTTP connections. -+ */ -+ -+Bool -+httpInitSockets(ScreenPtr pScreen) -+{ -+ VNCSCREENPTR(pScreen); -+ -+ if (!pVNC->httpDir) -+ return FALSE; -+ -+ pVNC->buf_filled = 0; -+ -+ if (pVNC->httpPort == 0) { -+ pVNC->httpPort = 5800 + atoi(display) + pScreen->myNum; -+ } -+ -+ if ((pVNC->httpListenSock = ListenOnTCPPort(pScreen, pVNC->httpPort)) < 0) { -+ rfbLog("ListenOnTCPPort %d failed\n",pVNC->httpPort); -+ pVNC->httpPort = 0; -+ return FALSE; -+ } -+ -+ rfbLog("Listening for HTTP connections on TCP port %d\n", pVNC->httpPort); -+ rfbLog(" URL http://%s:%d\n",rfbThisHost,pVNC->httpPort); -+ -+ AddEnabledDevice(pVNC->httpListenSock); -+ -+ return TRUE; -+} -+ -+ -+/* -+ * httpCheckFds is called from ProcessInputEvents to check for input on the -+ * HTTP socket(s). If there is input to process, httpProcessInput is called. -+ */ -+ -+void -+httpCheckFds(ScreenPtr pScreen) -+{ -+ VNCSCREENPTR(pScreen); -+ int nfds; -+ fd_set fds; -+ struct timeval tv; -+ struct sockaddr_in addr; -+ SOCKLEN_T addrlen = sizeof(addr); -+ -+ if (!pVNC->httpDir) -+ return; -+ -+ FD_ZERO(&fds); -+ FD_SET(pVNC->httpListenSock, &fds); -+ if (pVNC->httpSock >= 0) { -+ FD_SET(pVNC->httpSock, &fds); -+ } -+ tv.tv_sec = 0; -+ tv.tv_usec = 0; -+ nfds = select(max(pVNC->httpSock,pVNC->httpListenSock) + 1, &fds, NULL, NULL, &tv); -+ if (nfds == 0) { -+ return; -+ } -+ if (nfds < 0) { -+ if (errno != EINTR) -+ rfbLogPerror("httpCheckFds: select"); -+ return; -+ } -+ -+ if ((pVNC->httpSock >= 0) && FD_ISSET(pVNC->httpSock, &fds)) { -+ httpProcessInput(pScreen); -+ } -+ -+ if (FD_ISSET(pVNC->httpListenSock, &fds)) { -+ int flags; -+ -+ if (pVNC->httpSock >= 0) close(pVNC->httpSock); -+ -+ if ((pVNC->httpSock = accept(pVNC->httpListenSock, -+ (struct sockaddr *)&addr, &addrlen)) < 0) { -+ rfbLogPerror("httpCheckFds: accept"); -+ return; -+ } -+ -+#if USE_LIBWRAP -+ if (!hosts_ctl("Xvnc", STRING_UNKNOWN, inet_ntoa(addr.sin_addr), -+ STRING_UNKNOWN)) { -+ rfbLog("Rejected HTTP connection from client %s\n", -+ inet_ntoa(addr.sin_addr)); -+ close(pVNC->httpSock); -+ pVNC->httpSock = -1; -+ return; -+ } -+#endif -+ -+ flags = fcntl (pVNC->httpSock, F_GETFL); -+ -+ if (flags == -1 || -+ fcntl (pVNC->httpSock, F_SETFL, flags | O_NONBLOCK) == -1) { -+ rfbLogPerror("httpCheckFds: fcntl"); -+ close (pVNC->httpSock); -+ pVNC->httpSock = -1; -+ return; -+ } -+ -+ AddEnabledDevice(pVNC->httpSock); -+ } -+} -+ -+ -+static void -+httpCloseSock(ScreenPtr pScreen) -+{ -+ VNCSCREENPTR(pScreen); -+ close(pVNC->httpSock); -+ RemoveEnabledDevice(pVNC->httpSock); -+ pVNC->httpSock = -1; -+ pVNC->buf_filled = 0; -+} -+ -+ -+/* -+ * httpProcessInput is called when input is received on the HTTP socket. -+ */ -+ -+static void -+httpProcessInput(ScreenPtr pScreen) -+{ -+ VNCSCREENPTR(pScreen); -+ struct sockaddr_in addr; -+ SOCKLEN_T addrlen = sizeof(addr); -+ char fullFname[512]; -+ char params[1024]; -+ char *ptr; -+ char *fname; -+ int maxFnameLen; -+ int fd; -+ Bool performSubstitutions = FALSE; -+ char str[256]; -+ struct passwd *user = getpwuid(getuid()); -+ -+ if (strlen(pVNC->httpDir) > 255) { -+ rfbLog("-httpd directory too long\n"); -+ httpCloseSock(pScreen); -+ return; -+ } -+ strcpy(fullFname, pVNC->httpDir); -+ fname = &fullFname[strlen(fullFname)]; -+ maxFnameLen = 511 - strlen(fullFname); -+ -+ /* Read data from the HTTP client until we get a complete request. */ -+ while (1) { -+ ssize_t got = read (pVNC->httpSock, pVNC->buf + pVNC->buf_filled, -+ sizeof (pVNC->buf) - pVNC->buf_filled - 1); -+ -+ if (got <= 0) { -+ if (got == 0) { -+ rfbLog("httpd: premature connection close\n"); -+ } else { -+ if (errno == EAGAIN) { -+ return; -+ } -+ rfbLogPerror("httpProcessInput: read"); -+ } -+ httpCloseSock(pScreen); -+ return; -+ } -+ -+ pVNC->buf_filled += got; -+ pVNC->buf[pVNC->buf_filled] = '\0'; -+ -+ /* Is it complete yet (is there a blank line)? */ -+ if (strstr (pVNC->buf, "\r\r") || strstr (pVNC->buf, "\n\n") || -+ strstr (pVNC->buf, "\r\n\r\n") || strstr (pVNC->buf, "\n\r\n\r")) -+ break; -+ } -+ -+ /* Process the request. */ -+ if (strncmp(pVNC->buf, "GET ", 4)) { -+ rfbLog("httpd: no GET line\n"); -+ httpCloseSock(pScreen); -+ return; -+ } else { -+ /* Only use the first line. */ -+ pVNC->buf[strcspn(pVNC->buf, "\n\r")] = '\0'; -+ } -+ -+ if (strlen(pVNC->buf) > maxFnameLen) { -+ rfbLog("httpd: GET line too long\n"); -+ httpCloseSock(pScreen); -+ return; -+ } -+ -+ if (sscanf(pVNC->buf, "GET %s HTTP/1.0", fname) != 1) { -+ rfbLog("httpd: couldn't parse GET line\n"); -+ httpCloseSock(pScreen); -+ return; -+ } -+ -+ if (fname[0] != '/') { -+ rfbLog("httpd: filename didn't begin with '/'\n"); -+ WriteExact(pVNC->httpSock, NOT_FOUND_STR, strlen(NOT_FOUND_STR)); -+ httpCloseSock(pScreen); -+ return; -+ } -+ -+ if (strchr(fname+1, '/') != NULL) { -+ rfbLog("httpd: asking for file in other directory\n"); -+ WriteExact(pVNC->httpSock, NOT_FOUND_STR, strlen(NOT_FOUND_STR)); -+ httpCloseSock(pScreen); -+ return; -+ } -+ -+ getpeername(pVNC->httpSock, (struct sockaddr *)&addr, &addrlen); -+ rfbLog("httpd: get '%s' for %s\n", fname+1, -+ inet_ntoa(addr.sin_addr)); -+ -+ /* Extract parameters from the URL string if necessary */ -+ -+ params[0] = '\0'; -+ ptr = strchr(fname, '?'); -+ if (ptr != NULL) { -+ *ptr = '\0'; -+ if (!parseParams(&ptr[1], params, 1024)) { -+ params[0] = '\0'; -+ rfbLog("httpd: bad parameters in the URL\n"); -+ } -+ } -+ -+ /* If we were asked for '/', actually read the file index.vnc */ -+ -+ if (strcmp(fname, "/") == 0) { -+ strcpy(fname, "/index.vnc"); -+ rfbLog("httpd: defaulting to '%s'\n", fname+1); -+ } -+ -+ /* Substitutions are performed on files ending .vnc */ -+ -+ if (strlen(fname) >= 4 && strcmp(&fname[strlen(fname)-4], ".vnc") == 0) { -+ performSubstitutions = TRUE; -+ } -+ -+ /* Open the file */ -+ -+ if ((fd = open(fullFname, O_RDONLY)) < 0) { -+ rfbLogPerror("httpProcessInput: open"); -+ WriteExact(pVNC->httpSock, NOT_FOUND_STR, strlen(NOT_FOUND_STR)); -+ httpCloseSock(pScreen); -+ return; -+ } -+ -+ WriteExact(pVNC->httpSock, OK_STR, strlen(OK_STR)); -+ -+ while (1) { -+ int n = read(fd, pVNC->buf, HTTP_BUF_SIZE-1); -+ if (n < 0) { -+ rfbLogPerror("httpProcessInput: read"); -+ close(fd); -+ httpCloseSock(pScreen); -+ return; -+ } -+ -+ if (n == 0) -+ break; -+ -+ if (performSubstitutions) { -+ -+ /* Substitute $WIDTH, $HEIGHT, etc with the appropriate values. -+ This won't quite work properly if the .vnc file is longer than -+ HTTP_BUF_SIZE, but it's reasonable to assume that .vnc files will -+ always be short. */ -+ -+ char *ptr = pVNC->buf; -+ char *dollar; -+ pVNC->buf[n] = 0; /* make sure it's null-terminated */ -+ -+ while ((dollar = strchr(ptr, '$'))) { -+ WriteExact(pVNC->httpSock, ptr, (dollar - ptr)); -+ -+ ptr = dollar; -+ -+ if (compareAndSkip(&ptr, "$WIDTH")) { -+ -+ sprintf(str, "%d", pVNC->width); -+ WriteExact(pVNC->httpSock, str, strlen(str)); -+ -+ } else if (compareAndSkip(&ptr, "$HEIGHT")) { -+ -+ sprintf(str, "%d", pVNC->height); -+ WriteExact(pVNC->httpSock, str, strlen(str)); -+ -+ } else if (compareAndSkip(&ptr, "$APPLETWIDTH")) { -+ -+ sprintf(str, "%d", pVNC->width); -+ WriteExact(pVNC->httpSock, str, strlen(str)); -+ -+ } else if (compareAndSkip(&ptr, "$APPLETHEIGHT")) { -+ -+ sprintf(str, "%d", pVNC->height + 32); -+ WriteExact(pVNC->httpSock, str, strlen(str)); -+ -+ } else if (compareAndSkip(&ptr, "$PORT")) { -+ -+ sprintf(str, "%d", pVNC->rfbPort); -+ WriteExact(pVNC->httpSock, str, strlen(str)); -+ -+ } else if (compareAndSkip(&ptr, "$DESKTOP")) { -+ -+ WriteExact(pVNC->httpSock, desktopName, strlen(desktopName)); -+ -+ } else if (compareAndSkip(&ptr, "$DISPLAY")) { -+ -+ sprintf(str, "%s:%s", rfbThisHost, display); -+ WriteExact(pVNC->httpSock, str, strlen(str)); -+ -+ } else if (compareAndSkip(&ptr, "$USER")) { -+ -+ if (user) { -+ WriteExact(pVNC->httpSock, user->pw_name, -+ strlen(user->pw_name)); -+ } else { -+ WriteExact(pVNC->httpSock, "?", 1); -+ } -+ -+ } else if (compareAndSkip(&ptr, "$PARAMS")) { -+ -+ if (params[0] != '\0') -+ WriteExact(pVNC->httpSock, params, strlen(params)); -+ -+ } else { -+ if (!compareAndSkip(&ptr, "$$")) -+ ptr++; -+ -+ if (WriteExact(pVNC->httpSock, "$", 1) < 0) { -+ close(fd); -+ httpCloseSock(pScreen); -+ return; -+ } -+ } -+ } -+ if (WriteExact(pVNC->httpSock, ptr, (&pVNC->buf[n] - ptr)) < 0) -+ break; -+ -+ } else { -+ -+ /* For files not ending .vnc, just write out the buffer */ -+ -+ if (WriteExact(pVNC->httpSock, pVNC->buf, n) < 0) -+ break; -+ } -+ } -+ -+ close(fd); -+ httpCloseSock(pScreen); -+} -+ -+ -+static Bool -+compareAndSkip(char **ptr, const char *str) -+{ -+ if (strncmp(*ptr, str, strlen(str)) == 0) { -+ *ptr += strlen(str); -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+/* -+ * Parse the request tail after the '?' character, and format a sequence -+ * of tags for inclusion into an HTML page with embedded applet. -+ */ -+ -+static Bool -+parseParams(const char *request, char *result, int max_bytes) -+{ -+ char param_request[128]; -+ char param_formatted[196]; -+ const char *tail; -+ char *delim_ptr; -+ char *value_str; -+ int cur_bytes, len; -+ -+ result[0] = '\0'; -+ cur_bytes = 0; -+ -+ tail = request; -+ for (;;) { -+ /* Copy individual "name=value" string into a buffer */ -+ delim_ptr = strchr((char *)tail, '&'); -+ if (delim_ptr == NULL) { -+ if (strlen(tail) >= sizeof(param_request)) { -+ return FALSE; -+ } -+ strcpy(param_request, tail); -+ } else { -+ len = delim_ptr - tail; -+ if (len >= sizeof(param_request)) { -+ return FALSE; -+ } -+ memcpy(param_request, tail, len); -+ param_request[len] = '\0'; -+ } -+ -+ /* Split the request into parameter name and value */ -+ value_str = strchr(¶m_request[1], '='); -+ if (value_str == NULL) { -+ return FALSE; -+ } -+ *value_str++ = '\0'; -+ if (strlen(value_str) == 0) { -+ return FALSE; -+ } -+ -+ /* Validate both parameter name and value */ -+ if (!validateString(param_request) || !validateString(value_str)) { -+ return FALSE; -+ } -+ -+ /* Prepare HTML-formatted representation of the name=value pair */ -+ len = sprintf(param_formatted, -+ "\n", -+ param_request, value_str); -+ if (cur_bytes + len + 1 > max_bytes) { -+ return FALSE; -+ } -+ strcat(result, param_formatted); -+ cur_bytes += len; -+ -+ /* Go to the next parameter */ -+ if (delim_ptr == NULL) { -+ break; -+ } -+ tail = delim_ptr + 1; -+ } -+ return TRUE; -+} -+ -+/* -+ * Check if the string consists only of alphanumeric characters, '+' -+ * signs, underscores, and dots. Replace all '+' signs with spaces. -+ */ -+ -+static Bool -+validateString(char *str) -+{ -+ char *ptr; -+ -+ for (ptr = str; *ptr != '\0'; ptr++) { -+ if (!isalnum(*ptr) && *ptr != '_' && *ptr != '.') { -+ if (*ptr == '+') { -+ *ptr = ' '; -+ } else { -+ return FALSE; -+ } -+ } -+ } -+ return TRUE; -+} -+ -diff -pruN xorg-server-1.12.1.orig/hw/vnc/init.c xorg-server-1.12.1/hw/vnc/init.c ---- xorg-server-1.12.1.orig/hw/vnc/init.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/init.c 2012-04-18 15:57:06.373003593 -0500 -@@ -0,0 +1,1054 @@ -+/* -+ * init.c -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+ -+/* -+ -+Copyright (c) 1993 X Consortium -+ -+Permission is hereby granted, free of charge, to any person obtaining -+a copy of this software and associated documentation files (the -+"Software"), to deal in the Software without restriction, including -+without limitation the rights to use, copy, modify, merge, publish, -+distribute, sublicense, and/or sell copies of the Software, and to -+permit persons to whom the Software is furnished to do so, subject to -+the following conditions: -+ -+The above copyright notice and this permission notice shall be included -+in all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR -+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+OTHER DEALINGS IN THE SOFTWARE. -+ -+Except as contained in this notice, the name of the X Consortium shall -+not be used in advertising or otherwise to promote the sale, use or -+other dealings in this Software without prior written authorization -+from the X Consortium. -+ -+*/ -+ -+/* Use ``#define CORBA'' to enable CORBA control interface */ -+ -+/* XXX this definition should probably go elsewhere */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#ifndef XVNCRELEASE -+#define XVNCRELEASE "X.org/xf4vnc custom version" -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "X11/X.h" -+#define NEED_EVENTS -+#include "X11/Xproto.h" -+#include "X11/Xos.h" -+#include "scrnintstr.h" -+#include "servermd.h" -+#include "fb.h" -+#include "mibstore.h" -+#include "colormapst.h" -+#include "gcstruct.h" -+#include "input.h" -+#include "mipointer.h" -+#include "dixstruct.h" -+#include -+#include -+#include -+#include "dix.h" -+#include "micmap.h" -+#include "rfb.h" -+#include "xserver-properties.h" -+#include "exevents.h" -+ -+#ifdef CORBA -+#include -+#endif -+ -+#define RFB_DEFAULT_WIDTH 640 -+#define RFB_DEFAULT_HEIGHT 480 -+#define RFB_DEFAULT_DEPTH 8 -+#define RFB_DEFAULT_WHITEPIXEL 0 -+#define RFB_DEFAULT_BLACKPIXEL 1 -+ -+static unsigned long VNCGeneration = 0; -+rfbScreenInfo rfbScreen; -+extern char dispatchExceptionAtReset; -+ -+extern void VncExtensionInit(void); -+ -+static Bool initOutputCalled = FALSE; -+static Bool noCursor = FALSE; -+char *desktopName = "x11"; -+ -+char rfbThisHost[256]; -+ -+Atom VNC_LAST_CLIENT_ID; -+Atom VNC_CONNECT; -+ -+#if 0 -+static HWEventQueueType alwaysCheckForInput[2] = { 0, 1 }; -+static HWEventQueueType *mieqCheckForInput[2]; -+#endif -+ -+static char primaryOrder[4] = ""; -+static int redBits, greenBits, blueBits; -+ -+static Bool rfbScreenInit(int index, ScreenPtr pScreen, int argc, -+ char **argv); -+static int rfbKeybdProc(DeviceIntPtr pDevice, int onoff); -+static int rfbMouseProc(DeviceIntPtr pDevice, int onoff); -+static Bool CheckDisplayNumber(int n); -+ -+static Bool rfbAlwaysTrue(void); -+static unsigned char *rfbAllocateFramebufferMemory(rfbScreenInfoPtr prfb); -+static Bool rfbCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y); -+static void rfbCrossScreen(ScreenPtr pScreen, Bool entering); -+ -+ -+ -+static void -+PointerWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) -+{ -+#if 0 -+ DeviceIntPtr pDev = NULL; -+ miPointerSetPosition(pDev, &x, &y, GetTimeInMillis()); -+#endif -+} -+ -+ -+static miPointerScreenFuncRec rfbPointerCursorFuncs = { -+ rfbCursorOffScreen, -+ rfbCrossScreen, -+ PointerWarpCursor, -+ NULL/*dmxeqEnqueue*/, -+ NULL/*dmxeqSwitchScreen*/ -+}; -+ -+ -+int inetdSock = -1; -+static char inetdDisplayNumStr[10]; -+ -+ -+void -+DDXRingBell(int volume, int pitch, int duration) -+{ -+ /* NO-OP - stub to solve link problem */ -+} -+ -+ -+/* -+ * ddxProcessArgument is our first entry point and will be called at the -+ * very start for each argument. It is not called again on server reset. -+ */ -+ -+int -+ddxProcessArgument (int argc, char *argv[], int i) -+{ -+ VNCSCREENPTR(screenInfo.screens[i]); -+ static Bool firstTime = TRUE; -+ -+ if (firstTime) -+ { -+ pVNC->width = RFB_DEFAULT_WIDTH; -+ pVNC->height = RFB_DEFAULT_HEIGHT; -+ pVNC->depth = RFB_DEFAULT_DEPTH; -+ pVNC->blackPixel = RFB_DEFAULT_BLACKPIXEL; -+ pVNC->whitePixel = RFB_DEFAULT_WHITEPIXEL; -+ pVNC->pfbMemory = NULL; -+ pVNC->httpPort = 0; -+ pVNC->httpDir = NULL; -+ pVNC->rfbAuthPasswdFile = NULL; -+ pVNC->udpPort = 0; -+ pVNC->rfbPort = 0; -+ pVNC->rdpPort = 3389; -+ noCursor = FALSE; -+ pVNC->loginAuthEnabled = FALSE; -+ pVNC->rfbAlwaysShared = FALSE; -+ pVNC->rfbNeverShared = FALSE; -+ pVNC->rfbDontDisconnect = FALSE; -+ pVNC->rfbViewOnly = FALSE; -+ -+ gethostname(rfbThisHost, 255); -+ pVNC->interface.s_addr = htonl (INADDR_ANY); -+ firstTime = FALSE; -+ } -+ -+ if (strcmp (argv[i], "-geometry") == 0) /* -geometry WxH */ -+ { -+ if (i + 1 >= argc) UseMsg(); -+ if (sscanf(argv[i+1],"%dx%d", -+ &pVNC->width,&pVNC->height) != 2) { -+ ErrorF("Invalid geometry %s\n", argv[i+1]); -+ UseMsg(); -+ } -+#ifdef CORBA -+ screenWidth= pVNC->width; -+ screenHeight= pVNC->height; -+#endif -+ return 2; -+ } -+ -+ if (strcmp (argv[i], "-depth") == 0) /* -depth D */ -+ { -+ if (i + 1 >= argc) UseMsg(); -+ pVNC->depth = atoi(argv[i+1]); -+#ifdef CORBA -+ screenDepth= pVNC->depth; -+#endif -+ return 2; -+ } -+ -+ if (strcmp (argv[i], "-pixelformat") == 0) { -+ if (i + 1 >= argc) UseMsg(); -+ if (sscanf(argv[i+1], "%3s", primaryOrder) < 1) { -+ ErrorF("Invalid pixel format %s\n", argv[i+1]); -+ UseMsg(); -+ } -+ -+ return 2; -+ } -+ -+ if (strcmp (argv[i], "-blackpixel") == 0) { /* -blackpixel n */ -+ if (i + 1 >= argc) UseMsg(); -+ pVNC->blackPixel = atoi(argv[i+1]); -+ return 2; -+ } -+ -+ if (strcmp (argv[i], "-whitepixel") == 0) { /* -whitepixel n */ -+ if (i + 1 >= argc) UseMsg(); -+ pVNC->whitePixel = atoi(argv[i+1]); -+ return 2; -+ } -+ -+ if (strcmp(argv[i], "-udpinputport") == 0) { /* -udpinputport port */ -+ if (i + 1 >= argc) UseMsg(); -+ pVNC->udpPort = atoi(argv[i+1]); -+ return 2; -+ } -+ -+ if (strcmp(argv[i], "-rfbport") == 0) { /* -rfbport port */ -+ if (i + 1 >= argc) UseMsg(); -+ pVNC->rfbPort = atoi(argv[i+1]); -+ return 2; -+ } -+ -+ if (strcmp(argv[i], "-rfbwait") == 0) { /* -rfbwait ms */ -+ if (i + 1 >= argc) UseMsg(); -+ rfbMaxClientWait = atoi(argv[i+1]); -+ return 2; -+ } -+ -+ if (strcmp(argv[i], "-nocursor") == 0) { -+ noCursor = TRUE; -+ return 1; -+ } -+ -+ if (strcmp(argv[i], "-rfbauth") == 0) { /* -rfbauth passwd-file */ -+ if (i + 1 >= argc) UseMsg(); -+ pVNC->rfbAuthPasswdFile = argv[i+1]; -+ return 2; -+ } -+ -+ if (strcmp(argv[i], "-loginauth") == 0) { -+ if (geteuid() == 0) { -+ /* Only when run as root! */ -+ pVNC->loginAuthEnabled = TRUE; -+ } -+ return 1; -+ } -+ -+ if (strcmp(argv[i], "-httpd") == 0) { -+ if (i + 1 >= argc) UseMsg(); -+ pVNC->httpDir = argv[i+1]; -+ return 2; -+ } -+ -+ if (strcmp(argv[i], "-httpport") == 0) { -+ if (i + 1 >= argc) UseMsg(); -+ pVNC->httpPort = atoi(argv[i+1]); -+ return 2; -+ } -+ -+ if (strcmp(argv[i], "-deferupdate") == 0) { /* -deferupdate ms */ -+ if (i + 1 >= argc) UseMsg(); -+ rfbDeferUpdateTime = atoi(argv[i+1]); -+ return 2; -+ } -+ -+ if (strcmp(argv[i], "-economictranslate") == 0) { -+ rfbEconomicTranslate = TRUE; -+ return 1; -+ } -+ -+ if (strcmp(argv[i], "-lazytight") == 0) { -+ rfbTightDisableGradient = TRUE; -+ return 1; -+ } -+ -+ if (strcmp(argv[i], "-desktop") == 0) { /* -desktop desktop-name */ -+ if (i + 1 >= argc) UseMsg(); -+ desktopName = argv[i+1]; -+ return 2; -+ } -+ -+#if 0 /* not deemed useful on standalone server - leave for completeness */ -+ if (strcmp(argv[i], "-useraccept") == 0) { -+ pVNC->rfbUserAccept = TRUE; -+ return 1; -+ } -+#endif -+ -+ if (strcmp(argv[i], "-alwaysshared") == 0) { -+ pVNC->rfbAlwaysShared = TRUE; -+ return 1; -+ } -+ -+ if (strcmp(argv[i], "-nevershared") == 0) { -+ pVNC->rfbNeverShared = TRUE; -+ return 1; -+ } -+ -+ if (strcmp(argv[i], "-dontdisconnect") == 0) { -+ pVNC->rfbDontDisconnect = TRUE; -+ return 1; -+ } -+ -+ /* Run server in view-only mode - Ehud Karni SW */ -+ if (strcmp(argv[i], "-viewonly") == 0) { -+ pVNC->rfbViewOnly = TRUE; -+ return 1; -+ } -+ -+ if (strcmp(argv[i], "-localhost") == 0) { -+ pVNC->interface.s_addr = htonl (INADDR_LOOPBACK); -+ return 1; -+ } -+ -+ if (strcmp(argv[i], "-interface") == 0) { /* -interface ipaddr */ -+ struct in_addr got; -+ unsigned long octet; -+ char *p, *end; -+ int q; -+ got.s_addr = 0; -+ if (i + 1 >= argc) { -+ UseMsg(); -+ return 2; -+ } -+ if (pVNC->interface.s_addr != htonl (INADDR_ANY)) { -+ /* Already set (-localhost?). */ -+ return 2; -+ } -+ p = argv[i + 1]; -+ for (q = 0; q < 4; q++) { -+ octet = strtoul (p, &end, 10); -+ if (p == end || octet > 255) { -+ UseMsg (); -+ return 2; -+ } -+ if ((q < 3 && *end != '.') || -+ (q == 3 && *end != '\0')) { -+ UseMsg (); -+ return 2; -+ } -+ got.s_addr = (got.s_addr << 8) | octet; -+ p = end + 1; -+ } -+ pVNC->interface.s_addr = htonl (got.s_addr); -+ return 2; -+ } -+ -+ if (strcmp(argv[i], "-inetd") == 0) { /* -inetd */ -+ int n; -+ for (n = 1; n < 100; n++) { -+ if (CheckDisplayNumber(n)) -+ break; -+ } -+ -+ if (n >= 100) -+ FatalError("-inetd: couldn't find free display number"); -+ -+ sprintf(inetdDisplayNumStr, "%d", n); -+ display = inetdDisplayNumStr; -+ -+ /* fds 0, 1 and 2 (stdin, out and err) are all the same socket to the -+ RFB client. OsInit() closes stdout and stdin, and we don't want -+ stderr to go to the RFB client, so make the client socket 3 and -+ close stderr. OsInit() will redirect stderr logging to an -+ appropriate log file or /dev/null if that doesn't work. */ -+ -+ dup2(0,3); -+ inetdSock = 3; -+ close(2); -+ -+ return 1; -+ } -+ -+ if (strcmp(argv[i], "-version") == 0) { -+ ErrorF("Xvnc version %s\n", XVNCRELEASE); -+ exit(0); -+ } -+ -+ if (inetdSock != -1 && argv[i][0] == ':') { -+ FatalError("can't specify both -inetd and :displaynumber"); -+ } -+ -+ return 0; -+} -+ -+ -+/* -+ * InitOutput is called every time the server resets. It should call -+ * AddScreen for each screen (FIXME - but we only ever have one), -+ * and in turn this will call rfbScreenInit. -+ */ -+ -+/* Common pixmap formats */ -+ -+static PixmapFormatRec formats[MAXFORMATS] = { -+ { 1, 1, BITMAP_SCANLINE_PAD }, -+ { 4, 8, BITMAP_SCANLINE_PAD }, -+ { 8, 8, BITMAP_SCANLINE_PAD }, -+ { 15, 16, BITMAP_SCANLINE_PAD }, -+ { 16, 16, BITMAP_SCANLINE_PAD }, -+ { 24, 32, BITMAP_SCANLINE_PAD }, -+#ifdef RENDER -+ { 32, 32, BITMAP_SCANLINE_PAD }, -+#endif -+}; -+#ifdef RENDER -+static int numFormats = 7; -+#else -+static int numFormats = 6; -+#endif -+ -+void -+InitOutput(ScreenInfo *screenInfo, int argc, char **argv) -+{ -+ int i; -+ initOutputCalled = TRUE; -+ -+ rfbLog("Xvnc version %s\n", XVNCRELEASE); -+ rfbLog("Copyright (C) 2001-2004 Alan Hourihane.\n"); -+ rfbLog("Copyright (C) 2000-2004 Constantin Kaplinsky\n"); -+ rfbLog("Copyright (C) 1999 AT&T Laboratories Cambridge\n"); -+ rfbLog("All Rights Reserved.\n"); -+ rfbLog("See http://www.tightvnc.com/ for information on TightVNC\n"); -+ rfbLog("See http://xf4vnc.sf.net for xf4vnc-specific information\n"); -+ rfbLog("Desktop name '%s' (%s:%s)\n",desktopName,rfbThisHost,display); -+ rfbLog("Protocol versions supported: %d.%d, %d.%d\n", -+ rfbProtocolMajorVersion, rfbProtocolMinorVersion, -+ rfbProtocolMajorVersion, rfbProtocolFallbackMinorVersion); -+ -+ VNC_LAST_CLIENT_ID = MakeAtom("VNC_LAST_CLIENT_ID", -+ strlen("VNC_LAST_CLIENT_ID"), TRUE); -+ VNC_CONNECT = MakeAtom("VNC_CONNECT", strlen("VNC_CONNECT"), TRUE); -+ -+ /* initialize pixmap formats */ -+ -+ screenInfo->imageByteOrder = IMAGE_BYTE_ORDER; -+ screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; -+ screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; -+ screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; -+ screenInfo->numPixmapFormats = numFormats; -+ for (i = 0; i < numFormats; i++) -+ screenInfo->formats[i] = formats[i]; -+ -+ /* initialize screen */ -+ -+ if (AddScreen(rfbScreenInit, argc, argv) == -1) { -+ FatalError("Couldn't add screen"); -+ } -+ -+#ifdef CORBA -+ initialiseCORBA(argc, argv, desktopName); -+#endif -+} -+ -+static void -+rfbWakeupHandler ( -+ int i, -+ pointer blockData, -+ unsigned long err, -+ pointer pReadmask -+){ -+ ScreenPtr pScreen = screenInfo.screens[i]; -+ VNCSCREENPTR(pScreen); -+ int e = (int)err; -+ -+ if (e < 0) -+ goto SKIPME; -+ -+ rfbRootPropertyChange(pScreen); -+ -+#if XFREE86VNC -+ if (pScrn->vtSema) { -+ rfbCheckFds(pScreen); -+ httpCheckFds(pScreen); -+#if 0 -+ rdpCheckFds(pScreen); -+#endif -+#ifdef CORBA -+ corbaCheckFds(); -+#endif -+ } else { -+ rfbCheckFds(pScreen); -+#if 0 -+ rdpCheckFds(pScreen); -+#endif -+ } -+#else -+ rfbCheckFds(pScreen); -+ httpCheckFds(pScreen); -+#if 0 -+ rdpCheckFds(pScreen); -+#endif -+#ifdef CORBA -+ corbaCheckFds(); -+#endif -+#endif -+ -+SKIPME: -+ -+ pScreen->WakeupHandler = pVNC->WakeupHandler; -+ (*pScreen->WakeupHandler) (i, blockData, err, pReadmask); -+ pScreen->WakeupHandler = rfbWakeupHandler; -+} -+ -+static Bool -+rfbScreenInit(int index, ScreenPtr pScreen, int argc, char ** argv) -+{ -+ rfbScreenInfoPtr prfb = &rfbScreen; -+ int dpix = 75, dpiy = 75; -+ int ret; -+ unsigned char *pbits; -+ VisualPtr vis; -+#ifdef RENDER -+ PictureScreenPtr ps; -+#endif -+ -+ if (VNCGeneration != serverGeneration) { -+ VncExtensionInit(); -+ VNCGeneration = serverGeneration; -+ } -+ -+ if (monitorResolution != 0) { -+ dpix = monitorResolution; -+ dpiy = monitorResolution; -+ } -+ -+ prfb->rfbAuthTries = 0; -+ prfb->rfbAuthTooManyTries = FALSE; -+ prfb->rfbUserAccept = FALSE; -+ prfb->udpSockConnected = FALSE; -+ prfb->timer = NULL; -+ prfb->httpListenSock = -1; -+ prfb->httpSock = -1; -+ prfb->rfbListenSock = -1; -+ prfb->rdpListenSock = -1; -+ prfb->paddedWidthInBytes = PixmapBytePad(prfb->width, prfb->depth); -+ prfb->bitsPerPixel = rfbBitsPerPixel(prfb->depth); -+ pbits = rfbAllocateFramebufferMemory(prfb); -+ if (!pbits) return FALSE; -+ -+ miClearVisualTypes(); -+ -+ if (defaultColorVisualClass == -1) -+ defaultColorVisualClass = TrueColor; -+ -+ if (!miSetVisualTypes(prfb->depth, miGetDefaultVisualMask(prfb->depth), 8, -+ defaultColorVisualClass) ) -+ return FALSE; -+ -+ miSetPixmapDepths(); -+ -+ switch (prfb->bitsPerPixel) -+ { -+ case 8: -+ ret = fbScreenInit(pScreen, pbits, prfb->width, prfb->height, -+ dpix, dpiy, prfb->paddedWidthInBytes, 8); -+ break; -+ case 16: -+ ret = fbScreenInit(pScreen, pbits, prfb->width, prfb->height, -+ dpix, dpiy, prfb->paddedWidthInBytes / 2, 16); -+ if (prfb->depth == 15) { -+ blueBits = 5; greenBits = 5; redBits = 5; -+ } else { -+ blueBits = 5; greenBits = 6; redBits = 5; -+ } -+ break; -+ case 32: -+ ret = fbScreenInit(pScreen, pbits, prfb->width, prfb->height, -+ dpix, dpiy, prfb->paddedWidthInBytes / 4, 32); -+ blueBits = 8; greenBits = 8; redBits = 8; -+ break; -+ default: -+ return FALSE; -+ } -+ -+ if (!ret) return FALSE; -+ -+ miInitializeBackingStore(pScreen); -+ -+ if (prfb->bitsPerPixel > 8) { -+ if (strcasecmp(primaryOrder, "bgr") == 0) { -+ rfbLog("BGR format %d %d %d\n", blueBits, greenBits, redBits); -+ vis = pScreen->visuals + pScreen->numVisuals; -+ while (--vis >= pScreen->visuals) { -+ if ((vis->class | DynamicClass) == DirectColor) { -+ vis->offsetRed = 0; -+ vis->redMask = (1 << redBits) - 1; -+ vis->offsetGreen = redBits; -+ vis->greenMask = ((1 << greenBits) - 1) << vis->offsetGreen; -+ vis->offsetBlue = redBits + greenBits; -+ vis->blueMask = ((1 << blueBits) - 1) << vis->offsetBlue; -+ } -+ } -+ } else { -+ rfbLog("RGB format %d %d %d\n", blueBits, greenBits, redBits); -+ vis = pScreen->visuals + pScreen->numVisuals; -+ while (--vis >= pScreen->visuals) { -+ if ((vis->class | DynamicClass) == DirectColor) { -+ vis->offsetBlue = 0; -+ vis->blueMask = (1 << blueBits) - 1; -+ vis->offsetGreen = blueBits; -+ vis->greenMask = ((1 << greenBits) - 1) << vis->offsetGreen; -+ vis->offsetRed = blueBits + greenBits; -+ vis->redMask = ((1 << redBits) - 1) << vis->offsetRed; -+ } -+ } -+ } -+ } -+ -+ if (prfb->bitsPerPixel > 4) -+ fbPictureInit(pScreen, 0, 0); -+ -+ prfb->cursorIsDrawn = FALSE; -+ prfb->dontSendFramebufferUpdate = FALSE; -+ -+ prfb->CloseScreen = pScreen->CloseScreen; -+ prfb->WakeupHandler = pScreen->WakeupHandler; -+ prfb->CreateGC = pScreen->CreateGC; -+ prfb->CopyWindow = pScreen->CopyWindow; -+ prfb->ClearToBackground = pScreen->ClearToBackground; -+#ifdef CHROMIUM -+ prfb->RealizeWindow = pScreen->RealizeWindow; -+ prfb->UnrealizeWindow = pScreen->UnrealizeWindow; -+ prfb->DestroyWindow = pScreen->DestroyWindow; -+ prfb->PositionWindow = pScreen->PositionWindow; -+ prfb->ResizeWindow = pScreen->ResizeWindow; -+ prfb->ClipNotify = pScreen->ClipNotify; -+#endif -+#ifdef RENDER -+ ps = GetPictureScreenIfSet(pScreen); -+ if (ps) -+ prfb->Composite = ps->Composite; -+#endif -+ pScreen->CloseScreen = rfbCloseScreen; -+ pScreen->WakeupHandler = rfbWakeupHandler; -+ pScreen->CreateGC = rfbCreateGC; -+ pScreen->CopyWindow = rfbCopyWindow; -+ pScreen->ClearToBackground = rfbClearToBackground; -+#ifdef CHROMIUM -+ pScreen->RealizeWindow = rfbRealizeWindow; -+ pScreen->UnrealizeWindow = rfbUnrealizeWindow; -+ pScreen->DestroyWindow = rfbDestroyWindow; -+ pScreen->PositionWindow = rfbPositionWindow; -+ pScreen->ResizeWindow = rfbResizeWindow; -+ pScreen->ClipNotify = rfbClipNotify; -+#endif -+#ifdef RENDER -+ if (ps) -+ ps->Composite = rfbComposite; -+#endif -+ -+ pScreen->InstallColormap = rfbInstallColormap; -+ pScreen->UninstallColormap = rfbUninstallColormap; -+ pScreen->ListInstalledColormaps = rfbListInstalledColormaps; -+ pScreen->StoreColors = rfbStoreColors; -+ -+ pScreen->SaveScreen = (SaveScreenProcPtr)rfbAlwaysTrue; -+ -+ rfbDCInitialize(pScreen, &rfbPointerCursorFuncs); -+ -+ if (noCursor) { -+ pScreen->DisplayCursor = (DisplayCursorProcPtr)rfbAlwaysTrue; -+ prfb->cursorIsDrawn = TRUE; -+ } -+ -+ pScreen->blackPixel = prfb->blackPixel; -+ pScreen->whitePixel = prfb->whitePixel; -+ -+ prfb->rfbServerFormat.bitsPerPixel = prfb->bitsPerPixel; -+ prfb->rfbServerFormat.depth = prfb->depth; -+ prfb->rfbServerFormat.bigEndian = !(*(char *)&rfbEndianTest); -+ -+ /* Find the root visual and set the server format */ -+ for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++) -+ ; -+ prfb->rfbServerFormat.trueColour = (vis->class == TrueColor); -+ -+ if ( (vis->class == TrueColor) || (vis->class == DirectColor) ) { -+ prfb->rfbServerFormat.redMax = vis->redMask >> vis->offsetRed; -+ prfb->rfbServerFormat.greenMax = vis->greenMask >> vis->offsetGreen; -+ prfb->rfbServerFormat.blueMax = vis->blueMask >> vis->offsetBlue; -+ prfb->rfbServerFormat.redShift = vis->offsetRed; -+ prfb->rfbServerFormat.greenShift = vis->offsetGreen; -+ prfb->rfbServerFormat.blueShift = vis->offsetBlue; -+ } else { -+ prfb->rfbServerFormat.redMax -+ = prfb->rfbServerFormat.greenMax -+ = prfb->rfbServerFormat.blueMax = 0; -+ prfb->rfbServerFormat.redShift -+ = prfb->rfbServerFormat.greenShift -+ = prfb->rfbServerFormat.blueShift = 0; -+ } -+ -+ ret = fbCreateDefColormap(pScreen); -+ -+ rfbInitSockets(pScreen); -+#if 0 -+ rdpInitSockets(pScreen); -+#endif -+ if (inetdSock == -1) -+ httpInitSockets(pScreen); -+ -+ return ret; -+ -+} /* end rfbScreenInit */ -+ -+ -+ -+/* -+ * InitInput is also called every time the server resets. It is called after -+ * InitOutput so we can assume that rfbInitSockets has already been called. -+ */ -+void -+InitInput(int argc, char *argv[]) -+{ -+ DeviceIntPtr p, k; -+ k = AddInputDevice(serverClient, rfbKeybdProc, TRUE); -+ p = AddInputDevice(serverClient, rfbMouseProc, TRUE); -+ -+ mieqInit(); -+ -+#if 0 -+ mieqCheckForInput[0] = checkForInput[0]; -+ mieqCheckForInput[1] = checkForInput[1]; -+ SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]); -+#endif -+} -+ -+ -+static int -+rfbKeybdProc(DeviceIntPtr pDevice, int onoff) -+{ -+ KeySymsRec keySyms; -+ CARD8 modMap[MAP_LENGTH]; -+ DevicePtr pDev = (DevicePtr)pDevice; -+ -+ switch (onoff) -+ { -+ case DEVICE_INIT: -+ vncSetKeyboardDevice(pDevice); -+ KbdDeviceInit(pDevice, &keySyms, modMap); -+ InitKeyboardDeviceStruct(pDevice, NULL, -+ (BellProcPtr)rfbSendBell, -+ (KbdCtrlProcPtr)NoopDDA); -+ break; -+ case DEVICE_ON: -+ pDev->on = TRUE; -+ KbdDeviceOn(); -+ break; -+ case DEVICE_OFF: -+ pDev->on = FALSE; -+ KbdDeviceOff(); -+ break; -+ case DEVICE_CLOSE: -+ vncSetKeyboardDevice(NULL); -+ if (pDev->on) -+ KbdDeviceOff(); -+ break; -+ } -+ return Success; -+} -+ -+static int -+rfbMouseProc(DeviceIntPtr pDevice, int onoff) -+{ -+ BYTE map[6]; -+ Atom btn_labels[5] = {0}; -+ Atom axes_labels[2] = {0}; -+ DevicePtr pDev = (DevicePtr)pDevice; -+ -+ switch (onoff) -+ { -+ case DEVICE_INIT: -+ PtrDeviceInit(); -+ map[1] = 1; -+ map[2] = 2; -+ map[3] = 3; -+ map[4] = 4; -+ map[5] = 5; -+ btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); -+ btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); -+ btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); -+ -+ axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); -+ axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); -+ -+ InitPointerDeviceStruct(pDev, map, 5, btn_labels, -+ PtrDeviceControl, -+ GetMaximumEventsNum(), 2 /* numAxes */, axes_labels); -+ vncSetPointerDevice(pDevice); -+ break; -+ -+ case DEVICE_ON: -+ pDev->on = TRUE; -+ PtrDeviceOn(pDevice); -+ break; -+ -+ case DEVICE_OFF: -+ pDev->on = FALSE; -+ PtrDeviceOff(); -+ break; -+ -+ case DEVICE_CLOSE: -+ vncSetPointerDevice(NULL); -+ if (pDev->on) -+ PtrDeviceOff(); -+ break; -+ } -+ return Success; -+} -+ -+ -+Bool -+LegalModifier(unsigned int key, DeviceIntPtr pDev) -+{ -+ return TRUE; -+} -+ -+ -+void -+ProcessInputEvents(void) -+{ -+#if 0 -+ if (*mieqCheckForInput[0] != *mieqCheckForInput[1]) { -+#endif -+ mieqProcessInputEvents(); -+#if 0 -+ } -+#endif -+} -+ -+ -+static Bool CheckDisplayNumber(int n) -+{ -+ char fname[32]; -+ int sock; -+ struct sockaddr_in addr; -+ -+ sock = socket(AF_INET, SOCK_STREAM, 0); -+ -+ memset(&addr, 0, sizeof(addr)); -+ addr.sin_family = AF_INET; -+ addr.sin_addr.s_addr = htonl(INADDR_ANY); -+ addr.sin_port = htons(6000+n); -+ if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { -+ close(sock); -+ return FALSE; -+ } -+ close(sock); -+ -+ sprintf(fname, "/tmp/.X%d-lock", n); -+ if (access(fname, F_OK) == 0) -+ return FALSE; -+ -+ sprintf(fname, "/tmp/.X11-unix/X%d", n); -+ if (access(fname, F_OK) == 0) -+ return FALSE; -+ -+ return TRUE; -+} -+ -+static Bool -+rfbAlwaysTrue(void) -+{ -+ return TRUE; -+} -+ -+ -+static unsigned char * -+rfbAllocateFramebufferMemory(rfbScreenInfoPtr prfb) -+{ -+ if (prfb->pfbMemory) return prfb->pfbMemory; /* already done */ -+ -+ prfb->sizeInBytes = (prfb->paddedWidthInBytes * prfb->height); -+ -+ prfb->pfbMemory = (unsigned char *)malloc(prfb->sizeInBytes); -+ -+ return prfb->pfbMemory; -+} -+ -+ -+static Bool -+rfbCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y) -+{ -+ return FALSE; -+} -+ -+static void -+rfbCrossScreen (ScreenPtr pScreen, Bool entering) -+{ -+} -+ -+void -+ddxGiveUp(enum ExitCode error) -+{ -+ free(rfbScreen.pfbMemory); -+ if (initOutputCalled) { -+ char unixSocketName[32]; -+ sprintf(unixSocketName,"/tmp/.X11-unix/X%s",display); -+ unlink(unixSocketName); -+#ifdef CORBA -+ shutdownCORBA(); -+#endif -+ } -+} -+ -+void -+AbortDDX(enum ExitCode error) -+{ -+ ddxGiveUp(error); -+} -+ -+void -+CloseInput(void) -+{ -+} -+ -+void -+OsVendorInit(void) -+{ -+} -+ -+void -+OsVendorFatalError(void) -+{ -+} -+ -+void -+ddxUseMsg(void) -+{ -+ ErrorF("-geometry WxH set framebuffer width & height\n"); -+ ErrorF("-depth D set framebuffer depth\n"); -+ ErrorF("-pixelformat format set pixel format (BGRnnn or RGBnnn)\n"); -+ ErrorF("-udpinputport port UDP port for keyboard/pointer data\n"); -+ ErrorF("-rfbport port TCP port for RFB protocol\n"); -+ ErrorF("-rfbwait time max time in ms to wait for RFB client\n"); -+ ErrorF("-nocursor don't put up a cursor\n"); -+ ErrorF("-rfbauth passwd-file use authentication on RFB protocol\n"); -+ ErrorF("-loginauth use login-style Unix authentication\n"); -+ ErrorF("-httpd dir serve files via HTTP from here\n"); -+ ErrorF("-httpport port port for HTTP\n"); -+ ErrorF("-deferupdate time time in ms to defer updates " -+ "(default 40)\n"); -+ ErrorF("-economictranslate less memory-hungry translation\n"); -+ ErrorF("-lazytight disable \"gradient\" filter in tight " -+ "encoding\n"); -+ ErrorF("-desktop name VNC desktop name (default x11)\n"); -+ ErrorF("-alwaysshared always treat new clients as shared\n"); -+ ErrorF("-nevershared never treat new clients as shared\n"); -+ ErrorF("-dontdisconnect don't disconnect existing clients when a " -+ "new non-shared\n" -+ " connection comes in (refuse new connection " -+ "instead)\n"); -+ ErrorF("-localhost only allow connections from localhost\n" -+ " to the vnc ports. Use -nolisten tcp to disable\n" -+ " remote X clients as well.\n"); -+ ErrorF("-viewonly let clients only view the desktop\n"); -+ ErrorF("-interface ipaddr only bind to specified interface " -+ "address\n"); -+ ErrorF("-inetd Xvnc is launched by inetd\n"); -+ exit(1); -+} -+ -+#if 0 -+void ddxInitGlobals(void) -+{ -+ /* dummy function called by InitGlobals in os/utils.c */ -+} -+#endif -+ -+int -+NewInputDeviceRequest(InputOption *options, InputAttributes *attrs, DeviceIntPtr *pdev) -+{ -+ return BadValue; -+} -+ -+void -+DeleteInputDeviceRequest(DeviceIntPtr dev) -+{ -+} -+ -+ -+/* -+ * rfbLog prints a time-stamped message to the log file (stderr). -+ */ -+ -+void rfbLog(char *format, ...) -+{ -+ va_list args; -+ char buf[256]; -+ time_t clock; -+ -+ va_start(args, format); -+ -+ time(&clock); -+ strftime(buf, 255, "%d/%m/%Y %H:%M:%S ", localtime(&clock)); -+ fprintf(stderr, "%s\n", buf); -+ -+ vfprintf(stderr, format, args); -+ fflush(stderr); -+ -+ va_end(args); -+} -+ -+void rfbLogPerror(char *str) -+{ -+ rfbLog(""); -+ perror(str); -+} -diff -pruN xorg-server-1.12.1.orig/hw/vnc/kbdptr.c xorg-server-1.12.1/hw/vnc/kbdptr.c ---- xorg-server-1.12.1.orig/hw/vnc/kbdptr.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/kbdptr.c 2012-04-18 14:45:21.576820954 -0500 -@@ -0,0 +1,599 @@ -+/* -+ * kbdptr.c - deal with keyboard and pointer device over TCP & UDP. -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ * -+ */ -+ -+/* -+ * 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#include "rfb.h" -+#include "X11/X.h" -+#define NEED_EVENTS -+#include "X11/Xproto.h" -+#include "inputstr.h" -+#include "inpututils.h" -+#define XK_CYRILLIC -+#include -+#include -+#include "mi.h" -+#include "mipointer.h" -+#include "keyboard.h" -+#include "xkbsrv.h" -+ -+#ifdef DMXVNC -+#include "dmxinput.h" -+#endif -+ -+#if !XFREE86VNC -+ -+#define MIN_KEY_CODE 8 -+#define MAX_KEY_CODE 255 -+#define NO_OF_KEYS (MAX_KEY_CODE - MIN_KEY_CODE + 1) -+#define GLYPHS_PER_KEY 4 -+ -+#define CONTROL_L_KEY_CODE (MIN_KEY_CODE + 29) -+#define CONTROL_R_KEY_CODE (MIN_KEY_CODE + 101) -+#define SHIFT_L_KEY_CODE (MIN_KEY_CODE + 42) -+#define SHIFT_R_KEY_CODE (MIN_KEY_CODE + 54) -+#define META_L_KEY_CODE (MIN_KEY_CODE + 107) -+#define META_R_KEY_CODE (MIN_KEY_CODE + 108) -+#define ALT_L_KEY_CODE (MIN_KEY_CODE + 56) -+#define ALT_R_KEY_CODE (MIN_KEY_CODE + 105) -+ -+static KeySym map[MAX_KEY_CODE * GLYPHS_PER_KEY] = { -+ /* 0x00 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x01 */ XK_Escape, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x02 */ XK_1, XK_exclam, NoSymbol, NoSymbol, -+ /* 0x03 */ XK_2, XK_at, NoSymbol, NoSymbol, -+ /* 0x04 */ XK_3, XK_numbersign, NoSymbol, NoSymbol, -+ /* 0x05 */ XK_4, XK_dollar, NoSymbol, NoSymbol, -+ /* 0x06 */ XK_5, XK_percent, NoSymbol, NoSymbol, -+ /* 0x07 */ XK_6, XK_asciicircum, NoSymbol, NoSymbol, -+ /* 0x08 */ XK_7, XK_ampersand, NoSymbol, NoSymbol, -+ /* 0x09 */ XK_8, XK_asterisk, NoSymbol, NoSymbol, -+ /* 0x0a */ XK_9, XK_parenleft, NoSymbol, NoSymbol, -+ /* 0x0b */ XK_0, XK_parenright, NoSymbol, NoSymbol, -+ /* 0x0c */ XK_minus, XK_underscore, NoSymbol, NoSymbol, -+ /* 0x0d */ XK_equal, XK_plus, NoSymbol, NoSymbol, -+ /* 0x0e */ XK_BackSpace, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x0f */ XK_Tab, XK_ISO_Left_Tab,NoSymbol, NoSymbol, -+ /* 0x10 */ XK_q, XK_Q, NoSymbol, NoSymbol, -+ /* 0x11 */ XK_w, XK_W, NoSymbol, NoSymbol, -+ /* 0x12 */ XK_e, XK_E, NoSymbol, NoSymbol, -+ /* 0x13 */ XK_r, XK_R, NoSymbol, NoSymbol, -+ /* 0x14 */ XK_t, XK_T, NoSymbol, NoSymbol, -+ /* 0x15 */ XK_y, XK_Y, NoSymbol, NoSymbol, -+ /* 0x16 */ XK_u, XK_U, NoSymbol, NoSymbol, -+ /* 0x17 */ XK_i, XK_I, NoSymbol, NoSymbol, -+ /* 0x18 */ XK_o, XK_O, NoSymbol, NoSymbol, -+ /* 0x19 */ XK_p, XK_P, NoSymbol, NoSymbol, -+ /* 0x1a */ XK_bracketleft, XK_braceleft, NoSymbol, NoSymbol, -+ /* 0x1b */ XK_bracketright,XK_braceright, NoSymbol, NoSymbol, -+ /* 0x1c */ XK_Return, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x1d */ XK_Control_L, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x1e */ XK_a, XK_A, NoSymbol, NoSymbol, -+ /* 0x1f */ XK_s, XK_S, NoSymbol, NoSymbol, -+ /* 0x20 */ XK_d, XK_D, NoSymbol, NoSymbol, -+ /* 0x21 */ XK_f, XK_F, NoSymbol, NoSymbol, -+ /* 0x22 */ XK_g, XK_G, NoSymbol, NoSymbol, -+ /* 0x23 */ XK_h, XK_H, NoSymbol, NoSymbol, -+ /* 0x24 */ XK_j, XK_J, NoSymbol, NoSymbol, -+ /* 0x25 */ XK_k, XK_K, NoSymbol, NoSymbol, -+ /* 0x26 */ XK_l, XK_L, NoSymbol, NoSymbol, -+ /* 0x27 */ XK_semicolon, XK_colon, NoSymbol, NoSymbol, -+ /* 0x28 */ XK_quoteright, XK_quotedbl, NoSymbol, NoSymbol, -+ /* 0x29 */ XK_quoteleft, XK_asciitilde, NoSymbol, NoSymbol, -+ /* 0x2a */ XK_Shift_L, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x2b */ XK_backslash, XK_bar, NoSymbol, NoSymbol, -+ /* 0x2c */ XK_z, XK_Z, NoSymbol, NoSymbol, -+ /* 0x2d */ XK_x, XK_X, NoSymbol, NoSymbol, -+ /* 0x2e */ XK_c, XK_C, NoSymbol, NoSymbol, -+ /* 0x2f */ XK_v, XK_V, NoSymbol, NoSymbol, -+ /* 0x30 */ XK_b, XK_B, NoSymbol, NoSymbol, -+ /* 0x31 */ XK_n, XK_N, NoSymbol, NoSymbol, -+ /* 0x32 */ XK_m, XK_M, NoSymbol, NoSymbol, -+ /* 0x33 */ XK_comma, XK_less, NoSymbol, NoSymbol, -+ /* 0x34 */ XK_period, XK_greater, NoSymbol, NoSymbol, -+ /* 0x35 */ XK_slash, XK_question, NoSymbol, NoSymbol, -+ /* 0x36 */ XK_Shift_R, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x37 */ XK_KP_Multiply, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x38 */ XK_Alt_L, XK_Meta_L, NoSymbol, NoSymbol, -+ /* 0x39 */ XK_space, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x3a */ XK_Caps_Lock, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x3b */ XK_F1, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x3c */ XK_F2, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x3d */ XK_F3, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x3e */ XK_F4, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x3f */ XK_F5, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x40 */ XK_F6, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x41 */ XK_F7, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x42 */ XK_F8, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x43 */ XK_F9, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x44 */ XK_F10, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x45 */ XK_Num_Lock, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x46 */ XK_Scroll_Lock, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x47 */ XK_KP_Home, XK_KP_7, NoSymbol, NoSymbol, -+ /* 0x48 */ XK_KP_Up, XK_KP_8, NoSymbol, NoSymbol, -+ /* 0x49 */ XK_KP_Prior, XK_KP_9, NoSymbol, NoSymbol, -+ /* 0x4a */ XK_KP_Subtract, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x4b */ XK_KP_Left, XK_KP_4, NoSymbol, NoSymbol, -+ /* 0x4c */ XK_KP_Begin, XK_KP_5, NoSymbol, NoSymbol, -+ /* 0x4d */ XK_KP_Right, XK_KP_6, NoSymbol, NoSymbol, -+ /* 0x4e */ XK_KP_Add, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x4f */ XK_KP_End, XK_KP_1, NoSymbol, NoSymbol, -+ /* 0x50 */ XK_KP_Down, XK_KP_2, NoSymbol, NoSymbol, -+ /* 0x51 */ XK_KP_Next, XK_KP_3, NoSymbol, NoSymbol, -+ /* 0x52 */ XK_KP_Insert, XK_KP_0, NoSymbol, NoSymbol, -+ /* 0x53 */ XK_KP_Delete, XK_KP_Decimal, NoSymbol, NoSymbol, -+ /* 0x54 */ XK_Sys_Req, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x55 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x56 */ XK_less, XK_greater, NoSymbol, NoSymbol, -+ /* 0x57 */ XK_F11, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x58 */ XK_F12, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x59 */ XK_Home, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x5a */ XK_Up, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x5b */ XK_Prior, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x5c */ XK_Left, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x5d */ XK_Begin, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x5e */ XK_Right, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x5f */ XK_End, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x60 */ XK_Down, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x61 */ XK_Next, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x62 */ XK_Insert, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x63 */ XK_Delete, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x64 */ XK_KP_Enter, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x65 */ XK_Control_R, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x66 */ XK_Pause, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x67 */ XK_Print, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x68 */ XK_KP_Divide, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x69 */ XK_Alt_R, XK_Meta_R, NoSymbol, NoSymbol, -+ /* 0x6a */ XK_Break, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x6b */ XK_Meta_L, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x6c */ XK_Meta_R, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x6d */ XK_Menu, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x6e */ XK_F13, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x6f */ XK_F14, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x70 */ XK_F15, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x71 */ XK_F16, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x72 */ XK_F17, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x73 */ XK_backslash, XK_underscore, NoSymbol, NoSymbol, -+ /* 0x74 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x75 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x76 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x77 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x78 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x79 */ XK_Henkan, XK_Mode_switch, NoSymbol, NoSymbol, -+ /* 0x7a */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x7b */ XK_Muhenkan, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x7c */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x7d */ XK_backslash, XK_bar, NoSymbol, NoSymbol, -+ /* 0x7e */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x7f */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+}; -+ -+#define N_PREDEFINED_KEYS (sizeof(map) / (sizeof(KeySym) * GLYPHS_PER_KEY)) -+ -+#endif -+ -+#define KEY_IS_PRESSED(keycode) \ -+ (kbdDevice->key->down[(keycode) >> 3] & (1 << ((keycode) & 7))) -+ -+static void vncXConvertCase(KeySym sym, KeySym *lower, KeySym *upper); -+ -+static DeviceIntPtr ptrDevice = NULL, kbdDevice = NULL; -+ -+ -+void -+vncSetKeyboardDevice(DeviceIntPtr kbd) -+{ -+ if (kbdDevice && kbd) -+ return; /* set once */ -+ kbdDevice = kbd; -+} -+ -+ -+void -+vncSetPointerDevice(DeviceIntPtr ptr) -+{ -+ if (ptrDevice && ptr) -+ return; /* set once */ -+ ptrDevice = ptr; -+} -+ -+#ifndef DMXVNC -+static void -+EnqueueMotion(DeviceIntPtr ptrDev, int x, int y) -+{ -+ int detail = 0, valuators[2]; -+ ValuatorMask mask; -+ valuators[0] = x; -+ valuators[1] = y; -+ -+ if (!ptrDev) { -+ ErrorF("VNC: In EnqueueMotion() ptrDev=NULL\n"); -+ return; -+ } -+ valuator_mask_set_range(&mask,0, 2, valuators); -+ QueuePointerEvents(ptrDev, MotionNotify, detail, POINTER_ABSOLUTE, &mask); -+} -+#endif -+ -+ -+static void -+EnqueueButton(DeviceIntPtr ptrDev, int type, int detail) -+{ -+ if (!ptrDev) { -+ ErrorF("VNC: In EnqueueButton() ptrDev=NULL\n"); -+ return; -+ } -+ QueuePointerEvents(ptrDev, type, detail, -+ POINTER_ABSOLUTE, NULL/*valuators*/); -+} -+ -+ -+static void -+EnqueueKey(DeviceIntPtr kbdDev, int type, int detail) -+{ -+ if (!kbdDev) { -+ ErrorF("VNC: In EnqueueKey() kbdDev=NULL\n"); -+ return; -+ } -+ QueueKeyboardEvents(kbdDev, type, detail, NULL); -+} -+ -+/* -+ * Called when the rfbserver receives a rfbKeyEvent event from a client. -+ * Put an X keyboard event into the event queue. -+ */ -+void -+KbdAddEvent(Bool down, KeySym keySym, rfbClientPtr cl) -+{ -+ const int type = down ? KeyPress : KeyRelease; -+ KeySymsPtr keySyms; -+ XkbStateRec *xkb; -+ int i; -+ int keyCode = 0; -+ int freeIndex = -1; -+ Bool fakeShiftPress = FALSE; -+ Bool fakeShiftLRelease = FALSE; -+ Bool fakeShiftRRelease = FALSE; -+ Bool shiftMustBeReleased = FALSE; -+ Bool shiftMustBePressed = FALSE; -+ -+ if (!kbdDevice) -+ return; -+ -+ keySyms = XkbGetCoreMap(kbdDevice); -+ -+#ifdef CORBA -+ if (cl) { -+ CARD32 clientId = cl->sock; -+ ChangeWindowProperty(screenInfo.screens[0]->root, VNC_LAST_CLIENT_ID, XA_INTEGER, -+ 32, PropModeReplace, 1, (pointer)&clientId, TRUE); -+ } -+#endif -+ -+ /* NOTE: This is where it gets hairy for XFree86 servers. -+ * I think the best way to deal with this is invent a new protocol -+ * to send over the wire the remote keyboard type and correctly -+ * handle that as XINPUT extension device (we're part of the way -+ * there for that. -+ * -+ * Alan. -+ */ -+#if !XFREE86VNC -+ /* First check if it's one of our predefined keys. If so then we can make -+ some attempt at allowing an xmodmap inside a VNC desktop behave -+ something like you'd expect - e.g. if keys A & B are swapped over and -+ the VNC client sends an A, then map it to a B when generating the X -+ event. We don't attempt to do this for keycodes which we make up on the -+ fly because it's too hard... */ -+ -+ for (i = 0; i < N_PREDEFINED_KEYS * GLYPHS_PER_KEY; i++) { -+ if (keySym == map[i]) { -+ keyCode = MIN_KEY_CODE + i / GLYPHS_PER_KEY; -+ -+ if (map[(i/GLYPHS_PER_KEY) * GLYPHS_PER_KEY + 1] != NoSymbol) { -+ -+ /* this keycode has more than one symbol associated with it, -+ so shift state is important */ -+ -+ if ((i % GLYPHS_PER_KEY) == 0) -+ shiftMustBeReleased = TRUE; -+ else -+ shiftMustBePressed = TRUE; -+ } -+ break; -+ } -+ } -+#endif -+ -+ if (!keyCode) { -+ -+ /* not one of our predefined keys - see if it's in the current keyboard -+ mapping (i.e. we've already allocated an extra keycode for it) */ -+ -+ if (keySyms->mapWidth < 2) { -+ ErrorF("KbdAddEvent: Sanity check failed - Keyboard mapping has " -+ "less than 2 keysyms per keycode (KeySym 0x%x)\n", (int)keySym); -+ return; -+ } -+ -+ for (i = 0; i < NO_OF_KEYS * keySyms->mapWidth; i++) { -+ if (keySym == keySyms->map[i]) { -+ keyCode = MIN_KEY_CODE + i / keySyms->mapWidth; -+ -+ if (keySyms->map[(i / keySyms->mapWidth) -+ * keySyms->mapWidth + 1] != NoSymbol) { -+ -+ /* this keycode has more than one symbol associated with -+ it, so shift state is important */ -+ -+ if ((i % keySyms->mapWidth) == 0) -+ shiftMustBeReleased = TRUE; -+ else -+ shiftMustBePressed = TRUE; -+ } -+ break; -+ } -+ if ((freeIndex == -1) && (keySyms->map[i] == NoSymbol) -+ && (i % keySyms->mapWidth) == 0) -+ { -+ freeIndex = i; -+ } -+ } -+ } -+ -+ if (!keyCode) { -+ KeySym lower, upper; -+ -+ /* we don't have an existing keycode - make one up on the fly and add -+ it to the keyboard mapping. Thanks to Vlad Harchev for pointing -+ out problems with non-ascii capitalisation. */ -+ -+ if (freeIndex == -1) { -+ ErrorF("KbdAddEvent: ignoring KeySym 0x%x - no free KeyCodes\n", -+ (int)keySym); -+ return; -+ } -+ -+ keyCode = MIN_KEY_CODE + freeIndex / keySyms->mapWidth; -+ -+ vncXConvertCase(keySym, &lower, &upper); -+ -+ if (lower == upper) { -+ keySyms->map[freeIndex] = keySym; -+ -+ } else { -+ keySyms->map[freeIndex] = lower; -+ keySyms->map[freeIndex+1] = upper; -+ -+ if (keySym == lower) -+ shiftMustBeReleased = TRUE; -+ else -+ shiftMustBePressed = TRUE; -+ } -+ -+ XkbApplyMappingChange(kbdDevice, keySyms, keyCode, 1, NULL, serverClient); -+ -+ ErrorF("KbdAddEvent: unknown KeySym 0x%x - allocating KeyCode %d\n", -+ (int)keySym, keyCode); -+ } -+ -+ xkb = &kbdDevice->key->xkbInfo->state; -+ if (down) { -+ if (shiftMustBePressed && !(XkbStateFieldFromRec(xkb) & ShiftMask)) { -+ fakeShiftPress = TRUE; -+ EnqueueKey(kbdDevice, KeyPress, SHIFT_L_KEY_CODE); -+ } -+ if (shiftMustBeReleased && (XkbStateFieldFromRec(xkb) & ShiftMask)) { -+ if (KEY_IS_PRESSED(SHIFT_L_KEY_CODE)) { -+ fakeShiftLRelease = TRUE; -+ EnqueueKey(kbdDevice, KeyRelease, SHIFT_L_KEY_CODE); -+ } -+ if (KEY_IS_PRESSED(SHIFT_R_KEY_CODE)) { -+ fakeShiftRRelease = TRUE; -+ EnqueueKey(kbdDevice, KeyRelease, SHIFT_R_KEY_CODE); -+ } -+ } -+ } -+ -+ EnqueueKey(kbdDevice, type, keyCode); -+ -+ if (fakeShiftPress) { -+ EnqueueKey(kbdDevice, KeyRelease, SHIFT_L_KEY_CODE); -+ } -+ if (fakeShiftLRelease) { -+ EnqueueKey(kbdDevice, KeyPress, SHIFT_L_KEY_CODE); -+ } -+ if (fakeShiftRRelease) { -+ EnqueueKey(kbdDevice, KeyPress, SHIFT_R_KEY_CODE); -+ } -+} -+ -+ -+/* -+ * Called when the rfbserver receives a rfbPointerEvent event from a client. -+ * Put an X mouse event into the event queue. -+ */ -+void -+PtrAddEvent(int buttonMask, int x, int y, rfbClientPtr cl) -+{ -+ int i; -+ static int oldButtonMask = 0; -+ -+#ifdef CORBA -+ if (cl) { -+ CARD32 clientId = cl->sock; -+ ChangeWindowProperty(screenInfo.screens[0]->root, VNC_LAST_CLIENT_ID, XA_INTEGER, -+ 32, PropModeReplace, 1, (pointer)&clientId, TRUE); -+ } -+#endif -+ -+#ifdef DMXVNC -+ dmxCoreMotion(&ptrDevice->public, x, y, 0, DMX_BLOCK); -+#else -+ EnqueueMotion(ptrDevice, x, y ); -+#endif -+ -+ for (i = 0; i < 5; i++) { -+ if ((buttonMask ^ oldButtonMask) & (1<key->down[i] != 0) { -+ for (j = 0; j < 8; j++) { -+ if (kbdDevice->key->down[i] & (1 << j)) { -+ int detail = (i << 3) | j; -+ EnqueueKey(kbdDevice, KeyRelease, detail); -+ } -+ } -+ } -+ } -+} -+ -+ -+/* copied from Xlib source */ -+ -+static void vncXConvertCase(KeySym sym, KeySym *lower, KeySym *upper) -+{ -+ *lower = sym; -+ *upper = sym; -+ switch(sym >> 8) { -+ case 0: /* Latin 1 */ -+ if ((sym >= XK_A) && (sym <= XK_Z)) -+ *lower += (XK_a - XK_A); -+ else if ((sym >= XK_a) && (sym <= XK_z)) -+ *upper -= (XK_a - XK_A); -+ else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis)) -+ *lower += (XK_agrave - XK_Agrave); -+ else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis)) -+ *upper -= (XK_agrave - XK_Agrave); -+ else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn)) -+ *lower += (XK_oslash - XK_Ooblique); -+ else if ((sym >= XK_oslash) && (sym <= XK_thorn)) -+ *upper -= (XK_oslash - XK_Ooblique); -+ break; -+ case 1: /* Latin 2 */ -+ /* Assume the KeySym is a legal value (ignore discontinuities) */ -+ if (sym == XK_Aogonek) -+ *lower = XK_aogonek; -+ else if (sym >= XK_Lstroke && sym <= XK_Sacute) -+ *lower += (XK_lstroke - XK_Lstroke); -+ else if (sym >= XK_Scaron && sym <= XK_Zacute) -+ *lower += (XK_scaron - XK_Scaron); -+ else if (sym >= XK_Zcaron && sym <= XK_Zabovedot) -+ *lower += (XK_zcaron - XK_Zcaron); -+ else if (sym == XK_aogonek) -+ *upper = XK_Aogonek; -+ else if (sym >= XK_lstroke && sym <= XK_sacute) -+ *upper -= (XK_lstroke - XK_Lstroke); -+ else if (sym >= XK_scaron && sym <= XK_zacute) -+ *upper -= (XK_scaron - XK_Scaron); -+ else if (sym >= XK_zcaron && sym <= XK_zabovedot) -+ *upper -= (XK_zcaron - XK_Zcaron); -+ else if (sym >= XK_Racute && sym <= XK_Tcedilla) -+ *lower += (XK_racute - XK_Racute); -+ else if (sym >= XK_racute && sym <= XK_tcedilla) -+ *upper -= (XK_racute - XK_Racute); -+ break; -+ case 2: /* Latin 3 */ -+ /* Assume the KeySym is a legal value (ignore discontinuities) */ -+ if (sym >= XK_Hstroke && sym <= XK_Hcircumflex) -+ *lower += (XK_hstroke - XK_Hstroke); -+ else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex) -+ *lower += (XK_gbreve - XK_Gbreve); -+ else if (sym >= XK_hstroke && sym <= XK_hcircumflex) -+ *upper -= (XK_hstroke - XK_Hstroke); -+ else if (sym >= XK_gbreve && sym <= XK_jcircumflex) -+ *upper -= (XK_gbreve - XK_Gbreve); -+ else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex) -+ *lower += (XK_cabovedot - XK_Cabovedot); -+ else if (sym >= XK_cabovedot && sym <= XK_scircumflex) -+ *upper -= (XK_cabovedot - XK_Cabovedot); -+ break; -+ case 3: /* Latin 4 */ -+ /* Assume the KeySym is a legal value (ignore discontinuities) */ -+ if (sym >= XK_Rcedilla && sym <= XK_Tslash) -+ *lower += (XK_rcedilla - XK_Rcedilla); -+ else if (sym >= XK_rcedilla && sym <= XK_tslash) -+ *upper -= (XK_rcedilla - XK_Rcedilla); -+ else if (sym == XK_ENG) -+ *lower = XK_eng; -+ else if (sym == XK_eng) -+ *upper = XK_ENG; -+ else if (sym >= XK_Amacron && sym <= XK_Umacron) -+ *lower += (XK_amacron - XK_Amacron); -+ else if (sym >= XK_amacron && sym <= XK_umacron) -+ *upper -= (XK_amacron - XK_Amacron); -+ break; -+ case 6: /* Cyrillic */ -+ /* Assume the KeySym is a legal value (ignore discontinuities) */ -+ if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE) -+ *lower -= (XK_Serbian_DJE - XK_Serbian_dje); -+ else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze) -+ *upper += (XK_Serbian_DJE - XK_Serbian_dje); -+ else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN) -+ *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu); -+ else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign) -+ *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu); -+ break; -+ case 7: /* Greek */ -+ /* Assume the KeySym is a legal value (ignore discontinuities) */ -+ if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent) -+ *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent); -+ else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent && -+ sym != XK_Greek_iotaaccentdieresis && -+ sym != XK_Greek_upsilonaccentdieresis) -+ *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent); -+ else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA) -+ *lower += (XK_Greek_alpha - XK_Greek_ALPHA); -+ else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega && -+ sym != XK_Greek_finalsmallsigma) -+ *upper -= (XK_Greek_alpha - XK_Greek_ALPHA); -+ break; -+ } -+} -diff -pruN xorg-server-1.12.1.orig/hw/vnc/keyboard.h xorg-server-1.12.1/hw/vnc/keyboard.h ---- xorg-server-1.12.1.orig/hw/vnc/keyboard.h 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/keyboard.h 2012-04-18 14:45:21.577820941 -0500 -@@ -0,0 +1,34 @@ -+/* -+ * Copyright (C) 2002 Alan Hourihane. 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. -+ * -+ * Author: Alan Hourihane -+ */ -+ -+#define MIN_KEY_CODE 8 -+#define MAX_KEY_CODE 255 -+#define NO_OF_KEYS (MAX_KEY_CODE - MIN_KEY_CODE + 1) -+#define GLYPHS_PER_KEY 4 -+ -+#define CONTROL_L_KEY_CODE (MIN_KEY_CODE + 29) -+#define CONTROL_R_KEY_CODE (MIN_KEY_CODE + 101) -+#define SHIFT_L_KEY_CODE (MIN_KEY_CODE + 42) -+#define SHIFT_R_KEY_CODE (MIN_KEY_CODE + 54) -+#define META_L_KEY_CODE (MIN_KEY_CODE + 107) -+#define META_R_KEY_CODE (MIN_KEY_CODE + 108) -+#define ALT_L_KEY_CODE (MIN_KEY_CODE + 56) -+#define ALT_R_KEY_CODE (MIN_KEY_CODE + 105) -diff -pruN xorg-server-1.12.1.orig/hw/vnc/LICENCE.TXT xorg-server-1.12.1/hw/vnc/LICENCE.TXT ---- xorg-server-1.12.1.orig/hw/vnc/LICENCE.TXT 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/LICENCE.TXT 2012-04-18 14:45:21.577820941 -0500 -@@ -0,0 +1,340 @@ -+ GNU GENERAL PUBLIC LICENSE -+ Version 2, June 1991 -+ -+ Copyright (C) 1989, 1991 Free Software Foundation, Inc. -+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -+ Everyone is permitted to copy and distribute verbatim copies -+ of this license document, but changing it is not allowed. -+ -+ Preamble -+ -+ The licenses for most software are designed to take away your -+freedom to share and change it. By contrast, the GNU General Public -+License is intended to guarantee your freedom to share and change free -+software--to make sure the software is free for all its users. This -+General Public License applies to most of the Free Software -+Foundation's software and to any other program whose authors commit to -+using it. (Some other Free Software Foundation software is covered by -+the GNU Library General Public License instead.) You can apply it to -+your programs, too. -+ -+ When we speak of free software, we are referring to freedom, not -+price. Our General Public Licenses are designed to make sure that you -+have the freedom to distribute copies of free software (and charge for -+this service if you wish), that you receive source code or can get it -+if you want it, that you can change the software or use pieces of it -+in new free programs; and that you know you can do these things. -+ -+ To protect your rights, we need to make restrictions that forbid -+anyone to deny you these rights or to ask you to surrender the rights. -+These restrictions translate to certain responsibilities for you if you -+distribute copies of the software, or if you modify it. -+ -+ For example, if you distribute copies of such a program, whether -+gratis or for a fee, you must give the recipients all the rights that -+you have. You must make sure that they, too, receive or can get the -+source code. And you must show them these terms so they know their -+rights. -+ -+ We protect your rights with two steps: (1) copyright the software, and -+(2) offer you this license which gives you legal permission to copy, -+distribute and/or modify the software. -+ -+ Also, for each author's protection and ours, we want to make certain -+that everyone understands that there is no warranty for this free -+software. If the software is modified by someone else and passed on, we -+want its recipients to know that what they have is not the original, so -+that any problems introduced by others will not reflect on the original -+authors' reputations. -+ -+ Finally, any free program is threatened constantly by software -+patents. We wish to avoid the danger that redistributors of a free -+program will individually obtain patent licenses, in effect making the -+program proprietary. To prevent this, we have made it clear that any -+patent must be licensed for everyone's free use or not licensed at all. -+ -+ The precise terms and conditions for copying, distribution and -+modification follow. -+ -+ GNU GENERAL PUBLIC LICENSE -+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -+ -+ 0. This License applies to any program or other work which contains -+a notice placed by the copyright holder saying it may be distributed -+under the terms of this General Public License. The "Program", below, -+refers to any such program or work, and a "work based on the Program" -+means either the Program or any derivative work under copyright law: -+that is to say, a work containing the Program or a portion of it, -+either verbatim or with modifications and/or translated into another -+language. (Hereinafter, translation is included without limitation in -+the term "modification".) Each licensee is addressed as "you". -+ -+Activities other than copying, distribution and modification are not -+covered by this License; they are outside its scope. The act of -+running the Program is not restricted, and the output from the Program -+is covered only if its contents constitute a work based on the -+Program (independent of having been made by running the Program). -+Whether that is true depends on what the Program does. -+ -+ 1. You may copy and distribute verbatim copies of the Program's -+source code as you receive it, in any medium, provided that you -+conspicuously and appropriately publish on each copy an appropriate -+copyright notice and disclaimer of warranty; keep intact all the -+notices that refer to this License and to the absence of any warranty; -+and give any other recipients of the Program a copy of this License -+along with the Program. -+ -+You may charge a fee for the physical act of transferring a copy, and -+you may at your option offer warranty protection in exchange for a fee. -+ -+ 2. You may modify your copy or copies of the Program or any portion -+of it, thus forming a work based on the Program, and copy and -+distribute such modifications or work under the terms of Section 1 -+above, provided that you also meet all of these conditions: -+ -+ a) You must cause the modified files to carry prominent notices -+ stating that you changed the files and the date of any change. -+ -+ b) You must cause any work that you distribute or publish, that in -+ whole or in part contains or is derived from the Program or any -+ part thereof, to be licensed as a whole at no charge to all third -+ parties under the terms of this License. -+ -+ c) If the modified program normally reads commands interactively -+ when run, you must cause it, when started running for such -+ interactive use in the most ordinary way, to print or display an -+ announcement including an appropriate copyright notice and a -+ notice that there is no warranty (or else, saying that you provide -+ a warranty) and that users may redistribute the program under -+ these conditions, and telling the user how to view a copy of this -+ License. (Exception: if the Program itself is interactive but -+ does not normally print such an announcement, your work based on -+ the Program is not required to print an announcement.) -+ -+These requirements apply to the modified work as a whole. If -+identifiable sections of that work are not derived from the Program, -+and can be reasonably considered independent and separate works in -+themselves, then this License, and its terms, do not apply to those -+sections when you distribute them as separate works. But when you -+distribute the same sections as part of a whole which is a work based -+on the Program, the distribution of the whole must be on the terms of -+this License, whose permissions for other licensees extend to the -+entire whole, and thus to each and every part regardless of who wrote it. -+ -+Thus, it is not the intent of this section to claim rights or contest -+your rights to work written entirely by you; rather, the intent is to -+exercise the right to control the distribution of derivative or -+collective works based on the Program. -+ -+In addition, mere aggregation of another work not based on the Program -+with the Program (or with a work based on the Program) on a volume of -+a storage or distribution medium does not bring the other work under -+the scope of this License. -+ -+ 3. You may copy and distribute the Program (or a work based on it, -+under Section 2) in object code or executable form under the terms of -+Sections 1 and 2 above provided that you also do one of the following: -+ -+ a) Accompany it with the complete corresponding machine-readable -+ source code, which must be distributed under the terms of Sections -+ 1 and 2 above on a medium customarily used for software interchange; or, -+ -+ b) Accompany it with a written offer, valid for at least three -+ years, to give any third party, for a charge no more than your -+ cost of physically performing source distribution, a complete -+ machine-readable copy of the corresponding source code, to be -+ distributed under the terms of Sections 1 and 2 above on a medium -+ customarily used for software interchange; or, -+ -+ c) Accompany it with the information you received as to the offer -+ to distribute corresponding source code. (This alternative is -+ allowed only for noncommercial distribution and only if you -+ received the program in object code or executable form with such -+ an offer, in accord with Subsection b above.) -+ -+The source code for a work means the preferred form of the work for -+making modifications to it. For an executable work, complete source -+code means all the source code for all modules it contains, plus any -+associated interface definition files, plus the scripts used to -+control compilation and installation of the executable. However, as a -+special exception, the source code distributed need not include -+anything that is normally distributed (in either source or binary -+form) with the major components (compiler, kernel, and so on) of the -+operating system on which the executable runs, unless that component -+itself accompanies the executable. -+ -+If distribution of executable or object code is made by offering -+access to copy from a designated place, then offering equivalent -+access to copy the source code from the same place counts as -+distribution of the source code, even though third parties are not -+compelled to copy the source along with the object code. -+ -+ 4. You may not copy, modify, sublicense, or distribute the Program -+except as expressly provided under this License. Any attempt -+otherwise to copy, modify, sublicense or distribute the Program is -+void, and will automatically terminate your rights under this License. -+However, parties who have received copies, or rights, from you under -+this License will not have their licenses terminated so long as such -+parties remain in full compliance. -+ -+ 5. You are not required to accept this License, since you have not -+signed it. However, nothing else grants you permission to modify or -+distribute the Program or its derivative works. These actions are -+prohibited by law if you do not accept this License. Therefore, by -+modifying or distributing the Program (or any work based on the -+Program), you indicate your acceptance of this License to do so, and -+all its terms and conditions for copying, distributing or modifying -+the Program or works based on it. -+ -+ 6. Each time you redistribute the Program (or any work based on the -+Program), the recipient automatically receives a license from the -+original licensor to copy, distribute or modify the Program subject to -+these terms and conditions. You may not impose any further -+restrictions on the recipients' exercise of the rights granted herein. -+You are not responsible for enforcing compliance by third parties to -+this License. -+ -+ 7. If, as a consequence of a court judgment or allegation of patent -+infringement or for any other reason (not limited to patent issues), -+conditions are imposed on you (whether by court order, agreement or -+otherwise) that contradict the conditions of this License, they do not -+excuse you from the conditions of this License. If you cannot -+distribute so as to satisfy simultaneously your obligations under this -+License and any other pertinent obligations, then as a consequence you -+may not distribute the Program at all. For example, if a patent -+license would not permit royalty-free redistribution of the Program by -+all those who receive copies directly or indirectly through you, then -+the only way you could satisfy both it and this License would be to -+refrain entirely from distribution of the Program. -+ -+If any portion of this section is held invalid or unenforceable under -+any particular circumstance, the balance of the section is intended to -+apply and the section as a whole is intended to apply in other -+circumstances. -+ -+It is not the purpose of this section to induce you to infringe any -+patents or other property right claims or to contest validity of any -+such claims; this section has the sole purpose of protecting the -+integrity of the free software distribution system, which is -+implemented by public license practices. Many people have made -+generous contributions to the wide range of software distributed -+through that system in reliance on consistent application of that -+system; it is up to the author/donor to decide if he or she is willing -+to distribute software through any other system and a licensee cannot -+impose that choice. -+ -+This section is intended to make thoroughly clear what is believed to -+be a consequence of the rest of this License. -+ -+ 8. If the distribution and/or use of the Program is restricted in -+certain countries either by patents or by copyrighted interfaces, the -+original copyright holder who places the Program under this License -+may add an explicit geographical distribution limitation excluding -+those countries, so that distribution is permitted only in or among -+countries not thus excluded. In such case, this License incorporates -+the limitation as if written in the body of this License. -+ -+ 9. The Free Software Foundation may publish revised and/or new versions -+of the General Public License from time to time. Such new versions will -+be similar in spirit to the present version, but may differ in detail to -+address new problems or concerns. -+ -+Each version is given a distinguishing version number. If the Program -+specifies a version number of this License which applies to it and "any -+later version", you have the option of following the terms and conditions -+either of that version or of any later version published by the Free -+Software Foundation. If the Program does not specify a version number of -+this License, you may choose any version ever published by the Free Software -+Foundation. -+ -+ 10. If you wish to incorporate parts of the Program into other free -+programs whose distribution conditions are different, write to the author -+to ask for permission. For software which is copyrighted by the Free -+Software Foundation, write to the Free Software Foundation; we sometimes -+make exceptions for this. Our decision will be guided by the two goals -+of preserving the free status of all derivatives of our free software and -+of promoting the sharing and reuse of software generally. -+ -+ NO WARRANTY -+ -+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -+REPAIR OR CORRECTION. -+ -+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -+POSSIBILITY OF SUCH DAMAGES. -+ -+ END OF TERMS AND CONDITIONS -+ -+ Appendix: How to Apply These Terms to Your New Programs -+ -+ If you develop a new program, and you want it to be of the greatest -+possible use to the public, the best way to achieve this is to make it -+free software which everyone can redistribute and change under these terms. -+ -+ To do so, attach the following notices to the program. It is safest -+to attach them to the start of each source file to most effectively -+convey the exclusion of warranty; and each file should have at least -+the "copyright" line and a pointer to where the full notice is found. -+ -+ -+ Copyright (C) 19yy -+ -+ This program 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 program 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 program; if not, write to the Free Software -+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -+ USA. -+ -+Also add information on how to contact you by electronic and paper mail. -+ -+If the program is interactive, make it output a short notice like this -+when it starts in an interactive mode: -+ -+ Gnomovision version 69, Copyright (C) 19yy name of author -+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. -+ This is free software, and you are welcome to redistribute it -+ under certain conditions; type `show c' for details. -+ -+The hypothetical commands `show w' and `show c' should show the appropriate -+parts of the General Public License. Of course, the commands you use may -+be called something other than `show w' and `show c'; they could even be -+mouse-clicks or menu items--whatever suits your program. -+ -+You should also get your employer (if you work as a programmer) or your -+school, if any, to sign a "copyright disclaimer" for the program, if -+necessary. Here is a sample; alter the names: -+ -+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program -+ `Gnomovision' (which makes passes at compilers) written by James Hacker. -+ -+ , 1 April 1989 -+ Ty Coon, President of Vice -+ -+This General Public License does not permit incorporating your program into -+proprietary programs. If your program is a subroutine library, you may -+consider it more useful to permit linking proprietary applications with the -+library. If this is what you want to do, use the GNU Library General -+Public License instead of this License. -diff -pruN xorg-server-1.12.1.orig/hw/vnc/loginauth.c xorg-server-1.12.1/hw/vnc/loginauth.c ---- xorg-server-1.12.1.orig/hw/vnc/loginauth.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/loginauth.c 2012-04-18 14:45:21.577820941 -0500 -@@ -0,0 +1,142 @@ -+/* -+ * loginauth.c - deal with login-style Unix authentication. -+ * -+ * This file implements the UnixLogin authentication protocol when setting up -+ * an RFB connection. -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * Copyright (C) 2003 Constantin Kaplinsky. 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#ifdef linux -+#include "/usr/include/shadow.h" -+#endif -+#include -+#include -+#include -+#include -+#include -+#include "rfb.h" -+ -+void rfbLoginAuthProcessClientMessage(rfbClientPtr cl) -+{ -+ int n1 = 0, n2 = 0; -+ CARD32 loginLen, passwdLen, authResult; -+ char *loginBuf, *passwdBuf; -+ struct passwd *ps; -+ char *encPasswd1, *encPasswd2; -+ Bool ok; -+ -+ if ((n1 = ReadExact(cl->sock, (char *)&loginLen, -+ sizeof(loginLen))) <= 0 || -+ (n2 = ReadExact(cl->sock, (char *)&passwdLen, -+ sizeof(passwdLen))) <= 0) { -+ if (n1 != 0 || n2 != 0) -+ rfbLogPerror("rfbLoginAuthProcessClientMessage: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ loginLen = Swap32IfLE(loginLen); -+ passwdLen = Swap32IfLE(passwdLen); -+ loginBuf = (char *)malloc(loginLen + 1); -+ passwdBuf = (char *)malloc(passwdLen + 1); -+ -+ n1 = n2 = 0; -+ if ((n1 = ReadExact(cl->sock, loginBuf, loginLen)) <= 0 || -+ (n2 = ReadExact(cl->sock, passwdBuf, passwdLen)) <= 0) { -+ if (n1 != 0 || n2 != 0) -+ rfbLogPerror("rfbLoginAuthProcessClientMessage: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ loginBuf[loginLen] = '\0'; -+ passwdBuf[passwdLen] = '\0'; -+ -+ encPasswd1 = encPasswd2 = NULL; -+ -+ ps = getpwnam(loginBuf); -+ if (ps == NULL) { -+ rfbLog("rfbLoginAuthProcessClientMessage: " -+ "Cannot get password file entry for \"%s\"\n", loginBuf); -+ } else { -+ encPasswd1 = ps->pw_passwd; -+#ifdef linux -+ if (strlen(ps->pw_passwd) == 1) { -+ struct spwd *sps; -+ -+ sps = getspnam(loginBuf); -+ if (sps == NULL) { -+ rfbLog("rfbLoginAuthProcessClientMessage:" -+ " getspnam() failed for user \"%s\"\n", loginBuf); -+ } else { -+ encPasswd1 = sps->sp_pwdp; -+ } -+ } -+#endif -+ encPasswd2 = (char *)crypt(passwdBuf, encPasswd1); -+ memset(passwdBuf, 0, strlen(passwdBuf)); -+ } -+ -+ ok = FALSE; -+ if (encPasswd1 != NULL && encPasswd2 != NULL) { -+ if (strcmp(encPasswd1, encPasswd2) == 0) -+ ok = TRUE; -+ } -+ -+ if (!ok) { -+ rfbLog("rfbAuthProcessClientMessage: authentication failed from %s\n", -+ cl->host); -+ -+ if (rfbAuthConsiderBlocking(cl)) { -+ authResult = Swap32IfLE(rfbVncAuthTooMany); -+ } else { -+ authResult = Swap32IfLE(rfbVncAuthFailed); -+ } -+ -+ if (WriteExact(cl->sock, (char *)&authResult, -+ sizeof(authResult)) < 0) { -+ rfbLogPerror("rfbLoginAuthProcessClientMessage: write"); -+ } -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ rfbAuthUnblock(cl); -+ -+ cl->login = strdup(loginBuf); -+ rfbLog("Login-style authentication passed for user %s at %s\n", -+ cl->login, cl->host); -+ -+ authResult = Swap32IfLE(rfbVncAuthOK); -+ -+ if (WriteExact(cl->sock, (char *)&authResult, sizeof(authResult)) < 0) { -+ rfbLogPerror("rfbLoginAuthProcessClientMessage: write"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ cl->state = RFB_INITIALISATION; -+} -+ -diff -pruN xorg-server-1.12.1.orig/hw/vnc/Makefile.am xorg-server-1.12.1/hw/vnc/Makefile.am ---- xorg-server-1.12.1.orig/hw/vnc/Makefile.am 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/Makefile.am 2012-04-18 14:45:21.577820941 -0500 -@@ -0,0 +1,55 @@ -+# XXX This Makefile.am probably needs some work. -+ -+bin_PROGRAMS = Xvnc -+ -+Xvnc_SOURCES = \ -+ $(top_srcdir)/fb/fbcmap_mi.c \ -+ $(top_srcdir)/mi/miinitext.c \ -+ auth.c \ -+ cmap.c \ -+ corre.c \ -+ cursor.c \ -+ cutpaste.c \ -+ d3des.c \ -+ dispcur.c \ -+ dpmsstubs.c \ -+ draw.c \ -+ hextile.c \ -+ httpd.c \ -+ init.c \ -+ kbdptr.c \ -+ loginauth.c \ -+ rfbkeyb.c \ -+ rfbmouse.c \ -+ rfbserver.c \ -+ rre.c \ -+ sprite.c \ -+ sockets.c \ -+ stats.c \ -+ tight.c \ -+ translate.c \ -+ vncauth.c \ -+ vncext.c \ -+ xistubs.c \ -+ zlib.c -+ -+ -+JPEG_LIBS = -ljpeg -+CRYPT_LIBS = -lcrypt -+Z_LIBS = -lz -+ -+AM_CFLAGS = $(DIX_CFLAGS) $(XVNC_CFLAGS) -I$(top_srcdir)/hw/dmx/vnc -DCHROMIUM=1 -+ -+Xvnc_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) -+Xvnc_LDADD = \ -+ $(XORG_CORE_LIBS) \ -+ $(XVNC_LIBS) \ -+ $(JPEG_LIBS) \ -+ $(CRYPT_LIBS) \ -+ $(XSERVER_SYS_LIBS) \ -+ $(VNCMODULES_LIBS) \ -+ $(Z_LIBS) -+ -+ -+relink: -+ rm -f Xvnc && $(MAKE) Xvnc -diff -pruN xorg-server-1.12.1.orig/hw/vnc/rdp.c xorg-server-1.12.1/hw/vnc/rdp.c ---- xorg-server-1.12.1.orig/hw/vnc/rdp.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/rdp.c 2012-04-18 14:45:21.577820941 -0500 -@@ -0,0 +1,145 @@ -+/* -+ * Copyright (C) 2004 Alan Hourihane. 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "rfb.h" -+ -+typedef struct rdpClientRec { -+ ScreenPtr pScreen; -+} rdpClientRec, *rdpClientPtr; -+ -+typedef struct rdpInRec { -+ char version; -+ char pad; -+ short length; -+ char hdrlen; -+ unsigned char pdu; -+} rdpInRec, *rdpInPtr; -+#if 0 -+static void -+rdpCloseSock(ScreenPtr pScreen) -+{ -+ VNCSCREENPTR(pScreen); -+ close(pVNC->rdpListenSock); -+ RemoveEnabledDevice(pVNC->rdpListenSock); -+ pVNC->rdpListenSock = -1; -+} -+#endif -+/* -+ * rdpNewClient is called when a new connection has been made by whatever -+ * means. -+ */ -+#if 0 -+static rdpClientPtr -+rdpNewClient(ScreenPtr pScreen, int sock) -+{ -+ rdpInRec in; -+ rdpClientPtr cl; -+ -+ cl = (rdpClientPtr)malloc(sizeof(rdpClientRec)); -+ -+ cl->pScreen = pScreen; -+ -+ in.version = 3; -+ in.pad = 0; -+ in.length = 0x600; /* big endian */ -+ in.hdrlen = 0x00; -+ in.pdu = 0xCC; -+ -+ if (WriteExact(sock, (char *)&in, sizeof(rdpInRec)) < 0) { -+ rfbLogPerror("rfbNewClient: write"); -+ rdpCloseSock(pScreen); -+ return NULL; -+ } -+ -+ return cl; -+} -+#endif -+/* -+ * rdpCheckFds is called from ProcessInputEvents to check for input on the -+ * HTTP socket(s). If there is input to process, rdpProcessInput is called. -+ */ -+#if 0 -+static void -+rdpCheckFds(ScreenPtr pScreen) -+{ -+ VNCSCREENPTR(pScreen); -+ int nfds; -+ fd_set fds; -+ struct timeval tv; -+ struct sockaddr_in addr; -+ int sock; -+ const int one =1; -+ SOCKLEN_T addrlen = sizeof(addr); -+ -+ FD_ZERO(&fds); -+ FD_SET(pVNC->rdpListenSock, &fds); -+ tv.tv_sec = 0; -+ tv.tv_usec = 0; -+ nfds = select(pVNC->rdpListenSock + 1, &fds, NULL, NULL, &tv); -+ if (nfds == 0) { -+ return; -+ } -+ if (nfds < 0) { -+ if (errno != EINTR) -+ rfbLogPerror("httpCheckFds: select"); -+ return; -+ } -+ -+ if (pVNC->rdpListenSock != -1 && FD_ISSET(pVNC->rdpListenSock, &fds)) { -+ -+ if ((sock = accept(pVNC->rdpListenSock, -+ (struct sockaddr *)&addr, &addrlen)) < 0) { -+ rfbLogPerror("rdpCheckFds: accept"); -+ return; -+ } -+ -+ if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { -+ rfbLogPerror("rdpCheckFds: fcntl"); -+ close(sock); -+ return; -+ } -+ -+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, -+ (char *)&one, sizeof(one)) < 0) { -+ rfbLogPerror("rdpCheckFds: setsockopt"); -+ close(sock); -+ return; -+ } -+ -+ rfbLog("\n"); -+ -+ rfbLog("Got RDP connection from client %s\n", inet_ntoa(addr.sin_addr)); -+ -+ AddEnabledDevice(sock); -+ -+ rdpNewClient(pScreen, sock); -+ } -+} -+#endif -diff -pruN xorg-server-1.12.1.orig/hw/vnc/README xorg-server-1.12.1/hw/vnc/README ---- xorg-server-1.12.1.orig/hw/vnc/README 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/README 2012-04-18 14:45:21.577820941 -0500 -@@ -0,0 +1,14 @@ -+ -+This is the directory containing the code specific to the TightVNC X server (Xvnc). -+Note that within this directory the name RFB is still used instead of VNC. -+ -+NOTE: -+ -+The is the new XFree86 v4 architecture VNC server code. -+ -+Modified entirely by Alan Hourihane -+ -+For information please visit http://xf4vnc.sourceforge.net -+ -+Moved to X.org modular tree by Brian Paul. -+ -diff -pruN xorg-server-1.12.1.orig/hw/vnc/rfb.h xorg-server-1.12.1/hw/vnc/rfb.h ---- xorg-server-1.12.1.orig/hw/vnc/rfb.h 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/rfb.h 2012-04-18 15:58:19.960083626 -0500 -@@ -0,0 +1,747 @@ -+/* -+ * rfb.h - header file for RFB DDX implementation. -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * Copyright (C) 2000-2004 Const Kaplinsky. All Rights Reserved. -+ * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. -+ * 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. -+ */ -+ -+#ifndef RFB_H_INCLUDED -+#define RFB_H_INCLUDED -+ -+#ifdef HAVE_DMX_CONFIG_H -+#include "dmx-config.h" -+#endif -+ -+#ifdef DMXVNC -+#include -+#else -+#include -+#endif -+ -+#include -+#ifdef XFREE86VNC -+#include "xf86.h" -+#endif -+#include "scrnintstr.h" -+#include "colormapst.h" -+#include "dixstruct.h" -+#include "gcstruct.h" -+#include "regionstr.h" -+#include "windowstr.h" -+#include "dixfontstr.h" -+#include "mipointer.h" -+#include -+#include -+#define _VNC_SERVER -+#include -+#include "picturestr.h" -+ -+#if defined(sun) || defined(hpux) -+#define SOCKLEN_T int -+#else -+#define SOCKLEN_T socklen_t -+#endif -+ -+/* It's a good idea to keep these values a bit greater than required. */ -+#define MAX_ENCODINGS 10 -+#define MAX_SECURITY_TYPES 4 -+#define MAX_TUNNELING_CAPS 16 -+#define MAX_AUTH_CAPS 16 -+ -+/* -+ * HTTP_BUF_SIZE for http transfers -+ */ -+#define HTTP_BUF_SIZE 32768 -+ -+/* -+ * UPDATE_BUF_SIZE must be big enough to send at least one whole line of the -+ * framebuffer. So for a max screen width of say 2K with 32-bit pixels this -+ * means 8K minimum. -+ */ -+#define UPDATE_BUF_SIZE 30000 -+ -+extern DevPrivateKey VNCScreenKey; -+extern DevPrivateKey rfbGCKey; -+ -+#if XFREE86VNC || defined(DMXVNC) -+#include "vncint.h" -+#define VNCSCREENPTR(ptr) \ -+ vncScreenPtr pVNC = VNCPTR(ptr) -+#else -+#define VNCSCREENPTR(ptr) \ -+/* Soon \ -+ rfbScreenInfoPtr pVNC = rfbScreen[ptr->myNum] \ -+*/ \ -+ rfbScreenInfoPtr pVNC = &rfbScreen -+#endif -+ -+/* -+ * Per-screen (framebuffer) structure. There is only one of these, since we -+ * don't allow the X server to have multiple screens. -+ */ -+ -+typedef struct -+{ -+ int rfbPort; -+ int rdpPort; -+ int udpPort; -+ int rfbListenSock; -+ int rdpListenSock; -+ int udpSock; -+ int httpPort; -+ int httpListenSock; -+ int httpSock; -+ char * httpDir; -+ char buf[HTTP_BUF_SIZE]; -+ Bool udpSockConnected; -+ char * rfbAuthPasswdFile; -+ size_t buf_filled; -+ int maxFd; -+ fd_set allFds; -+ Bool noCursor; -+ Bool rfbAlwaysShared; -+ Bool rfbNeverShared; -+ Bool rfbDontDisconnect; -+ Bool rfbUserAccept; -+ Bool rfbViewOnly; -+ ColormapPtr savedColormap; -+ ColormapPtr rfbInstalledColormap; -+ rfbPixelFormat rfbServerFormat; -+ Bool rfbAuthTooManyTries; -+ int rfbAuthTries; -+ Bool loginAuthEnabled; -+ struct in_addr interface; -+ OsTimerPtr timer; -+ unsigned char updateBuf[UPDATE_BUF_SIZE]; -+ int ublen; -+ int width; -+ int paddedWidthInBytes; -+ int height; -+ int depth; -+ int bitsPerPixel; -+ int sizeInBytes; -+ unsigned char *pfbMemory; -+ Pixel blackPixel; -+ Pixel whitePixel; -+ -+ /* The following two members are used to minimise the amount of unnecessary -+ drawing caused by cursor movement. Whenever any drawing affects the -+ part of the screen where the cursor is, the cursor is removed first and -+ then the drawing is done (this is what the sprite routines test for). -+ Afterwards, however, we do not replace the cursor, even when the cursor -+ is logically being moved across the screen. We only draw the cursor -+ again just as we are about to send the client a framebuffer update. -+ -+ We need to be careful when removing and drawing the cursor because of -+ their relationship with the normal drawing routines. The drawing -+ routines can invoke the cursor routines, but also the cursor routines -+ themselves end up invoking drawing routines. -+ -+ Removing the cursor (rfbSpriteRemoveCursor) is eventually achieved by -+ doing a CopyArea from a pixmap to the screen, where the pixmap contains -+ the saved contents of the screen under the cursor. Before doing this, -+ however, we set cursorIsDrawn to FALSE. Then, when CopyArea is called, -+ it sees that cursorIsDrawn is FALSE and so doesn't feel the need to -+ (recursively!) remove the cursor before doing it. -+ -+ Putting up the cursor (rfbSpriteRestoreCursor) involves a call to -+ PushPixels. While this is happening, cursorIsDrawn must be FALSE so -+ that PushPixels doesn't think it has to remove the cursor first. -+ Obviously cursorIsDrawn is set to TRUE afterwards. -+ -+ Another problem we face is that drawing routines sometimes cause a -+ framebuffer update to be sent to the RFB client. When the RFB client is -+ already waiting for a framebuffer update and some drawing to the -+ framebuffer then happens, the drawing routine sees that the client is -+ ready, so it calls rfbSendFramebufferUpdate. If the cursor is not drawn -+ at this stage, it must be put up, and so rfbSpriteRestoreCursor is -+ called. However, if the original drawing routine was actually called -+ from within rfbSpriteRestoreCursor or rfbSpriteRemoveCursor we don't -+ want this to happen. So both the cursor routines set -+ dontSendFramebufferUpdate to TRUE, and all the drawing routines check -+ this before calling rfbSendFramebufferUpdate. */ -+ -+ Bool cursorIsDrawn; /* TRUE if the cursor is currently drawn */ -+ Bool dontSendFramebufferUpdate; /* TRUE while removing or drawing the -+ cursor */ -+ -+ /* wrapped screen functions */ -+ -+ CloseScreenProcPtr CloseScreen; -+ CreateGCProcPtr CreateGC; -+ CopyWindowProcPtr CopyWindow; -+ ClearToBackgroundProcPtr ClearToBackground; -+ ScreenWakeupHandlerProcPtr WakeupHandler; -+#ifdef CHROMIUM -+ RealizeWindowProcPtr RealizeWindow; -+ UnrealizeWindowProcPtr UnrealizeWindow; -+ DestroyWindowProcPtr DestroyWindow; -+ ResizeWindowProcPtr ResizeWindow; -+ PositionWindowProcPtr PositionWindow; -+ ClipNotifyProcPtr ClipNotify; -+#endif -+#ifdef RENDER -+ CompositeProcPtr Composite; -+#endif -+ -+} rfbScreenInfo, *rfbScreenInfoPtr; -+ -+ -+/* -+ * rfbTranslateFnType is the type of translation functions. -+ */ -+ -+struct rfbClientRec; -+typedef void (*rfbTranslateFnType)(ScreenPtr pScreen, -+ char *table, rfbPixelFormat *in, -+ rfbPixelFormat *out, -+ unsigned char *optr, -+ int bytesBetweenInputLines, -+ int width, int height, -+ int x, int y); -+ -+ -+/* -+ * Per-client structure. -+ */ -+ -+typedef struct rfbClientRec { -+ int sock; -+ char *host; -+ char *login; -+ -+ int protocol_minor_ver; /* RFB protocol minor version in use. */ -+ Bool protocol_tightvnc; /* TightVNC protocol extensions enabled */ -+ -+ /* Possible client states: */ -+ -+ enum { -+ RFB_PROTOCOL_VERSION, /* establishing protocol version */ -+ RFB_SECURITY_TYPE, /* negotiating security (RFB v.3.7) */ -+ RFB_TUNNELING_TYPE, /* establishing tunneling (RFB v.3.7t) */ -+ RFB_AUTH_TYPE, /* negotiating authentication (RFB v.3.7t) */ -+ RFB_AUTHENTICATION, /* authenticating (VNC authentication) */ -+ RFB_INITIALISATION, /* sending initialisation messages */ -+ RFB_NORMAL /* normal protocol messages */ -+ } state; -+ -+ Bool viewOnly; /* Do not accept input from this client. */ -+ -+ Bool reverseConnection; -+ -+ Bool readyForSetColourMapEntries; -+ -+ Bool useCopyRect; -+ int preferredEncoding; -+ int correMaxWidth, correMaxHeight; -+ -+ /* The list of security types sent to this client (protocol 3.7). -+ Note that the first entry is the number of list items following. */ -+ -+ CARD8 securityTypes[MAX_SECURITY_TYPES + 1]; -+ -+ /* Lists of capability codes sent to clients. We remember these -+ lists to restrict clients from choosing those tunneling and -+ authentication types that were not advertised. */ -+ -+ int nAuthCaps; -+ CARD32 authCaps[MAX_AUTH_CAPS]; -+ -+ /* This is not useful while we don't support tunneling: -+ int nTunnelingCaps; -+ CARD32 tunnelingCaps[MAX_TUNNELING_CAPS]; */ -+ -+ /* The following member is only used during VNC authentication */ -+ -+ CARD8 authChallenge[CHALLENGESIZE]; -+ -+ /* The following members represent the update needed to get the client's -+ framebuffer from its present state to the current state of our -+ framebuffer. -+ -+ If the client does not accept CopyRect encoding then the update is -+ simply represented as the region of the screen which has been modified -+ (modifiedRegion). -+ -+ If the client does accept CopyRect encoding, then the update consists of -+ two parts. First we have a single copy from one region of the screen to -+ another (the destination of the copy is copyRegion), and second we have -+ the region of the screen which has been modified in some other way -+ (modifiedRegion). -+ -+ Although the copy is of a single region, this region may have many -+ rectangles. When sending an update, the copyRegion is always sent -+ before the modifiedRegion. This is because the modifiedRegion may -+ overlap parts of the screen which are in the source of the copy. -+ -+ In fact during normal processing, the modifiedRegion may even overlap -+ the destination copyRegion. Just before an update is sent we remove -+ from the copyRegion anything in the modifiedRegion. */ -+ -+ RegionRec copyRegion; /* the destination region of the copy */ -+ int copyDX, copyDY; /* the translation by which the copy happens */ -+ -+ RegionRec modifiedRegion; /* the region of the screen modified in any -+ other way */ -+ -+ /* As part of the FramebufferUpdateRequest, a client can express interest -+ in a subrectangle of the whole framebuffer. This is stored in the -+ requestedRegion member. In the normal case this is the whole -+ framebuffer if the client is ready, empty if it's not. */ -+ -+ RegionRec requestedRegion; -+ -+ /* The following members represent the state of the "deferred update" timer -+ - when the framebuffer is modified and the client is ready, in most -+ cases it is more efficient to defer sending the update by a few -+ milliseconds so that several changes to the framebuffer can be combined -+ into a single update. */ -+ -+ Bool deferredUpdateScheduled; -+ OsTimerPtr deferredUpdateTimer; -+ -+ /* translateFn points to the translation function which is used to copy -+ and translate a rectangle from the framebuffer to an output buffer. */ -+ -+ rfbTranslateFnType translateFn; -+ -+ char *translateLookupTable; -+ -+ rfbPixelFormat format; -+ -+ /* statistics */ -+ -+ int rfbBytesSent[MAX_ENCODINGS]; -+ int rfbRectanglesSent[MAX_ENCODINGS]; -+ int rfbLastRectMarkersSent; -+ int rfbLastRectBytesSent; -+ int rfbCursorShapeBytesSent; -+ int rfbCursorShapeUpdatesSent; -+ int rfbCursorPosBytesSent; -+ int rfbCursorPosUpdatesSent; -+ int rfbFramebufferUpdateMessagesSent; -+ int rfbRawBytesEquivalent; -+ int rfbKeyEventsRcvd; -+ int rfbPointerEventsRcvd; -+ -+ /* zlib encoding -- necessary compression state info per client */ -+ -+ struct z_stream_s compStream; -+ Bool compStreamInited; -+ -+ CARD32 zlibCompressLevel; -+ -+ /* tight encoding -- preserve zlib streams' state for each client */ -+ -+ z_stream zsStruct[4]; -+ Bool zsActive[4]; -+ int zsLevel[4]; -+ int tightCompressLevel; -+ int tightQualityLevel; -+ -+ Bool enableLastRectEncoding; /* client supports LastRect encoding */ -+ Bool enableCursorShapeUpdates; /* client supports cursor shape updates */ -+ Bool enableCursorPosUpdates; /* client supports PointerPos updates */ -+#ifdef CHROMIUM -+ Bool enableChromiumEncoding; /* client supports Chromium encoding */ -+#endif -+ Bool useRichCursorEncoding; /* rfbEncodingRichCursor is preferred */ -+ Bool cursorWasChanged; /* cursor shape update should be sent */ -+ Bool cursorWasMoved; /* cursor position update should be sent */ -+ -+ int cursorX, cursorY; /* client's cursor position */ -+ -+ struct rfbClientRec *next; -+ -+ ScreenPtr pScreen; -+ int userAccepted; -+ -+#ifdef CHROMIUM -+ unsigned int chromium_port; -+ unsigned int chromium_msport; -+#endif -+} rfbClientRec, *rfbClientPtr; -+ -+#ifdef CHROMIUM -+typedef struct CRWindowTable { -+ unsigned long CRwinId; -+ unsigned long XwinId; -+ BoxPtr clipRects; -+ int numRects; -+ struct CRWindowTable *next; -+} CRWindowTable, *CRWindowTablePtr; -+ -+extern struct CRWindowTable *windowTable; -+#endif -+ -+/* -+ * This macro is used to test whether there is a framebuffer update needing to -+ * be sent to the client. -+ */ -+ -+#define FB_UPDATE_PENDING(cl) \ -+ ((!(cl)->enableCursorShapeUpdates && !pVNC->cursorIsDrawn) || \ -+ ((cl)->enableCursorShapeUpdates && (cl)->cursorWasChanged) || \ -+ ((cl)->enableCursorPosUpdates && (cl)->cursorWasMoved) || \ -+ REGION_NOTEMPTY(((cl)->pScreen),&(cl)->copyRegion) || \ -+ REGION_NOTEMPTY(((cl)->pScreen),&(cl)->modifiedRegion)) -+ -+/* -+ * This macro creates an empty region (ie. a region with no areas) if it is -+ * given a rectangle with a width or height of zero. It appears that -+ * REGION_INTERSECT does not quite do the right thing with zero-width -+ * rectangles, but it should with completely empty regions. -+ */ -+ -+#define SAFE_REGION_INIT(pscreen, preg, rect, size) \ -+{ \ -+ if ( \ -+ ( ( (rect)->x2 == (rect)->x1 ) || \ -+ ( (rect)->y2 == (rect)->y1 ) ) ) { \ -+ REGION_NULL( (pscreen), (preg) ); \ -+ } else { \ -+ REGION_INIT( (pscreen), (preg), (rect), (size) ); \ -+ } \ -+} -+ -+/* -+ * An rfbGCRec is where we store the pointers to the original GC funcs and ops -+ * which we wrap (NULL means not wrapped). -+ */ -+ -+typedef struct { -+ GCFuncs *wrapFuncs; -+ GCOps *wrapOps; -+} rfbGCRec, *rfbGCPtr; -+ -+ -+ -+/* -+ * Macros for endian swapping. -+ */ -+ -+#define Swap16(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) -+ -+#define Swap32(l) (((l) >> 24) | \ -+ (((l) & 0x00ff0000) >> 8) | \ -+ (((l) & 0x0000ff00) << 8) | \ -+ ((l) << 24)) -+ -+static const int rfbEndianTest = 1; -+ -+#define Swap16IfLE(s) (*(const char *)&rfbEndianTest ? Swap16(s) : (s)) -+ -+#define Swap32IfLE(l) (*(const char *)&rfbEndianTest ? Swap32(l) : (l)) -+ -+ -+/* -+ * Macro to fill in an rfbCapabilityInfo structure (protocol 3.130). -+ * Normally, using macros is no good, but this macro saves us from -+ * writing constants twice -- it constructs signature names from codes. -+ * Note that "code_sym" argument should be a single symbol, not an expression. -+ */ -+ -+#define SetCapInfo(cap_ptr, code_sym, vendor) \ -+{ \ -+ rfbCapabilityInfo *pcap; \ -+ pcap = (cap_ptr); \ -+ pcap->code = Swap32IfLE(code_sym); \ -+ memcpy(pcap->vendorSignature, (vendor), \ -+ sz_rfbCapabilityInfoVendor); \ -+ memcpy(pcap->nameSignature, sig_##code_sym, \ -+ sz_rfbCapabilityInfoName); \ -+} -+ -+ -+/* init.c */ -+ -+extern char *desktopName; -+extern char rfbThisHost[]; -+extern Atom VNC_LAST_CLIENT_ID; -+ -+extern rfbScreenInfo rfbScreen; -+ -+extern int inetdSock; -+ -+extern int rfbBitsPerPixel(int depth); -+extern void rfbLog(char *format, ...); -+extern void rfbLogPerror(char *str); -+ -+ -+/* sockets.c */ -+ -+extern int rfbMaxClientWait; -+ -+extern Bool rfbInitSockets(ScreenPtr pScreen); -+extern void rfbDisconnectUDPSock(ScreenPtr pScreen); -+extern void rfbCloseSock(ScreenPtr pScreen, int sock); -+extern void rfbCheckFds(ScreenPtr pScreen); -+extern void rfbWaitForClient(int sock); -+extern int rfbConnect(ScreenPtr pScreen, char *host, int port); -+ -+extern int ReadExact(int sock, char *buf, int len); -+extern int WriteExact(int sock, char *buf, int len); -+extern int ListenOnTCPPort(ScreenPtr pScreen, int port); -+extern int ListenOnUDPPort(ScreenPtr pScreen, int port); -+extern int ConnectToTcpAddr(char *host, int port); -+ -+ -+/* cmap.c */ -+ -+ -+extern int rfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps); -+extern void rfbInstallColormap(ColormapPtr pmap); -+extern void rfbUninstallColormap(ColormapPtr pmap); -+extern void rfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs); -+ -+ -+/* draw.c */ -+ -+extern int rfbDeferUpdateTime; -+ -+extern void -+rfbComposite( -+ CARD8 op, -+ PicturePtr pSrc, -+ PicturePtr pMask, -+ PicturePtr pDst, -+ INT16 xSrc, -+ INT16 ySrc, -+ INT16 xMask, -+ INT16 yMask, -+ INT16 xDst, -+ INT16 yDst, -+ CARD16 width, -+ CARD16 height -+); -+ -+extern void rfbGlyphs( -+ CARD8 op, -+ PicturePtr pSrc, -+ PicturePtr pDst, -+ PictFormatPtr maskFormat, -+ INT16 xSrc, -+ INT16 ySrc, -+ int nlistInit, -+ GlyphListPtr listInit, -+ GlyphPtr *glyphsInit -+); -+extern Bool rfbCloseScreen(int,ScreenPtr); -+extern Bool rfbCreateGC(GCPtr); -+extern void rfbPaintWindowBackground(WindowPtr, RegionPtr, int what); -+extern void rfbPaintWindowBorder(WindowPtr, RegionPtr, int what); -+extern void rfbCopyWindow(WindowPtr, DDXPointRec, RegionPtr); -+#ifdef CHROMIUM -+extern Bool rfbRealizeWindow(WindowPtr); -+extern Bool rfbUnrealizeWindow(WindowPtr); -+extern Bool rfbDestroyWindow(WindowPtr); -+extern void rfbResizeWindow(WindowPtr, int x, int y, unsigned int w, unsigned int h, WindowPtr pSib); -+extern Bool rfbPositionWindow(WindowPtr, int x, int y); -+extern void rfbClipNotify(WindowPtr, int x, int y); -+#endif -+extern void rfbClearToBackground(WindowPtr, int x, int y, int w, -+ int h, Bool generateExposures); -+extern void rfbScheduleUpdate(ScreenPtr pScreen); -+ -+/* dispcur.c */ -+extern Bool rfbDCInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs); -+ -+ -+/* cutpaste.c */ -+ -+extern void rfbSetXCutText(char *str, int len); -+extern void rfbGotXCutText(char *str, int len); -+ -+ -+/* kbdptr.c */ -+ -+extern Bool compatibleKbd; -+extern unsigned char ptrAcceleration; -+ -+extern void PtrDeviceInit(void); -+extern void PtrDeviceOn(DeviceIntPtr pDev); -+extern void PtrDeviceOff(void); -+extern void PtrDeviceControl(DeviceIntPtr dev, PtrCtrl *ctrl); -+extern void PtrAddEvent(int buttonMask, int x, int y, rfbClientPtr cl); -+ -+extern void KbdDeviceInit(DeviceIntPtr pDevice, KeySymsPtr pKeySyms, CARD8 *pModMap); -+extern void KbdDeviceOn(void); -+extern void KbdDeviceOff(void); -+extern void KbdAddEvent(Bool down, KeySym keySym, rfbClientPtr cl); -+extern void KbdReleaseAllKeys(void); -+ -+extern void vncSetKeyboardDevice(DeviceIntPtr kbd); -+extern void vncSetPointerDevice(DeviceIntPtr ptr); -+ -+ -+/* rfbserver.c */ -+ -+ -+extern rfbClientPtr rfbClientHead; -+extern rfbClientPtr pointerClient; -+ -+extern void rfbNewClientConnection(ScreenPtr pScreen, int sock); -+extern rfbClientPtr rfbReverseConnection(ScreenPtr pScreen, char *host, int port); -+extern void rfbRootPropertyChange(ScreenPtr pScreen); -+extern void rfbClientConnectionGone(int sock); -+extern void rfbProcessClientMessage(ScreenPtr pScreen, int sock); -+extern void rfbClientConnFailed(rfbClientPtr cl, char *reason); -+extern void rfbNewUDPConnection(int sock); -+extern void rfbProcessUDPInput(ScreenPtr pScreen, int sock); -+extern Bool rfbSendFramebufferUpdate(ScreenPtr pScreen, rfbClientPtr cl); -+extern Bool rfbSendRectEncodingRaw(rfbClientPtr cl, int x,int y,int w,int h); -+extern Bool rfbSendUpdateBuf(rfbClientPtr cl); -+extern Bool rfbSendSetColourMapEntries(rfbClientPtr cl, int firstColour, -+ int nColours); -+extern void rfbSendBell(void); -+extern void rfbSendServerCutText(char *str, int len); -+extern void rfbUserAllow(int sock, int accept); -+extern void rfbSetClip (WindowPtr pWin, BOOL enable); -+ -+extern int GenerateVncConnectedEvent(int sock); -+extern int GenerateVncDisconnectedEvent(int sock); -+ -+#ifdef CHROMIUM -+extern void rfbSendChromiumWindowShow(unsigned int winid, unsigned int show); -+extern void rfbSendChromiumWindowDestroy(unsigned int winid); -+extern void rfbSendChromiumMoveResizeWindow(unsigned int winid, int x, int y, unsigned int w, unsigned int h); -+extern void rfbSendChromiumClipList(unsigned int winid, BoxPtr pClipRects, int numClipRects); -+#endif -+ -+/* translate.c */ -+ -+extern Bool rfbEconomicTranslate; -+ -+extern void rfbTranslateNone(ScreenPtr pScreen, char *table, rfbPixelFormat *in, -+ rfbPixelFormat *out, -+ unsigned char *optr, -+ int bytesBetweenInputLines, -+ int width, int height, -+ int x, int y); -+extern Bool rfbSetTranslateFunction(rfbClientPtr cl); -+extern void rfbSetClientColourMaps(int firstColour, int nColours); -+extern Bool rfbSetClientColourMap(rfbClientPtr cl, int firstColour, -+ int nColours); -+ -+ -+/* httpd.c */ -+ -+extern Bool httpInitSockets(ScreenPtr pScreen); -+extern void httpCheckFds(ScreenPtr pScreen); -+ -+ -+/* vncInit.c */ -+extern void VNCInitForDMX(void); -+extern void rfbWakeupHandlerDMX(void); -+ -+ -+/* vncext.c */ -+ -+#ifdef CHROMIUM -+extern void rfbSendChromiumStart(unsigned int ipaddress, unsigned int crServerPort, unsigned int mothershipPort); -+extern void rfbChromiumMonitorWindowID(unsigned int cr_windowid, unsigned long windowid); -+int GenerateVncChromiumConnectedEvent(int sock); -+#endif -+ -+ -+/* auth.c */ -+ -+extern void rfbAuthNewClient(rfbClientPtr cl); -+extern void rfbProcessClientSecurityType(rfbClientPtr cl); -+extern void rfbProcessClientTunnelingType(rfbClientPtr cl); -+extern void rfbProcessClientAuthType(rfbClientPtr cl); -+extern void rfbVncAuthProcessResponse(rfbClientPtr cl); -+ -+/* Functions to prevent too many successive authentication failures */ -+extern Bool rfbAuthConsiderBlocking(rfbClientPtr cl); -+extern void rfbAuthUnblock(rfbClientPtr cl); -+extern Bool rfbAuthIsBlocked(rfbClientPtr cl); -+ -+/* loginauth.c */ -+ -+extern void rfbLoginAuthProcessClientMessage(rfbClientPtr cl); -+ -+/* rre.c */ -+ -+extern Bool rfbSendRectEncodingRRE(rfbClientPtr cl, int x,int y,int w,int h); -+ -+ -+/* corre.c */ -+ -+extern Bool rfbSendRectEncodingCoRRE(rfbClientPtr cl, int x,int y,int w,int h); -+ -+ -+/* hextile.c */ -+ -+extern Bool rfbSendRectEncodingHextile(rfbClientPtr cl, int x, int y, int w, -+ int h); -+ -+ -+/* zlib.c */ -+ -+/* Minimum zlib rectangle size in bytes. Anything smaller will -+ * not compress well due to overhead. -+ */ -+#define VNC_ENCODE_ZLIB_MIN_COMP_SIZE (17) -+ -+/* Set maximum zlib rectangle size in pixels. Always allow at least -+ * two scan lines. -+ */ -+#define ZLIB_MAX_RECT_SIZE (128*256) -+#define ZLIB_MAX_SIZE(min) ((( min * 2 ) > ZLIB_MAX_RECT_SIZE ) ? \ -+ ( min * 2 ) : ZLIB_MAX_RECT_SIZE ) -+ -+extern Bool rfbSendRectEncodingZlib(rfbClientPtr cl, int x, int y, int w, -+ int h); -+ -+ -+/* tight.c */ -+ -+#define TIGHT_DEFAULT_COMPRESSION 6 -+ -+extern Bool rfbTightDisableGradient; -+ -+extern int rfbNumCodedRectsTight(rfbClientPtr cl, int x,int y,int w,int h); -+extern Bool rfbSendRectEncodingTight(rfbClientPtr cl, int x,int y,int w,int h); -+ -+ -+/* cursor.c */ -+ -+extern Bool rfbSendCursorShape(rfbClientPtr cl, ScreenPtr pScreen); -+extern Bool rfbSendCursorPos(rfbClientPtr cl, ScreenPtr pScreen); -+ -+ -+/* stats.c */ -+ -+extern void rfbResetStats(rfbClientPtr cl); -+extern void rfbPrintStats(rfbClientPtr cl); -+ -+ -+/* dpms.c */ -+ -+extern Bool DPMSSupported(void); -+extern int DPSMGet(int *level); -+extern int DPMSSet(ClientPtr client, int level); -+ -+ -+#endif /* RFB_H_INCLUDED */ -diff -pruN xorg-server-1.12.1.orig/hw/vnc/rfbkeyb.c xorg-server-1.12.1/hw/vnc/rfbkeyb.c ---- xorg-server-1.12.1.orig/hw/vnc/rfbkeyb.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/rfbkeyb.c 2012-04-18 16:18:07.674235155 -0500 -@@ -0,0 +1,519 @@ -+/* -+ * Copyright (C) 2002 Alan Hourihane. 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. -+ * -+ * Author: Alan Hourihane -+ */ -+ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#if XFREE86VNC -+#ifndef XFree86LOADER -+#include -+#include -+#endif -+ -+#include -+#include -+#if !defined(DGUX) -+#include -+#endif -+#include -+#include /* Needed for InitValuator/Proximity stuff */ -+#include -+ -+#ifdef XFree86LOADER -+#include -+#endif -+#else -+#include -+#include -+#endif -+#include "rfb.h" -+ -+ -+extern void rfbSendBell(void); -+extern DeviceIntPtr kbdDevice; -+extern void vncInitKeyb(void); -+ -+#include -+#include "keyboard.h" -+ -+#ifdef XKB -+#include -+#include -+#include -+ -+#if XFREE86VNC -+ /* -+ * would like to use an XkbComponentNamesRec here but can't without -+ * pulling in a bunch of header files. :-( -+ */ -+static char * xkbkeymap; -+static char * xkbkeycodes; -+static char * xkbtypes; -+static char * xkbcompat; -+static char * xkbsymbols; -+static char * xkbgeometry; -+static Bool xkbcomponents_specified; -+static char * xkbrules; -+static char * xkbmodel; -+static char * xkblayout; -+static char * xkbvariant; -+static char * xkboptions; -+#endif -+#endif -+ -+static KeySym map[MAX_KEY_CODE * GLYPHS_PER_KEY] = { -+ /* 0x00 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x01 */ XK_Escape, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x02 */ XK_1, XK_exclam, NoSymbol, NoSymbol, -+ /* 0x03 */ XK_2, XK_at, NoSymbol, NoSymbol, -+ /* 0x04 */ XK_3, XK_numbersign, NoSymbol, NoSymbol, -+ /* 0x05 */ XK_4, XK_dollar, NoSymbol, NoSymbol, -+ /* 0x06 */ XK_5, XK_percent, NoSymbol, NoSymbol, -+ /* 0x07 */ XK_6, XK_asciicircum, NoSymbol, NoSymbol, -+ /* 0x08 */ XK_7, XK_ampersand, NoSymbol, NoSymbol, -+ /* 0x09 */ XK_8, XK_asterisk, NoSymbol, NoSymbol, -+ /* 0x0a */ XK_9, XK_parenleft, NoSymbol, NoSymbol, -+ /* 0x0b */ XK_0, XK_parenright, NoSymbol, NoSymbol, -+ /* 0x0c */ XK_minus, XK_underscore, NoSymbol, NoSymbol, -+ /* 0x0d */ XK_equal, XK_plus, NoSymbol, NoSymbol, -+ /* 0x0e */ XK_BackSpace, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x0f */ XK_Tab, XK_ISO_Left_Tab,NoSymbol, NoSymbol, -+ /* 0x10 */ XK_q, XK_Q, NoSymbol, NoSymbol, -+ /* 0x11 */ XK_w, XK_W, NoSymbol, NoSymbol, -+ /* 0x12 */ XK_e, XK_E, NoSymbol, NoSymbol, -+ /* 0x13 */ XK_r, XK_R, NoSymbol, NoSymbol, -+ /* 0x14 */ XK_t, XK_T, NoSymbol, NoSymbol, -+ /* 0x15 */ XK_y, XK_Y, NoSymbol, NoSymbol, -+ /* 0x16 */ XK_u, XK_U, NoSymbol, NoSymbol, -+ /* 0x17 */ XK_i, XK_I, NoSymbol, NoSymbol, -+ /* 0x18 */ XK_o, XK_O, NoSymbol, NoSymbol, -+ /* 0x19 */ XK_p, XK_P, NoSymbol, NoSymbol, -+ /* 0x1a */ XK_bracketleft, XK_braceleft, NoSymbol, NoSymbol, -+ /* 0x1b */ XK_bracketright,XK_braceright, NoSymbol, NoSymbol, -+ /* 0x1c */ XK_Return, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x1d */ XK_Control_L, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x1e */ XK_a, XK_A, NoSymbol, NoSymbol, -+ /* 0x1f */ XK_s, XK_S, NoSymbol, NoSymbol, -+ /* 0x20 */ XK_d, XK_D, NoSymbol, NoSymbol, -+ /* 0x21 */ XK_f, XK_F, NoSymbol, NoSymbol, -+ /* 0x22 */ XK_g, XK_G, NoSymbol, NoSymbol, -+ /* 0x23 */ XK_h, XK_H, NoSymbol, NoSymbol, -+ /* 0x24 */ XK_j, XK_J, NoSymbol, NoSymbol, -+ /* 0x25 */ XK_k, XK_K, NoSymbol, NoSymbol, -+ /* 0x26 */ XK_l, XK_L, NoSymbol, NoSymbol, -+ /* 0x27 */ XK_semicolon, XK_colon, NoSymbol, NoSymbol, -+ /* 0x28 */ XK_quoteright, XK_quotedbl, NoSymbol, NoSymbol, -+ /* 0x29 */ XK_quoteleft, XK_asciitilde, NoSymbol, NoSymbol, -+ /* 0x2a */ XK_Shift_L, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x2b */ XK_backslash, XK_bar, NoSymbol, NoSymbol, -+ /* 0x2c */ XK_z, XK_Z, NoSymbol, NoSymbol, -+ /* 0x2d */ XK_x, XK_X, NoSymbol, NoSymbol, -+ /* 0x2e */ XK_c, XK_C, NoSymbol, NoSymbol, -+ /* 0x2f */ XK_v, XK_V, NoSymbol, NoSymbol, -+ /* 0x30 */ XK_b, XK_B, NoSymbol, NoSymbol, -+ /* 0x31 */ XK_n, XK_N, NoSymbol, NoSymbol, -+ /* 0x32 */ XK_m, XK_M, NoSymbol, NoSymbol, -+ /* 0x33 */ XK_comma, XK_less, NoSymbol, NoSymbol, -+ /* 0x34 */ XK_period, XK_greater, NoSymbol, NoSymbol, -+ /* 0x35 */ XK_slash, XK_question, NoSymbol, NoSymbol, -+ /* 0x36 */ XK_Shift_R, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x37 */ XK_KP_Multiply, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x38 */ XK_Alt_L, XK_Meta_L, NoSymbol, NoSymbol, -+ /* 0x39 */ XK_space, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x3a */ XK_Caps_Lock, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x3b */ XK_F1, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x3c */ XK_F2, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x3d */ XK_F3, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x3e */ XK_F4, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x3f */ XK_F5, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x40 */ XK_F6, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x41 */ XK_F7, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x42 */ XK_F8, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x43 */ XK_F9, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x44 */ XK_F10, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x45 */ XK_Num_Lock, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x46 */ XK_Scroll_Lock, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x47 */ XK_KP_Home, XK_KP_7, NoSymbol, NoSymbol, -+ /* 0x48 */ XK_KP_Up, XK_KP_8, NoSymbol, NoSymbol, -+ /* 0x49 */ XK_KP_Prior, XK_KP_9, NoSymbol, NoSymbol, -+ /* 0x4a */ XK_KP_Subtract, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x4b */ XK_KP_Left, XK_KP_4, NoSymbol, NoSymbol, -+ /* 0x4c */ XK_KP_Begin, XK_KP_5, NoSymbol, NoSymbol, -+ /* 0x4d */ XK_KP_Right, XK_KP_6, NoSymbol, NoSymbol, -+ /* 0x4e */ XK_KP_Add, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x4f */ XK_KP_End, XK_KP_1, NoSymbol, NoSymbol, -+ /* 0x50 */ XK_KP_Down, XK_KP_2, NoSymbol, NoSymbol, -+ /* 0x51 */ XK_KP_Next, XK_KP_3, NoSymbol, NoSymbol, -+ /* 0x52 */ XK_KP_Insert, XK_KP_0, NoSymbol, NoSymbol, -+ /* 0x53 */ XK_KP_Delete, XK_KP_Decimal, NoSymbol, NoSymbol, -+ /* 0x54 */ XK_Sys_Req, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x55 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x56 */ XK_less, XK_greater, NoSymbol, NoSymbol, -+ /* 0x57 */ XK_F11, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x58 */ XK_F12, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x59 */ XK_Home, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x5a */ XK_Up, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x5b */ XK_Prior, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x5c */ XK_Left, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x5d */ XK_Begin, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x5e */ XK_Right, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x5f */ XK_End, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x60 */ XK_Down, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x61 */ XK_Next, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x62 */ XK_Insert, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x63 */ XK_Delete, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x64 */ XK_KP_Enter, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x65 */ XK_Control_R, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x66 */ XK_Pause, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x67 */ XK_Print, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x68 */ XK_KP_Divide, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x69 */ XK_Alt_R, XK_Meta_R, NoSymbol, NoSymbol, -+ /* 0x6a */ XK_Break, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x6b */ XK_Meta_L, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x6c */ XK_Meta_R, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x6d */ XK_Menu, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x6e */ XK_F13, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x6f */ XK_F14, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x70 */ XK_F15, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x71 */ XK_F16, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x72 */ XK_F17, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x73 */ XK_backslash, XK_underscore, NoSymbol, NoSymbol, -+ /* 0x74 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x75 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x76 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x77 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x78 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x79 */ XK_Henkan, XK_Mode_switch, NoSymbol, NoSymbol, -+ /* 0x7a */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x7b */ XK_Muhenkan, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x7c */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x7d */ XK_backslash, XK_bar, NoSymbol, NoSymbol, -+ /* 0x7e */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+ /* 0x7f */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, -+}; -+ -+#define N_PREDEFINED_KEYS (sizeof(map) / (sizeof(KeySym) * GLYPHS_PER_KEY)) -+ -+void -+KbdDeviceInit(DeviceIntPtr pDevice, KeySymsPtr pKeySyms, CARD8 *pModMap) -+{ -+ int i; -+ -+ for (i = 0; i < MAP_LENGTH; i++) -+ pModMap[i] = NoSymbol; -+ -+ pModMap[CONTROL_L_KEY_CODE] = ControlMask; -+ pModMap[CONTROL_R_KEY_CODE] = ControlMask; -+ pModMap[SHIFT_L_KEY_CODE] = ShiftMask; -+ pModMap[SHIFT_R_KEY_CODE] = ShiftMask; -+ pModMap[META_L_KEY_CODE] = Mod1Mask; -+ pModMap[META_R_KEY_CODE] = Mod1Mask; -+ pModMap[ALT_L_KEY_CODE] = Mod1Mask; -+ pModMap[ALT_R_KEY_CODE] = Mod1Mask; -+ -+ pKeySyms->minKeyCode = MIN_KEY_CODE; -+ pKeySyms->maxKeyCode = MAX_KEY_CODE; -+ pKeySyms->mapWidth = GLYPHS_PER_KEY; -+ -+ pKeySyms->map = (KeySym *)malloc(sizeof(KeySym) -+ * MAP_LENGTH * GLYPHS_PER_KEY); -+ -+ if (!pKeySyms->map) { -+ ErrorF("xalloc failed\n"); -+ exit(1); -+ } -+ -+ for (i = 0; i < MAP_LENGTH * GLYPHS_PER_KEY; i++) -+ pKeySyms->map[i] = NoSymbol; -+ -+ for (i = 0; i < N_PREDEFINED_KEYS * GLYPHS_PER_KEY; i++) { -+ pKeySyms->map[i] = map[i]; -+ } -+} -+ -+void -+KbdDeviceOn(void) -+{ -+} -+ -+ -+void -+KbdDeviceOff(void) -+{ -+} -+ -+#if XFREE86VNC -+static int -+xf86rfbKeybControlProc(DeviceIntPtr device, int onoff) -+{ -+ KeySymsRec keySyms; -+ CARD8 modMap[MAP_LENGTH]; -+ DevicePtr pDev = (DevicePtr)device; -+ -+ if (!device) -+ return BadValue; -+ -+ switch (onoff) -+ { -+ case DEVICE_INIT: -+ vncSetKeyboardDevice(device); -+ KbdDeviceInit(device, &keySyms, modMap); -+#ifdef XKB -+ if (noXkbExtension) { -+#endif -+ InitKeyboardDeviceStruct(device, NULL, -+ (BellProcPtr)rfbSendBell, -+ (KbdCtrlProcPtr)NoopDDA); -+#ifdef XKB -+ } else { -+ XkbComponentNamesRec names; -+ if (xkbkeymap) { -+ names.keymap = xkbkeymap; -+ names.keycodes = NULL; -+ names.types = NULL; -+ names.compat = NULL; -+ names.symbols = NULL; -+ names.geometry = NULL; -+ } else { -+ names.keymap = NULL; -+ names.keycodes = xkbkeycodes; -+ names.types = xkbtypes; -+ names.compat = xkbcompat; -+ names.symbols = xkbsymbols; -+ names.geometry = xkbgeometry; -+ } -+ if ((xkbkeymap || xkbcomponents_specified) -+ && (xkbmodel == NULL || xkblayout == NULL)) { -+ xkbrules = NULL; -+ } -+#if 0 -+ XkbSetRulesDflts(xkbrules, xkbmodel, -+ xkblayout, xkbvariant, -+ xkboptions); -+#endif -+ XkbInitKeyboardDeviceStruct(device, -+ &names, -+ &keySyms, -+ modMap, -+ (BellProcPtr)rfbSendBell, -+ (KbdCtrlProcPtr)NoopDDA); -+ } -+#endif -+ break; -+ case DEVICE_ON: -+ pDev->on = TRUE; -+ KbdDeviceOn(); -+ break; -+ case DEVICE_OFF: -+ pDev->on = FALSE; -+ KbdDeviceOff(); -+ break; -+ case DEVICE_CLOSE: -+ vncSetKeyboardDevice(NULL); -+ if (pDev->on) -+ KbdDeviceOff(); -+ break; -+ } -+ return Success; -+} -+ -+static void -+xf86rfbKeybUninit(InputDriverPtr drv, -+ InputInfoPtr pInfo, -+ int flags) -+{ -+ xf86rfbKeybControlProc(pInfo->dev, DEVICE_OFF); -+} -+ -+static int -+xf86rfbKeybInit(struct _InputDriverRec *drv, -+ struct _InputInfoRec* pInfo, -+ int flags) -+{ -+ /* Initialise the InputInfoRec. */ -+ pInfo->type_name = "rfbKeyb"; -+ pInfo->device_control = xf86rfbKeybControlProc; -+ pInfo->read_input = NULL; -+#if 0 -+ pInfo->motion_history_proc = NULL; -+#endif -+ pInfo->control_proc = NULL; -+ pInfo->switch_mode = NULL; -+ pInfo->fd = -1; -+ pInfo->dev = NULL; -+ -+ /* Collect the options, and process the common options. */ -+ xf86CollectInputOptions(pInfo, (const char**)drv->default_options); -+ xf86ProcessCommonOptions(pInfo, pInfo->options); -+ -+#ifdef XKB -+ from = X_DEFAULT; -+ if (noXkbExtension) -+ from = X_CMDLINE; -+ else if (xf86FindOption(dev->commonOptions, "XkbDisable")) { -+ noXkbExtension = -+ xf86SetBoolOption(dev->commonOptions, "XkbDisable", FALSE); -+ from = X_CONFIG; -+ } -+ if (noXkbExtension) -+ xf86Msg(from, "XKB: disabled\n"); -+ -+#define NULL_IF_EMPTY(s) (s[0] ? s : (xfree(s), (char *)NULL)) -+ -+ if (!noXkbExtension) { -+ if ((s = xf86SetStrOption(dev->commonOptions, "XkbKeymap", NULL))) { -+ xkbkeymap = NULL_IF_EMPTY(s); -+ xf86Msg(X_CONFIG, "XKB: keymap: \"%s\" " -+ "(overrides other XKB settings)\n", xkbkeymap); -+ } else { -+ if ((s = xf86SetStrOption(dev->commonOptions, "XkbCompat", NULL))) { -+ xkbcompat = NULL_IF_EMPTY(s); -+ xkbcomponents_specified = TRUE; -+ xf86Msg(X_CONFIG, "XKB: compat: \"%s\"\n", s); -+ } -+ -+ if ((s = xf86SetStrOption(dev->commonOptions, "XkbTypes", NULL))) { -+ xkbtypes = NULL_IF_EMPTY(s); -+ xkbcomponents_specified = TRUE; -+ xf86Msg(X_CONFIG, "XKB: types: \"%s\"\n", s); -+ } -+ -+ if ((s = xf86SetStrOption(dev->commonOptions, "XkbKeycodes", NULL))) { -+ xkbkeycodes = NULL_IF_EMPTY(s); -+ xkbcomponents_specified = TRUE; -+ xf86Msg(X_CONFIG, "XKB: keycodes: \"%s\"\n", s); -+ } -+ -+ if ((s = xf86SetStrOption(dev->commonOptions, "XkbGeometry", NULL))) { -+ xkbgeometry = NULL_IF_EMPTY(s); -+ xkbcomponents_specified = TRUE; -+ xf86Msg(X_CONFIG, "XKB: geometry: \"%s\"\n", s); -+ } -+ -+ if ((s = xf86SetStrOption(dev->commonOptions, "XkbSymbols", NULL))) { -+ xkbsymbols = NULL_IF_EMPTY(s); -+ xkbcomponents_specified = TRUE; -+ xf86Msg(X_CONFIG, "XKB: symbols: \"%s\"\n", s); -+ } -+ -+ if ((s = xf86SetStrOption(dev->commonOptions, "XkbRules", NULL))) { -+ xkbrules = NULL_IF_EMPTY(s); -+ xkbcomponents_specified = TRUE; -+ xf86Msg(X_CONFIG, "XKB: rules: \"%s\"\n", s); -+ } -+ -+ if ((s = xf86SetStrOption(dev->commonOptions, "XkbModel", NULL))) { -+ xkbmodel = NULL_IF_EMPTY(s); -+ xkbcomponents_specified = TRUE; -+ xf86Msg(X_CONFIG, "XKB: model: \"%s\"\n", s); -+ } -+ -+ if ((s = xf86SetStrOption(dev->commonOptions, "XkbLayout", NULL))) { -+ xkblayout = NULL_IF_EMPTY(s); -+ xkbcomponents_specified = TRUE; -+ xf86Msg(X_CONFIG, "XKB: layout: \"%s\"\n", s); -+ } -+ -+ if ((s = xf86SetStrOption(dev->commonOptions, "XkbVariant", NULL))) { -+ xkbvariant = NULL_IF_EMPTY(s); -+ xkbcomponents_specified = TRUE; -+ xf86Msg(X_CONFIG, "XKB: variant: \"%s\"\n", s); -+ } -+ -+ if ((s = xf86SetStrOption(dev->commonOptions, "XkbOptions", NULL))) { -+ xkboptions = NULL_IF_EMPTY(s); -+ xkbcomponents_specified = TRUE; -+ xf86Msg(X_CONFIG, "XKB: options: \"%s\"\n", s); -+ } -+ } -+ } -+#undef NULL_IF_EMPTY -+#endif -+ -+ /* Return the configured device */ -+ return Success; -+} -+ -+#ifdef XFree86LOADER -+static -+#endif -+InputDriverRec RFBKEYB = { -+ 1, /* driver version */ -+ "rfbkeyb", /* driver name */ -+ NULL, /* identify */ -+ xf86rfbKeybInit, /* pre-init */ -+ xf86rfbKeybUninit, /* un-init */ -+ NULL, /* module */ -+ 0 /* ref count */ -+}; -+ -+/* -+ *************************************************************************** -+ * -+ * Dynamic loading functions -+ * -+ *************************************************************************** -+ */ -+#ifdef XFree86LOADER -+static void -+xf86rfbKeybUnplug(pointer p) -+{ -+} -+ -+static pointer -+xf86rfbKeybPlug(pointer module, -+ pointer options, -+ int *errmaj, -+ int *errmin) -+{ -+ xf86AddInputDriver(&RFBKEYB, module, 0); -+ -+ return module; -+} -+ -+void -+vncInitKeyb(void) -+{ -+ xf86AddInputDriver(&RFBKEYB, NULL, 0); -+} -+ -+static XF86ModuleVersionInfo xf86rfbKeybVersionRec = -+{ -+ "rfbkeyb", -+ "xf4vnc Project, see http://xf4vnc.sf.net", -+ MODINFOSTRING1, -+ MODINFOSTRING2, -+ XORG_VERSION_CURRENT, -+ 1, 0, 0, -+ ABI_CLASS_XINPUT, -+ ABI_XINPUT_VERSION, -+ MOD_CLASS_XINPUT, -+ {0, 0, 0, 0} /* signature, to be patched into the file by */ -+ /* a tool */ -+}; -+ -+XF86ModuleData rfbkeybModuleData = {&xf86rfbKeybVersionRec, -+ xf86rfbKeybPlug, -+ xf86rfbKeybUnplug}; -+ -+#endif /* XFree86LOADER */ -+#endif -diff -pruN xorg-server-1.12.1.orig/hw/vnc/rfbmouse.c xorg-server-1.12.1/hw/vnc/rfbmouse.c ---- xorg-server-1.12.1.orig/hw/vnc/rfbmouse.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/rfbmouse.c 2012-04-18 16:18:14.644148022 -0500 -@@ -0,0 +1,260 @@ -+/* -+ * Copyright (C) 2002 Alan Hourihane. 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. -+ * -+ * Author: Alan Hourihane -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#include -+#if XFREE86VNC -+#ifndef XFree86LOADER -+#include -+#include -+#endif -+ -+#include -+#include -+#if !defined(DGUX) -+#include -+#endif -+#include -+#include /* Needed for InitValuator/Proximity stuff */ -+#include -+ -+#ifdef XFree86LOADER -+#include -+#endif -+ -+#else -+#include -+#include -+#endif -+#include "rfb.h" -+#include "xserver-properties.h" -+ -+extern void vncInitMouse(void); -+ -+unsigned char ptrAcceleration = 50; -+ -+void -+PtrDeviceOn(DeviceIntPtr pDev) -+{ -+#if 0 -+ ptrAcceleration = (unsigned char)pDev->ptrfeed->ctrl.num; -+#endif -+} -+ -+void -+PtrDeviceInit(void) -+{ -+} -+ -+void -+PtrDeviceOff(void) -+{ -+} -+ -+ -+void -+PtrDeviceControl(DeviceIntPtr dev, PtrCtrl *ctrl) -+{ -+#if 0 -+ ptrAcceleration = (char)ctrl->num; -+ -+ if (udpSockConnected) { -+ if (write(udpSock, &ptrAcceleration, 1) <= 0) { -+ ErrorF("PtrDeviceControl: UDP input: write"); -+ rfbDisconnectUDPSock(); -+ } -+ } -+#endif -+} -+ -+#if XFREE86VNC -+static int -+xf86rfbMouseControlProc(DeviceIntPtr dev, int onoff) -+{ -+ BYTE map[6]; -+ DevicePtr pDev = &dev->public; -+ Atom btn_labels[5] = {0}; -+ Atom axes_labels[2] = {0}; -+ -+ int (*func2)(void); -+ -+ if (!dev) -+ return BadValue; -+ -+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3 -+ if (LoaderSymbol("GetMotionHistory")) -+ func1 = LoaderSymbol("GetMotionHistory"); -+ else -+ func1 = LoaderSymbol("miPointerGetMotionEvents"); -+#endif -+ -+ if (LoaderSymbol("GetMotionHistorySize")) -+ func2 = LoaderSymbol("GetMotionHistorySize"); -+ else -+ func2 = LoaderSymbol("miPointerGetMotionBufferSize"); -+ -+ -+ switch (onoff) -+ { -+ case DEVICE_INIT: -+ vncSetPointerDevice(dev); -+ PtrDeviceInit(); -+ map[1] = 1; -+ map[2] = 2; -+ map[3] = 3; -+ map[4] = 4; -+ map[5] = 5; -+ btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); -+ btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); -+ btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); -+ btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); -+ btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); -+ -+ axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); -+ axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); -+ -+ InitPointerDeviceStruct(pDev, map, 5, btn_labels, -+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3 -+ func1, -+#endif -+ PtrDeviceControl, -+ (*func2)(), 2, axes_labels); -+ break; -+ -+ case DEVICE_ON: -+ pDev->on = TRUE; -+ PtrDeviceOn(dev); -+ break; -+ -+ case DEVICE_OFF: -+ pDev->on = FALSE; -+ PtrDeviceOff(); -+ break; -+ -+ case DEVICE_CLOSE: -+ vncSetPointerDevice(NULL); -+ if (pDev->on) -+ PtrDeviceOff(); -+ break; -+ } -+ return Success; -+} -+ -+static void -+xf86rfbMouseUninit(InputDriverPtr drv, -+ InputInfoPtr pInfo, -+ int flags) -+{ -+ xf86rfbMouseControlProc(pInfo->dev, DEVICE_OFF); -+} -+ -+static int -+xf86rfbMouseInit(InputDriverPtr drv, -+ InputInfoPtr pInfo, -+ int flags) -+{ -+ /* Initialise the InputInfoRec. */ -+ pInfo->type_name = "rfbMouse"; -+ pInfo->device_control = xf86rfbMouseControlProc; -+ pInfo->read_input = NULL; -+#if 0 -+ pInfo->motion_history_proc = xf86GetMotionEvents; -+#endif -+ pInfo->control_proc = NULL; -+ pInfo->switch_mode = NULL; -+ pInfo->fd = -1; -+ // pInfo->dev = NULL; -+ -+ /* Collect the options, and process the common options. */ -+ xf86CollectInputOptions(pInfo, (const char**)drv->default_options); -+ xf86ProcessCommonOptions(pInfo, pInfo->options); -+ -+ /* Return the configured device */ -+ return Success; -+} -+ -+#ifdef XFree86LOADER -+static -+#endif -+InputDriverRec RFBMOUSE = { -+ 1, /* driver version */ -+ "rfbmouse", /* driver name */ -+ NULL, /* identify */ -+ xf86rfbMouseInit, /* pre-init */ -+ xf86rfbMouseUninit, /* un-init */ -+ NULL, /* module */ -+ 0 /* ref count */ -+}; -+ -+/* -+ *************************************************************************** -+ * -+ * Dynamic loading functions -+ * -+ *************************************************************************** -+ */ -+#ifdef XFree86LOADER -+static void -+xf86rfbMouseUnplug(pointer p) -+{ -+} -+ -+static pointer -+xf86rfbMousePlug(pointer module, -+ pointer options, -+ int *errmaj, -+ int *errmin) -+{ -+ xf86AddInputDriver(&RFBMOUSE, module, 0); -+ -+ return module; -+} -+ -+void -+vncInitMouse(void) -+{ -+ xf86AddInputDriver(&RFBMOUSE, NULL, 0); -+} -+ -+static XF86ModuleVersionInfo xf86rfbMouseVersionRec = -+{ -+ "rfbmouse", -+ "xf4vnc Project, see http://xf4vnc.sf.net", -+ MODINFOSTRING1, -+ MODINFOSTRING2, -+ XORG_VERSION_CURRENT, -+ 1, 0, 0, -+ ABI_CLASS_XINPUT, -+ ABI_XINPUT_VERSION, -+ MOD_CLASS_XINPUT, -+ {0, 0, 0, 0} /* signature, to be patched into the file by */ -+ /* a tool */ -+}; -+ -+XF86ModuleData rfbmouseModuleData = {&xf86rfbMouseVersionRec, -+ xf86rfbMousePlug, -+ xf86rfbMouseUnplug}; -+ -+#endif /* XFree86LOADER */ -+#endif -diff -pruN xorg-server-1.12.1.orig/hw/vnc/rfbproto.h xorg-server-1.12.1/hw/vnc/rfbproto.h ---- xorg-server-1.12.1.orig/hw/vnc/rfbproto.h 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/rfbproto.h 2012-04-18 14:45:21.580820903 -0500 -@@ -0,0 +1,1362 @@ -+/* -+ * Copyright (C) 2000-2004 Constantin Kaplinsky. All Rights Reserved. -+ * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. -+ * 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. -+ */ -+ -+/* -+ * rfbproto.h - header file for the RFB protocol, versions 3.3, 3.7 and 3.7t -+ * (protocol 3.7t is effectively 3.7 with TightVNC extensions enabled) -+ * -+ * Uses types CARD for an n-bit unsigned integer, INT for an n-bit signed -+ * integer (for n = 8, 16 and 32). -+ * -+ * All multiple byte integers are in big endian (network) order (most -+ * significant byte first). Unless noted otherwise there is no special -+ * alignment of protocol structures. -+ * -+ * -+ * Once the initial handshaking is done, all messages start with a type byte, -+ * (usually) followed by message-specific data. The order of definitions in -+ * this file is as follows: -+ * -+ * (1) Structures used in several types of message. -+ * (2) Structures used in the initial handshaking. -+ * (3) Message types. -+ * (4) Encoding types. -+ * (5) For each message type, the form of the data following the type byte. -+ * Sometimes this is defined by a single structure but the more complex -+ * messages have to be explained by comments. -+ */ -+ -+ -+/***************************************************************************** -+ * -+ * Structures used in several messages -+ * -+ *****************************************************************************/ -+ -+/*----------------------------------------------------------------------------- -+ * Structure used to specify a rectangle. This structure is a multiple of 4 -+ * bytes so that it can be interspersed with 32-bit pixel data without -+ * affecting alignment. -+ */ -+ -+typedef struct _rfbRectangle { -+ CARD16 x; -+ CARD16 y; -+ CARD16 w; -+ CARD16 h; -+} rfbRectangle; -+ -+#define sz_rfbRectangle 8 -+ -+ -+/*----------------------------------------------------------------------------- -+ * Structure used to specify pixel format. -+ */ -+ -+typedef struct _rfbPixelFormat { -+ -+ CARD8 bitsPerPixel; /* 8,16,32 only */ -+ -+ CARD8 depth; /* 8 to 32 */ -+ -+ CARD8 bigEndian; /* True if multi-byte pixels are interpreted -+ as big endian, or if single-bit-per-pixel -+ has most significant bit of the byte -+ corresponding to first (leftmost) pixel. Of -+ course this is meaningless for 8 bits/pix */ -+ -+ CARD8 trueColour; /* If false then we need a "colour map" to -+ convert pixels to RGB. If true, xxxMax and -+ xxxShift specify bits used for red, green -+ and blue */ -+ -+ /* the following fields are only meaningful if trueColour is true */ -+ -+ CARD16 redMax; /* maximum red value (= 2^n - 1 where n is the -+ number of bits used for red). Note this -+ value is always in big endian order. */ -+ -+ CARD16 greenMax; /* similar for green */ -+ -+ CARD16 blueMax; /* and blue */ -+ -+ CARD8 redShift; /* number of shifts needed to get the red -+ value in a pixel to the least significant -+ bit. To find the red value from a given -+ pixel, do the following: -+ 1) Swap pixel value according to bigEndian -+ (e.g. if bigEndian is false and host byte -+ order is big endian, then swap). -+ 2) Shift right by redShift. -+ 3) AND with redMax (in host byte order). -+ 4) You now have the red value between 0 and -+ redMax. */ -+ -+ CARD8 greenShift; /* similar for green */ -+ -+ CARD8 blueShift; /* and blue */ -+ -+ CARD8 pad1; -+ CARD16 pad2; -+ -+} rfbPixelFormat; -+ -+#define sz_rfbPixelFormat 16 -+ -+ -+/*----------------------------------------------------------------------------- -+ * Structure used to describe protocol options such as tunneling methods, -+ * authentication schemes and message types (protocol version 3.7t). -+ */ -+ -+typedef struct _rfbCapabilityInfo { -+ -+ CARD32 code; /* numeric identifier */ -+ CARD8 vendorSignature[4]; /* vendor identification */ -+ CARD8 nameSignature[8]; /* abbreviated option name */ -+ -+} rfbCapabilityInfo; -+ -+#define sz_rfbCapabilityInfoVendor 4 -+#define sz_rfbCapabilityInfoName 8 -+#define sz_rfbCapabilityInfo 16 -+ -+/* -+ * Vendors known by TightVNC: standard VNC/RealVNC, TridiaVNC, and TightVNC. -+ */ -+ -+#define rfbStandardVendor "STDV" -+#define rfbTridiaVncVendor "TRDV" -+#define rfbTightVncVendor "TGHT" -+#define rfbTungstenGraphicsVendor "TGIV" -+ -+ -+/***************************************************************************** -+ * -+ * Initial handshaking messages -+ * -+ *****************************************************************************/ -+ -+/*----------------------------------------------------------------------------- -+ * Protocol Version -+ * -+ * The server always sends 12 bytes to start which identifies the latest RFB -+ * protocol version number which it supports. These bytes are interpreted -+ * as a string of 12 ASCII characters in the format "RFB xxx.yyy\n" where -+ * xxx and yyy are the major and minor version numbers (for version 3.7 -+ * this is "RFB 003.007\n"). -+ * -+ * The client then replies with a similar 12-byte message giving the version -+ * number of the protocol which should actually be used (which may be different -+ * to that quoted by the server). -+ * -+ * It is intended that both clients and servers may provide some level of -+ * backwards compatibility by this mechanism. Servers in particular should -+ * attempt to provide backwards compatibility, and even forwards compatibility -+ * to some extent. For example if a client demands version 3.1 of the -+ * protocol, a 3.0 server can probably assume that by ignoring requests for -+ * encoding types it doesn't understand, everything will still work OK. This -+ * will probably not be the case for changes in the major version number. -+ * -+ * The format string below can be used in sprintf or sscanf to generate or -+ * decode the version string respectively. -+ */ -+ -+#define rfbProtocolVersionFormat "RFB %03d.%03d\n" -+#define rfbProtocolMajorVersion 3 -+#define rfbProtocolMinorVersion 7 -+#define rfbProtocolFallbackMinorVersion 3 -+ -+typedef char rfbProtocolVersionMsg[13]; /* allow extra byte for null */ -+ -+#define sz_rfbProtocolVersionMsg 12 -+ -+ -+/* -+ * Negotiation of the security type (protocol version 3.7) -+ * -+ * Once the protocol version has been decided, the server either sends a list -+ * of supported security types, or informs the client about an error (when the -+ * number of security types is 0). Security type rfbSecTypeTight is used to -+ * enable TightVNC-specific protocol extensions. The value rfbSecTypeVncAuth -+ * stands for classic VNC authentication. -+ * -+ * The client selects a particular security type from the list provided by the -+ * server. -+ */ -+ -+#define rfbSecTypeInvalid 0 -+#define rfbSecTypeNone 1 -+#define rfbSecTypeVncAuth 2 -+#define rfbSecTypeTight 16 -+ -+ -+/*----------------------------------------------------------------------------- -+ * Negotiation of Tunneling Capabilities (protocol version 3.7t) -+ * -+ * If the chosen security type is rfbSecTypeTight, the server sends a list of -+ * supported tunneling methods ("tunneling" refers to any additional layer of -+ * data transformation, such as encryption or external compression.) -+ * -+ * nTunnelTypes specifies the number of following rfbCapabilityInfo structures -+ * that list all supported tunneling methods in the order of preference. -+ * -+ * NOTE: If nTunnelTypes is 0, that tells the client that no tunneling can be -+ * used, and the client should not send a response requesting a tunneling -+ * method. -+ */ -+ -+typedef struct _rfbTunnelingCapsMsg { -+ CARD32 nTunnelTypes; -+ /* followed by nTunnelTypes * rfbCapabilityInfo structures */ -+} rfbTunnelingCapsMsg; -+ -+#define sz_rfbTunnelingCapsMsg 4 -+ -+/*----------------------------------------------------------------------------- -+ * Tunneling Method Request (protocol version 3.7t) -+ * -+ * If the list of tunneling capabilities sent by the server was not empty, the -+ * client should reply with a 32-bit code specifying a particular tunneling -+ * method. The following code should be used for no tunneling. -+ */ -+ -+#define rfbNoTunneling 0 -+#define sig_rfbNoTunneling "NOTUNNEL" -+ -+ -+/*----------------------------------------------------------------------------- -+ * Negotiation of Authentication Capabilities (protocol version 3.7t) -+ * -+ * After setting up tunneling, the server sends a list of supported -+ * authentication schemes. -+ * -+ * nAuthTypes specifies the number of following rfbCapabilityInfo structures -+ * that list all supported authentication schemes in the order of preference. -+ * -+ * NOTE: If nAuthTypes is 0, that tells the client that no authentication is -+ * necessary, and the client should not send a response requesting an -+ * authentication scheme. -+ */ -+ -+typedef struct _rfbAuthenticationCapsMsg { -+ CARD32 nAuthTypes; -+ /* followed by nAuthTypes * rfbCapabilityInfo structures */ -+} rfbAuthenticationCapsMsg; -+ -+#define sz_rfbAuthenticationCapsMsg 4 -+ -+/*----------------------------------------------------------------------------- -+ * Authentication Scheme Request (protocol version 3.7t) -+ * -+ * If the list of authentication capabilities sent by the server was not empty, -+ * the client should reply with a 32-bit code specifying a particular -+ * authentication scheme. The following codes are supported. -+ */ -+ -+#define rfbAuthNone 1 -+#define rfbAuthVNC 2 -+#define rfbAuthUnixLogin 129 -+#define rfbAuthExternal 130 -+ -+#define sig_rfbAuthNone "NOAUTH__" -+#define sig_rfbAuthVNC "VNCAUTH_" -+#define sig_rfbAuthUnixLogin "ULGNAUTH" -+#define sig_rfbAuthExternal "XTRNAUTH" -+ -+ -+/*----------------------------------------------------------------------------- -+ * Standard VNC Authentication (all protocol versions) -+ * -+ * Standard authentication result codes are defined below. -+ */ -+ -+#define rfbVncAuthOK 0 -+#define rfbVncAuthFailed 1 -+#define rfbVncAuthTooMany 2 -+ -+ -+/*----------------------------------------------------------------------------- -+ * Client Initialisation Message -+ * -+ * Once the client and server are sure that they're happy to talk to one -+ * another, the client sends an initialisation message. At present this -+ * message only consists of a boolean indicating whether the server should try -+ * to share the desktop by leaving other clients connected, or give exclusive -+ * access to this client by disconnecting all other clients. -+ */ -+ -+typedef struct _rfbClientInitMsg { -+ CARD8 shared; -+} rfbClientInitMsg; -+ -+#define sz_rfbClientInitMsg 1 -+ -+ -+/*----------------------------------------------------------------------------- -+ * Server Initialisation Message -+ * -+ * After the client initialisation message, the server sends one of its own. -+ * This tells the client the width and height of the server's framebuffer, -+ * its pixel format and the name associated with the desktop. -+ */ -+ -+typedef struct _rfbServerInitMsg { -+ CARD16 framebufferWidth; -+ CARD16 framebufferHeight; -+ rfbPixelFormat format; /* the server's preferred pixel format */ -+ CARD32 nameLength; -+ /* followed by char name[nameLength] */ -+} rfbServerInitMsg; -+ -+#define sz_rfbServerInitMsg (8 + sz_rfbPixelFormat) -+ -+ -+/*----------------------------------------------------------------------------- -+ * Server Interaction Capabilities Message (protocol version 3.7t) -+ * -+ * In the protocol version 3.7t, the server informs the client what message -+ * types it supports in addition to ones defined in the protocol version 3.7. -+ * Also, the server sends the list of all supported encodings (note that it's -+ * not necessary to advertise the "raw" encoding sinse it MUST be supported in -+ * RFB 3.x protocols). -+ * -+ * This data immediately follows the server initialisation message. -+ */ -+ -+typedef struct _rfbInteractionCapsMsg { -+ CARD16 nServerMessageTypes; -+ CARD16 nClientMessageTypes; -+ CARD16 nEncodingTypes; -+ CARD16 pad; /* reserved, must be 0 */ -+ /* followed by nServerMessageTypes * rfbCapabilityInfo structures */ -+ /* followed by nClientMessageTypes * rfbCapabilityInfo structures */ -+} rfbInteractionCapsMsg; -+ -+#define sz_rfbInteractionCapsMsg 8 -+ -+ -+/* -+ * Following the server initialisation message it's up to the client to send -+ * whichever protocol messages it wants. Typically it will send a -+ * SetPixelFormat message and a SetEncodings message, followed by a -+ * FramebufferUpdateRequest. From then on the server will send -+ * FramebufferUpdate messages in response to the client's -+ * FramebufferUpdateRequest messages. The client should send -+ * FramebufferUpdateRequest messages with incremental set to true when it has -+ * finished processing one FramebufferUpdate and is ready to process another. -+ * With a fast client, the rate at which FramebufferUpdateRequests are sent -+ * should be regulated to avoid hogging the network. -+ */ -+ -+ -+ -+/***************************************************************************** -+ * -+ * Message types -+ * -+ *****************************************************************************/ -+ -+/* server -> client */ -+ -+#define rfbFramebufferUpdate 0 -+#define rfbSetColourMapEntries 1 -+#define rfbBell 2 -+#define rfbServerCutText 3 -+/* Chromium extensions, use higher values */ -+#define rfbChromiumStart 50 -+#define rfbChromiumMoveResizeWindow 51 -+#define rfbChromiumClipList 52 -+#define rfbChromiumWindowShow 53 -+#define rfbChromiumWindowDestroy 54 -+ -+#define rfbFileListData 130 -+#define rfbFileDownloadData 131 -+#define rfbFileUploadCancel 132 -+#define rfbFileDownloadFailed 133 -+ -+/* signatures for non-standard messages */ -+#define sig_rfbFileListData "FTS_LSDT" -+#define sig_rfbFileDownloadData "FTS_DNDT" -+#define sig_rfbFileUploadCancel "FTS_UPCN" -+#define sig_rfbFileDownloadFailed "FTS_DNFL" -+ -+ -+/* client -> server */ -+ -+#define rfbSetPixelFormat 0 -+#define rfbFixColourMapEntries 1 /* not currently supported */ -+#define rfbSetEncodings 2 -+#define rfbFramebufferUpdateRequest 3 -+#define rfbKeyEvent 4 -+#define rfbPointerEvent 5 -+#define rfbClientCutText 6 -+/* Chromium extensions, use higher values */ -+#define rfbChromiumStop 50 -+#define rfbChromiumExpose 51 -+ -+#define rfbFileListRequest 130 -+#define rfbFileDownloadRequest 131 -+#define rfbFileUploadRequest 132 -+#define rfbFileUploadData 133 -+#define rfbFileDownloadCancel 134 -+#define rfbFileUploadFailed 135 -+#define rfbFileCreateDirRequest 136 -+ -+/* signatures for non-standard messages */ -+#define sig_rfbFileListRequest "FTC_LSRQ" -+#define sig_rfbFileDownloadRequest "FTC_DNRQ" -+#define sig_rfbFileUploadRequest "FTC_UPRQ" -+#define sig_rfbFileUploadData "FTC_UPDT" -+#define sig_rfbFileDownloadCancel "FTC_DNCN" -+#define sig_rfbFileUploadFailed "FTC_UPFL" -+#define sig_rfbFileCreateDirRequest "FTC_FCDR" -+ -+/***************************************************************************** -+ * -+ * Encoding types -+ * -+ *****************************************************************************/ -+ -+#define rfbEncodingRaw 0 -+#define rfbEncodingCopyRect 1 -+#define rfbEncodingRRE 2 -+#define rfbEncodingCoRRE 4 -+#define rfbEncodingHextile 5 -+#define rfbEncodingZlib 6 -+#define rfbEncodingTight 7 -+#define rfbEncodingZlibHex 8 -+ -+/* signatures for basic encoding types */ -+#define sig_rfbEncodingRaw "RAW_____" -+#define sig_rfbEncodingCopyRect "COPYRECT" -+#define sig_rfbEncodingRRE "RRE_____" -+#define sig_rfbEncodingCoRRE "CORRE___" -+#define sig_rfbEncodingHextile "HEXTILE_" -+#define sig_rfbEncodingZlib "ZLIB____" -+#define sig_rfbEncodingTight "TIGHT___" -+#define sig_rfbEncodingZlibHex "ZLIBHEX_" -+#define sig_rfbEncodingChromium "CHROMIUM" -+ -+/* -+ * Special encoding numbers: -+ * 0xFFFFFF00 .. 0xFFFFFF0F -- encoding-specific compression levels; -+ * 0xFFFFFF10 .. 0xFFFFFF1F -- mouse cursor shape data; -+ * 0xFFFFFF20 .. 0xFFFFFF2F -- various protocol extensions; -+ * 0xFFFFFF30 .. 0xFFFFFFDF -- not allocated yet; -+ * 0xFFFFFFE0 .. 0xFFFFFFEF -- quality level for JPEG compressor; -+ * 0xFFFFFFF0 .. 0xFFFFFFFF -- not allocated yet. -+ */ -+ -+#define rfbEncodingCompressLevel0 0xFFFFFF00 -+#define rfbEncodingCompressLevel1 0xFFFFFF01 -+#define rfbEncodingCompressLevel2 0xFFFFFF02 -+#define rfbEncodingCompressLevel3 0xFFFFFF03 -+#define rfbEncodingCompressLevel4 0xFFFFFF04 -+#define rfbEncodingCompressLevel5 0xFFFFFF05 -+#define rfbEncodingCompressLevel6 0xFFFFFF06 -+#define rfbEncodingCompressLevel7 0xFFFFFF07 -+#define rfbEncodingCompressLevel8 0xFFFFFF08 -+#define rfbEncodingCompressLevel9 0xFFFFFF09 -+ -+#define rfbEncodingXCursor 0xFFFFFF10 -+#define rfbEncodingRichCursor 0xFFFFFF11 -+#define rfbEncodingPointerPos 0xFFFFFF18 -+ -+#define rfbEncodingLastRect 0xFFFFFF20 -+#define rfbEncodingNewFBSize 0xFFFFFF21 -+#define rfbEncodingChromium 0xFFFFFF2F -+#define rfbEncodingChromium2 0xFFFFFF30 -+ -+#define rfbEncodingQualityLevel0 0xFFFFFFE0 -+#define rfbEncodingQualityLevel1 0xFFFFFFE1 -+#define rfbEncodingQualityLevel2 0xFFFFFFE2 -+#define rfbEncodingQualityLevel3 0xFFFFFFE3 -+#define rfbEncodingQualityLevel4 0xFFFFFFE4 -+#define rfbEncodingQualityLevel5 0xFFFFFFE5 -+#define rfbEncodingQualityLevel6 0xFFFFFFE6 -+#define rfbEncodingQualityLevel7 0xFFFFFFE7 -+#define rfbEncodingQualityLevel8 0xFFFFFFE8 -+#define rfbEncodingQualityLevel9 0xFFFFFFE9 -+ -+/* signatures for "fake" encoding types */ -+#define sig_rfbEncodingCompressLevel0 "COMPRLVL" -+#define sig_rfbEncodingXCursor "X11CURSR" -+#define sig_rfbEncodingRichCursor "RCHCURSR" -+#define sig_rfbEncodingPointerPos "POINTPOS" -+#define sig_rfbEncodingLastRect "LASTRECT" -+#define sig_rfbEncodingNewFBSize "NEWFBSIZ" -+#define sig_rfbEncodingQualityLevel0 "JPEGQLVL" -+ -+ -+/***************************************************************************** -+ * -+ * Server -> client message definitions -+ * -+ *****************************************************************************/ -+ -+ -+/*----------------------------------------------------------------------------- -+ * FramebufferUpdate - a block of rectangles to be copied to the framebuffer. -+ * -+ * This message consists of a header giving the number of rectangles of pixel -+ * data followed by the rectangles themselves. The header is padded so that -+ * together with the type byte it is an exact multiple of 4 bytes (to help -+ * with alignment of 32-bit pixels): -+ */ -+ -+typedef struct _rfbFramebufferUpdateMsg { -+ CARD8 type; /* always rfbFramebufferUpdate */ -+ CARD8 pad; -+ CARD16 nRects; -+ /* followed by nRects rectangles */ -+} rfbFramebufferUpdateMsg; -+ -+#define sz_rfbFramebufferUpdateMsg 4 -+ -+/* -+ * Each rectangle of pixel data consists of a header describing the position -+ * and size of the rectangle and a type word describing the encoding of the -+ * pixel data, followed finally by the pixel data. Note that if the client has -+ * not sent a SetEncodings message then it will only receive raw pixel data. -+ * Also note again that this structure is a multiple of 4 bytes. -+ */ -+ -+typedef struct _rfbFramebufferUpdateRectHeader { -+ rfbRectangle r; -+ CARD32 encoding; /* one of the encoding types rfbEncoding... */ -+} rfbFramebufferUpdateRectHeader; -+ -+#define sz_rfbFramebufferUpdateRectHeader (sz_rfbRectangle + 4) -+ -+ -+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ * Raw Encoding. Pixels are sent in top-to-bottom scanline order, -+ * left-to-right within a scanline with no padding in between. -+ */ -+ -+ -+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ * CopyRect Encoding. The pixels are specified simply by the x and y position -+ * of the source rectangle. -+ */ -+ -+typedef struct _rfbCopyRect { -+ CARD16 srcX; -+ CARD16 srcY; -+} rfbCopyRect; -+ -+#define sz_rfbCopyRect 4 -+ -+ -+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ * RRE - Rise-and-Run-length Encoding. We have an rfbRREHeader structure -+ * giving the number of subrectangles following. Finally the data follows in -+ * the form [...] where each is -+ * []. -+ */ -+ -+typedef struct _rfbRREHeader { -+ CARD32 nSubrects; -+} rfbRREHeader; -+ -+#define sz_rfbRREHeader 4 -+ -+ -+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ * CoRRE - Compact RRE Encoding. We have an rfbRREHeader structure giving -+ * the number of subrectangles following. Finally the data follows in the form -+ * [...] where each is -+ * []. This means that -+ * the whole rectangle must be at most 255x255 pixels. -+ */ -+ -+typedef struct _rfbCoRRERectangle { -+ CARD8 x; -+ CARD8 y; -+ CARD8 w; -+ CARD8 h; -+} rfbCoRRERectangle; -+ -+#define sz_rfbCoRRERectangle 4 -+ -+ -+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ * Hextile Encoding. The rectangle is divided up into "tiles" of 16x16 pixels, -+ * starting at the top left going in left-to-right, top-to-bottom order. If -+ * the width of the rectangle is not an exact multiple of 16 then the width of -+ * the last tile in each row will be correspondingly smaller. Similarly if the -+ * height is not an exact multiple of 16 then the height of each tile in the -+ * final row will also be smaller. Each tile begins with a "subencoding" type -+ * byte, which is a mask made up of a number of bits. If the Raw bit is set -+ * then the other bits are irrelevant; w*h pixel values follow (where w and h -+ * are the width and height of the tile). Otherwise the tile is encoded in a -+ * similar way to RRE, except that the position and size of each subrectangle -+ * can be specified in just two bytes. The other bits in the mask are as -+ * follows: -+ * -+ * BackgroundSpecified - if set, a pixel value follows which specifies -+ * the background colour for this tile. The first non-raw tile in a -+ * rectangle must have this bit set. If this bit isn't set then the -+ * background is the same as the last tile. -+ * -+ * ForegroundSpecified - if set, a pixel value follows which specifies -+ * the foreground colour to be used for all subrectangles in this tile. -+ * If this bit is set then the SubrectsColoured bit must be zero. -+ * -+ * AnySubrects - if set, a single byte follows giving the number of -+ * subrectangles following. If not set, there are no subrectangles (i.e. -+ * the whole tile is just solid background colour). -+ * -+ * SubrectsColoured - if set then each subrectangle is preceded by a pixel -+ * value giving the colour of that subrectangle. If not set, all -+ * subrectangles are the same colour, the foreground colour; if the -+ * ForegroundSpecified bit wasn't set then the foreground is the same as -+ * the last tile. -+ * -+ * The position and size of each subrectangle is specified in two bytes. The -+ * Pack macros below can be used to generate the two bytes from x, y, w, h, -+ * and the Extract macros can be used to extract the x, y, w, h values from -+ * the two bytes. -+ */ -+ -+#define rfbHextileRaw (1 << 0) -+#define rfbHextileBackgroundSpecified (1 << 1) -+#define rfbHextileForegroundSpecified (1 << 2) -+#define rfbHextileAnySubrects (1 << 3) -+#define rfbHextileSubrectsColoured (1 << 4) -+ -+#define rfbHextilePackXY(x,y) (((x) << 4) | (y)) -+#define rfbHextilePackWH(w,h) ((((w)-1) << 4) | ((h)-1)) -+#define rfbHextileExtractX(byte) ((byte) >> 4) -+#define rfbHextileExtractY(byte) ((byte) & 0xf) -+#define rfbHextileExtractW(byte) (((byte) >> 4) + 1) -+#define rfbHextileExtractH(byte) (((byte) & 0xf) + 1) -+ -+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ * ZLIB - zlib compression Encoding. We have an rfbZlibHeader structure -+ * giving the number of bytes to follow. Finally the data follows in -+ * zlib compressed format. -+ */ -+ -+typedef struct _rfbZlibHeader { -+ CARD32 nBytes; -+} rfbZlibHeader; -+ -+#define sz_rfbZlibHeader 4 -+ -+ -+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ * Tight Encoding. -+ * -+ *-- The first byte of each Tight-encoded rectangle is a "compression control -+ * byte". Its format is as follows (bit 0 is the least significant one): -+ * -+ * bit 0: if 1, then compression stream 0 should be reset; -+ * bit 1: if 1, then compression stream 1 should be reset; -+ * bit 2: if 1, then compression stream 2 should be reset; -+ * bit 3: if 1, then compression stream 3 should be reset; -+ * bits 7-4: if 1000 (0x08), then the compression type is "fill", -+ * if 1001 (0x09), then the compression type is "jpeg", -+ * if 0xxx, then the compression type is "basic", -+ * values greater than 1001 are not valid. -+ * -+ * If the compression type is "basic", then bits 6..4 of the -+ * compression control byte (those xxx in 0xxx) specify the following: -+ * -+ * bits 5-4: decimal representation is the index of a particular zlib -+ * stream which should be used for decompressing the data; -+ * bit 6: if 1, then a "filter id" byte is following this byte. -+ * -+ *-- The data that follows after the compression control byte described -+ * above depends on the compression type ("fill", "jpeg" or "basic"). -+ * -+ *-- If the compression type is "fill", then the only pixel value follows, in -+ * client pixel format (see NOTE 1). This value applies to all pixels of the -+ * rectangle. -+ * -+ *-- If the compression type is "jpeg", the following data stream looks like -+ * this: -+ * -+ * 1..3 bytes: data size (N) in compact representation; -+ * N bytes: JPEG image. -+ * -+ * Data size is compactly represented in one, two or three bytes, according -+ * to the following scheme: -+ * -+ * 0xxxxxxx (for values 0..127) -+ * 1xxxxxxx 0yyyyyyy (for values 128..16383) -+ * 1xxxxxxx 1yyyyyyy zzzzzzzz (for values 16384..4194303) -+ * -+ * Here each character denotes one bit, xxxxxxx are the least significant 7 -+ * bits of the value (bits 0-6), yyyyyyy are bits 7-13, and zzzzzzzz are the -+ * most significant 8 bits (bits 14-21). For example, decimal value 10000 -+ * should be represented as two bytes: binary 10010000 01001110, or -+ * hexadecimal 90 4E. -+ * -+ *-- If the compression type is "basic" and bit 6 of the compression control -+ * byte was set to 1, then the next (second) byte specifies "filter id" which -+ * tells the decoder what filter type was used by the encoder to pre-process -+ * pixel data before the compression. The "filter id" byte can be one of the -+ * following: -+ * -+ * 0: no filter ("copy" filter); -+ * 1: "palette" filter; -+ * 2: "gradient" filter. -+ * -+ *-- If bit 6 of the compression control byte is set to 0 (no "filter id" -+ * byte), or if the filter id is 0, then raw pixel values in the client -+ * format (see NOTE 1) will be compressed. See below details on the -+ * compression. -+ * -+ *-- The "gradient" filter pre-processes pixel data with a simple algorithm -+ * which converts each color component to a difference between a "predicted" -+ * intensity and the actual intensity. Such a technique does not affect -+ * uncompressed data size, but helps to compress photo-like images better. -+ * Pseudo-code for converting intensities to differences is the following: -+ * -+ * P[i,j] := V[i-1,j] + V[i,j-1] - V[i-1,j-1]; -+ * if (P[i,j] < 0) then P[i,j] := 0; -+ * if (P[i,j] > MAX) then P[i,j] := MAX; -+ * D[i,j] := V[i,j] - P[i,j]; -+ * -+ * Here V[i,j] is the intensity of a color component for a pixel at -+ * coordinates (i,j). MAX is the maximum value of intensity for a color -+ * component. -+ * -+ *-- The "palette" filter converts true-color pixel data to indexed colors -+ * and a palette which can consist of 2..256 colors. If the number of colors -+ * is 2, then each pixel is encoded in 1 bit, otherwise 8 bits is used to -+ * encode one pixel. 1-bit encoding is performed such way that the most -+ * significant bits correspond to the leftmost pixels, and each raw of pixels -+ * is aligned to the byte boundary. When "palette" filter is used, the -+ * palette is sent before the pixel data. The palette begins with an unsigned -+ * byte which value is the number of colors in the palette minus 1 (i.e. 1 -+ * means 2 colors, 255 means 256 colors in the palette). Then follows the -+ * palette itself which consist of pixel values in client pixel format (see -+ * NOTE 1). -+ * -+ *-- The pixel data is compressed using the zlib library. But if the data -+ * size after applying the filter but before the compression is less then 12, -+ * then the data is sent as is, uncompressed. Four separate zlib streams -+ * (0..3) can be used and the decoder should read the actual stream id from -+ * the compression control byte (see NOTE 2). -+ * -+ * If the compression is not used, then the pixel data is sent as is, -+ * otherwise the data stream looks like this: -+ * -+ * 1..3 bytes: data size (N) in compact representation; -+ * N bytes: zlib-compressed data. -+ * -+ * Data size is compactly represented in one, two or three bytes, just like -+ * in the "jpeg" compression method (see above). -+ * -+ *-- NOTE 1. If the color depth is 24, and all three color components are -+ * 8-bit wide, then one pixel in Tight encoding is always represented by -+ * three bytes, where the first byte is red component, the second byte is -+ * green component, and the third byte is blue component of the pixel color -+ * value. This applies to colors in palettes as well. -+ * -+ *-- NOTE 2. The decoder must reset compression streams' states before -+ * decoding the rectangle, if some of bits 0,1,2,3 in the compression control -+ * byte are set to 1. Note that the decoder must reset zlib streams even if -+ * the compression type is "fill" or "jpeg". -+ * -+ *-- NOTE 3. The "gradient" filter and "jpeg" compression may be used only -+ * when bits-per-pixel value is either 16 or 32, not 8. -+ * -+ *-- NOTE 4. The width of any Tight-encoded rectangle cannot exceed 2048 -+ * pixels. If a rectangle is wider, it must be split into several rectangles -+ * and each one should be encoded separately. -+ * -+ */ -+ -+#define rfbTightExplicitFilter 0x04 -+#define rfbTightFill 0x08 -+#define rfbTightJpeg 0x09 -+#define rfbTightMaxSubencoding 0x09 -+ -+/* Filters to improve compression efficiency */ -+#define rfbTightFilterCopy 0x00 -+#define rfbTightFilterPalette 0x01 -+#define rfbTightFilterGradient 0x02 -+ -+ -+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ * ZLIBHEX - zlib compressed Hextile Encoding. Essentially, this is the -+ * hextile encoding with zlib compression on the tiles that can not be -+ * efficiently encoded with one of the other hextile subencodings. The -+ * new zlib subencoding uses two bytes to specify the length of the -+ * compressed tile and then the compressed data follows. As with the -+ * raw sub-encoding, the zlib subencoding invalidates the other -+ * values, if they are also set. -+ */ -+ -+#define rfbHextileZlibRaw (1 << 5) -+#define rfbHextileZlibHex (1 << 6) -+ -+ -+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ * XCursor encoding. This is a special encoding used to transmit X-style -+ * cursor shapes from server to clients. Note that for this encoding, -+ * coordinates in rfbFramebufferUpdateRectHeader structure hold hotspot -+ * position (r.x, r.y) and cursor size (r.w, r.h). If (w * h != 0), two RGB -+ * samples are sent after header in the rfbXCursorColors structure. They -+ * denote foreground and background colors of the cursor. If a client -+ * supports only black-and-white cursors, it should ignore these colors and -+ * assume that foreground is black and background is white. Next, two bitmaps -+ * (1 bits per pixel) follow: first one with actual data (value 0 denotes -+ * background color, value 1 denotes foreground color), second one with -+ * transparency data (bits with zero value mean that these pixels are -+ * transparent). Both bitmaps represent cursor data in a byte stream, from -+ * left to right, from top to bottom, and each row is byte-aligned. Most -+ * significant bits correspond to leftmost pixels. The number of bytes in -+ * each row can be calculated as ((w + 7) / 8). If (w * h == 0), cursor -+ * should be hidden (or default local cursor should be set by the client). -+ */ -+ -+typedef struct _rfbXCursorColors { -+ CARD8 foreRed; -+ CARD8 foreGreen; -+ CARD8 foreBlue; -+ CARD8 backRed; -+ CARD8 backGreen; -+ CARD8 backBlue; -+} rfbXCursorColors; -+ -+#define sz_rfbXCursorColors 6 -+ -+ -+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ * RichCursor encoding. This is a special encoding used to transmit cursor -+ * shapes from server to clients. It is similar to the XCursor encoding but -+ * uses client pixel format instead of two RGB colors to represent cursor -+ * image. For this encoding, coordinates in rfbFramebufferUpdateRectHeader -+ * structure hold hotspot position (r.x, r.y) and cursor size (r.w, r.h). -+ * After header, two pixmaps follow: first one with cursor image in current -+ * client pixel format (like in raw encoding), second with transparency data -+ * (1 bit per pixel, exactly the same format as used for transparency bitmap -+ * in the XCursor encoding). If (w * h == 0), cursor should be hidden (or -+ * default local cursor should be set by the client). -+ */ -+ -+ -+/*----------------------------------------------------------------------------- -+ * SetColourMapEntries - these messages are only sent if the pixel -+ * format uses a "colour map" (i.e. trueColour false) and the client has not -+ * fixed the entire colour map using FixColourMapEntries. In addition they -+ * will only start being sent after the client has sent its first -+ * FramebufferUpdateRequest. So if the client always tells the server to use -+ * trueColour then it never needs to process this type of message. -+ */ -+ -+typedef struct _rfbSetColourMapEntriesMsg { -+ CARD8 type; /* always rfbSetColourMapEntries */ -+ CARD8 redIndex; /* used to be pad, but used for DirectColor */ -+ CARD16 firstColour; -+ CARD16 nColours; -+ -+ /* Followed by nColours * 3 * CARD16 -+ r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */ -+ -+} rfbSetColourMapEntriesMsg; -+ -+#define sz_rfbSetColourMapEntriesMsg 6 -+ -+ -+ -+/*----------------------------------------------------------------------------- -+ * Bell - ring a bell on the client if it has one. -+ */ -+ -+typedef struct _rfbBellMsg { -+ CARD8 type; /* always rfbBell */ -+} rfbBellMsg; -+ -+#define sz_rfbBellMsg 1 -+ -+ -+ -+/*----------------------------------------------------------------------------- -+ * ServerCutText - the server has new text in its cut buffer. -+ */ -+ -+typedef struct _rfbServerCutTextMsg { -+ CARD8 type; /* always rfbServerCutText */ -+ CARD8 pad1; -+ CARD16 pad2; -+ CARD32 length; -+ /* followed by char text[length] */ -+} rfbServerCutTextMsg; -+ -+#define sz_rfbServerCutTextMsg 8 -+ -+/*----------------------------------------------------------------------------- -+ * ChromiumStart - a port number for the crserver -+ */ -+ -+typedef struct { -+ CARD8 type; /* always rfbChromiumStart */ -+ CARD8 pad1; -+ CARD16 pad2; -+ CARD32 crServerPort; -+ CARD32 mothershipPort; -+} rfbChromiumStartMsg; -+ -+#define sz_rfbChromiumStartMsg 12 -+ -+ -+/*----------------------------------------------------------------------------- -+ * ChromiumMoveResizeWindow - move a chromium window -+ */ -+ -+typedef struct { -+ CARD8 type; /* always rfbChromiumMoveResizeWindow */ -+ CARD8 pad1; -+ CARD16 pad2; -+ CARD32 winid; -+ CARD32 x; -+ CARD32 y; -+ CARD32 w; -+ CARD32 h; -+} rfbChromiumMoveResizeWindowMsg; -+ -+#define sz_rfbChromiumMoveResizeWindowMsg 24 -+ -+/*----------------------------------------------------------------------------- -+ * ChromiumClipList - send clip list -+ */ -+ -+typedef struct { -+ CARD8 type; /* always rfbChromiumClipList */ -+ CARD8 pad1; -+ CARD16 pad2; -+ CARD32 winid; -+ CARD32 length; -+} rfbChromiumClipListMsg; -+ -+#define sz_rfbChromiumClipListMsg 12 -+ -+/*----------------------------------------------------------------------------- -+ * ChromiumWindowShow - map or unmap a window -+ */ -+ -+typedef struct { -+ CARD8 type; /* always rfbChromiumWindowShow */ -+ CARD8 pad1; -+ CARD16 pad2; -+ CARD32 winid; -+ CARD32 show; -+} rfbChromiumWindowShowMsg; -+ -+#define sz_rfbChromiumWindowShowMsg 12 -+ -+/*----------------------------------------------------------------------------- -+ * ChromiumWindowDestroy - destroy a window -+ */ -+ -+typedef struct { -+ CARD8 type; /* always rfbChromiumWindowDestroy */ -+ CARD8 pad1; -+ CARD16 pad2; -+ CARD32 winid; -+} rfbChromiumWindowDestroyMsg; -+ -+#define sz_rfbChromiumWindowDestroyMsg 8 -+ -+/*----------------------------------------------------------------------------- -+ * FileListData -+ */ -+ -+typedef struct _rfbFileListDataMsg { -+ CARD8 type; -+ CARD8 flags; -+ CARD16 numFiles; -+ CARD16 dataSize; -+ CARD16 compressedSize; -+ /* Followed by SizeData[numFiles] */ -+ /* Followed by Filenames[compressedSize] */ -+} rfbFileListDataMsg; -+ -+#define sz_rfbFileListDataMsg 8 -+ -+/*----------------------------------------------------------------------------- -+ * FileDownloadData -+ */ -+ -+typedef struct _rfbFileDownloadDataMsg { -+ CARD8 type; -+ CARD8 compressLevel; -+ CARD16 realSize; -+ CARD16 compressedSize; -+ /* Followed by File[copressedSize] */ -+} rfbFileDownloadDataMsg; -+ -+#define sz_rfbFileDownloadDataMsg 6 -+ -+ -+/*----------------------------------------------------------------------------- -+ * FileUploadCancel -+ */ -+ -+typedef struct _rfbFileUploadCancelMsg { -+ CARD8 type; -+ CARD8 unused; -+ CARD16 reasonLen; -+ /* Followed by reason[reasonLen] */ -+} rfbFileUploadCancelMsg; -+ -+#define sz_rfbFileUploadCancelMsg 4 -+ -+/*----------------------------------------------------------------------------- -+ * FileDownloadFailed -+ */ -+ -+typedef struct _rfbFileDownloadFailedMsg { -+ CARD8 type; -+ CARD8 unused; -+ CARD16 reasonLen; -+ /* Followed by reason[reasonLen] */ -+} rfbFileDownloadFailedMsg; -+ -+#define sz_rfbFileDownloadFailedMsg 4 -+ -+/*----------------------------------------------------------------------------- -+ * Union of all server->client messages. -+ */ -+ -+typedef union _rfbServerToClientMsg { -+ CARD8 type; -+ rfbFramebufferUpdateMsg fu; -+ rfbSetColourMapEntriesMsg scme; -+ rfbBellMsg b; -+ rfbServerCutTextMsg sct; -+ rfbFileListDataMsg fld; -+ rfbFileDownloadDataMsg fdd; -+ rfbFileUploadCancelMsg fuc; -+ rfbFileDownloadFailedMsg fdf; -+ rfbChromiumStartMsg scd; -+ rfbChromiumMoveResizeWindowMsg scm; -+ rfbChromiumClipListMsg sccl; -+ rfbChromiumWindowShowMsg scws; -+ rfbChromiumWindowDestroyMsg scwd; -+} rfbServerToClientMsg; -+ -+ -+ -+/***************************************************************************** -+ * -+ * Message definitions (client -> server) -+ * -+ *****************************************************************************/ -+ -+ -+/*----------------------------------------------------------------------------- -+ * SetPixelFormat - tell the RFB server the format in which the client wants -+ * pixels sent. -+ */ -+ -+typedef struct _rfbSetPixelFormatMsg { -+ CARD8 type; /* always rfbSetPixelFormat */ -+ CARD8 pad1; -+ CARD16 pad2; -+ rfbPixelFormat format; -+} rfbSetPixelFormatMsg; -+ -+#define sz_rfbSetPixelFormatMsg (sz_rfbPixelFormat + 4) -+ -+ -+/*----------------------------------------------------------------------------- -+ * FixColourMapEntries - when the pixel format uses a "colour map", fix -+ * read-only colour map entries. -+ * -+ * ***************** NOT CURRENTLY SUPPORTED ***************** -+ */ -+ -+typedef struct _rfbFixColourMapEntriesMsg { -+ CARD8 type; /* always rfbFixColourMapEntries */ -+ CARD8 pad; -+ CARD16 firstColour; -+ CARD16 nColours; -+ -+ /* Followed by nColours * 3 * CARD16 -+ r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */ -+ -+} rfbFixColourMapEntriesMsg; -+ -+#define sz_rfbFixColourMapEntriesMsg 6 -+ -+ -+/*----------------------------------------------------------------------------- -+ * SetEncodings - tell the RFB server which encoding types we accept. Put them -+ * in order of preference, if we have any. We may always receive raw -+ * encoding, even if we don't specify it here. -+ */ -+ -+typedef struct _rfbSetEncodingsMsg { -+ CARD8 type; /* always rfbSetEncodings */ -+ CARD8 pad; -+ CARD16 nEncodings; -+ /* followed by nEncodings * CARD32 encoding types */ -+} rfbSetEncodingsMsg; -+ -+#define sz_rfbSetEncodingsMsg 4 -+ -+ -+/*----------------------------------------------------------------------------- -+ * FramebufferUpdateRequest - request for a framebuffer update. If incremental -+ * is true then the client just wants the changes since the last update. If -+ * false then it wants the whole of the specified rectangle. -+ */ -+ -+typedef struct _rfbFramebufferUpdateRequestMsg { -+ CARD8 type; /* always rfbFramebufferUpdateRequest */ -+ CARD8 incremental; -+ CARD16 x; -+ CARD16 y; -+ CARD16 w; -+ CARD16 h; -+} rfbFramebufferUpdateRequestMsg; -+ -+#define sz_rfbFramebufferUpdateRequestMsg 10 -+ -+ -+/*----------------------------------------------------------------------------- -+ * KeyEvent - key press or release -+ * -+ * Keys are specified using the "keysym" values defined by the X Window System. -+ * For most ordinary keys, the keysym is the same as the corresponding ASCII -+ * value. Other common keys are: -+ * -+ * BackSpace 0xff08 -+ * Tab 0xff09 -+ * Return or Enter 0xff0d -+ * Escape 0xff1b -+ * Insert 0xff63 -+ * Delete 0xffff -+ * Home 0xff50 -+ * End 0xff57 -+ * Page Up 0xff55 -+ * Page Down 0xff56 -+ * Left 0xff51 -+ * Up 0xff52 -+ * Right 0xff53 -+ * Down 0xff54 -+ * F1 0xffbe -+ * F2 0xffbf -+ * ... ... -+ * F12 0xffc9 -+ * Shift 0xffe1 -+ * Control 0xffe3 -+ * Meta 0xffe7 -+ * Alt 0xffe9 -+ */ -+ -+typedef struct _rfbKeyEventMsg { -+ CARD8 type; /* always rfbKeyEvent */ -+ CARD8 down; /* true if down (press), false if up */ -+ CARD16 pad; -+ CARD32 key; /* key is specified as an X keysym */ -+} rfbKeyEventMsg; -+ -+#define sz_rfbKeyEventMsg 8 -+ -+ -+/*----------------------------------------------------------------------------- -+ * PointerEvent - mouse/pen move and/or button press. -+ */ -+ -+typedef struct _rfbPointerEventMsg { -+ CARD8 type; /* always rfbPointerEvent */ -+ CARD8 buttonMask; /* bits 0-7 are buttons 1-8, 0=up, 1=down */ -+ CARD16 x; -+ CARD16 y; -+} rfbPointerEventMsg; -+ -+#define rfbButton1Mask 1 -+#define rfbButton2Mask 2 -+#define rfbButton3Mask 4 -+#define rfbButton4Mask 8 -+#define rfbButton5Mask 16 -+ -+#define sz_rfbPointerEventMsg 6 -+ -+ -+ -+/*----------------------------------------------------------------------------- -+ * ClientCutText - the client has new text in its cut buffer. -+ */ -+ -+typedef struct _rfbClientCutTextMsg { -+ CARD8 type; /* always rfbClientCutText */ -+ CARD8 pad1; -+ CARD16 pad2; -+ CARD32 length; -+ /* followed by char text[length] */ -+} rfbClientCutTextMsg; -+ -+#define sz_rfbClientCutTextMsg 8 -+ -+/*----------------------------------------------------------------------------- -+ * FileListRequest -+ */ -+ -+typedef struct _rfbFileListRequestMsg { -+ CARD8 type; -+ CARD8 flags; -+ CARD16 dirNameSize; -+ /* Followed by char Dirname[dirNameSize] */ -+} rfbFileListRequestMsg; -+ -+#define sz_rfbFileListRequestMsg 4 -+ -+/*----------------------------------------------------------------------------- -+ * FileDownloadRequest -+ */ -+ -+typedef struct _rfbFileDownloadRequestMsg { -+ CARD8 type; -+ CARD8 compressedLevel; -+ CARD16 fNameSize; -+ CARD32 position; -+ /* Followed by char Filename[fNameSize] */ -+} rfbFileDownloadRequestMsg; -+ -+#define sz_rfbFileDownloadRequestMsg 8 -+ -+/*----------------------------------------------------------------------------- -+ * FileUploadRequest -+ */ -+ -+typedef struct _rfbFileUploadRequestMsg { -+ CARD8 type; -+ CARD8 compressedLevel; -+ CARD16 fNameSize; -+ CARD32 position; -+ /* Followed by char Filename[fNameSize] */ -+} rfbFileUploadRequestMsg; -+ -+#define sz_rfbFileUploadRequestMsg 8 -+ -+ -+/*----------------------------------------------------------------------------- -+ * FileUploadData -+ */ -+ -+typedef struct _rfbFileUploadDataMsg { -+ CARD8 type; -+ CARD8 compressedLevel; -+ CARD16 realSize; -+ CARD16 compressedSize; -+ /* Followed by File[compressedSize] */ -+} rfbFileUploadDataMsg; -+ -+#define sz_rfbFileUploadDataMsg 8 -+ -+/*----------------------------------------------------------------------------- -+ * FileDownloadCancel -+ */ -+ -+typedef struct _rfbFileDownloadCancelMsg { -+ CARD8 type; -+ CARD8 unused; -+ CARD16 reasonLen; -+ /* Followed by reason[reasonLen] */ -+} rfbFileDownloadCancelMsg; -+ -+#define sz_rfbFileDownloadCancelMsg 4 -+ -+/*----------------------------------------------------------------------------- -+ * FileUploadFailed -+ */ -+ -+typedef struct _rfbFileUploadFailedMsg { -+ CARD8 type; -+ CARD8 unused; -+ CARD16 reasonLen; -+ /* Followed by reason[reasonLen] */ -+} rfbFileUploadFailedMsg; -+ -+#define sz_rfbFileUploadFailedMsg 4 -+ -+/*----------------------------------------------------------------------------- -+ * FileCreateDirRequest -+ */ -+ -+typedef struct _rfbFileCreateDirRequestMsg { -+ CARD8 type; -+ CARD8 unused; -+ CARD16 dNameLen; -+ CARD32 dModTime; -+ /* Followed by dName[dNameLen] */ -+} rfbFileCreateDirRequestMsg; -+ -+#define sz_rfbFileCreateDirRequestMsg 8 -+ -+/*----------------------------------------------------------------------------- -+ * ChromiumStop - the client has stopped the GL app. -+ */ -+ -+typedef struct { -+ CARD8 type; /* always rfbChromiumStop */ -+ CARD8 pad1; -+ CARD16 pad2; -+ CARD32 port; -+} rfbChromiumStopMsg; -+ -+#define sz_rfbChromiumStopMsg 8 -+ -+/*----------------------------------------------------------------------------- -+ * ChromiumExpose - redraw the window -+ */ -+ -+typedef struct { -+ CARD8 type; /* always rfbChromiumExpose */ -+ CARD8 pad1; -+ CARD16 pad2; -+ CARD32 winid; -+} rfbChromiumExposeMsg; -+ -+#define sz_rfbChromiumExposeMsg 8 -+ -+/*----------------------------------------------------------------------------- -+ * Union of all client->server messages. -+ */ -+ -+typedef union _rfbClientToServerMsg { -+ CARD8 type; -+ rfbSetPixelFormatMsg spf; -+ rfbFixColourMapEntriesMsg fcme; -+ rfbSetEncodingsMsg se; -+ rfbFramebufferUpdateRequestMsg fur; -+ rfbKeyEventMsg ke; -+ rfbPointerEventMsg pe; -+ rfbClientCutTextMsg cct; -+ rfbFileListRequestMsg flr; -+ rfbFileDownloadRequestMsg fdr; -+ rfbFileUploadRequestMsg fupr; -+ rfbFileUploadDataMsg fud; -+ rfbFileDownloadCancelMsg fdc; -+ rfbFileUploadFailedMsg fuf; -+ rfbFileCreateDirRequestMsg fcdr; -+ rfbChromiumStopMsg csd; -+ rfbChromiumExposeMsg cse; -+} rfbClientToServerMsg; -diff -pruN xorg-server-1.12.1.orig/hw/vnc/rfbserver.c xorg-server-1.12.1/hw/vnc/rfbserver.c ---- xorg-server-1.12.1.orig/hw/vnc/rfbserver.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/rfbserver.c 2012-04-18 14:45:21.581820891 -0500 -@@ -0,0 +1,2269 @@ -+/* -+ * rfbserver.c - deal with server-side of the RFB protocol. -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * Copyright (C) 2000-2004 Constantin Kaplinsky. All Rights Reserved. -+ * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. -+ * 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. -+ */ -+ -+/* Use ``#define CORBA'' to enable CORBA control interface */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "input.h" -+#include "mipointer.h" -+#if XFREE86VNC -+#include -+#endif -+#ifdef CHROMIUM -+#include "mivalidate.h" -+#endif -+#include "rfb.h" -+#include "windowstr.h" -+#include "sprite.h" -+#include "propertyst.h" -+#include -+#include -+#include -+ -+#ifdef CORBA -+#include -+#endif -+ -+#ifdef CHROMIUM -+struct CRWindowTable *windowTable = NULL; -+#endif -+ -+extern Atom VNC_CONNECT; -+ -+rfbClientPtr rfbClientHead = NULL; /* list of all VNC clients/viewers */ -+rfbClientPtr pointerClient = NULL; /* Mutex for pointer events */ -+ -+static rfbClientPtr rfbNewClient(ScreenPtr pScreen, int sock); -+static void rfbProcessClientProtocolVersion(rfbClientPtr cl); -+static void rfbProcessClientInitMessage(rfbClientPtr cl); -+static void rfbSendInteractionCaps(rfbClientPtr cl); -+static void rfbProcessClientNormalMessage(rfbClientPtr cl); -+static Bool rfbSendCopyRegion(rfbClientPtr cl, RegionPtr reg, int dx, int dy); -+static Bool rfbSendLastRectMarker(rfbClientPtr cl); -+ -+static char *text = NULL; -+ -+void -+rfbRootPropertyChange(ScreenPtr pScreen) -+{ -+ PropertyPtr pProp; -+ WindowPtr pWin = pScreen->root; -+ -+ pProp = wUserProps (pWin); -+ -+ while (pProp) { -+ if ((pProp->propertyName == XA_CUT_BUFFER0) && -+ (pProp->type == XA_STRING) && -+ (pProp->format == 8)) -+ { -+ /* Ensure we don't keep re-sending cut buffer */ -+ -+ if ( (text && pProp->data && strncmp(text, pProp->data, pProp->size)) || !text) -+ rfbGotXCutText(pProp->data, pProp->size); -+ -+ if (text) free(text); -+ text = malloc(1 + pProp->size); -+ if (! text) return; -+ if (pProp->data) memcpy(text, pProp->data, pProp->size); -+ text[pProp->size] = '\0'; -+ -+ return; -+ } -+ if ((pProp->propertyName == VNC_CONNECT) && (pProp->type == XA_STRING) -+ && (pProp->format == 8) && (pProp->size > 0)) -+ { -+ int i; -+ rfbClientPtr cl; -+ int port = 5500; -+ char *host = (char *)malloc(pProp->size+1); -+ memcpy(host, pProp->data, pProp->size); -+ host[pProp->size] = 0; -+ for (i = 0; i < pProp->size; i++) { -+ if (host[i] == ':') { -+ port = atoi(&host[i+1]); -+ host[i] = 0; -+ } -+ } -+ -+ cl = rfbReverseConnection(pScreen, host, port); -+ -+#ifdef CORBA -+ if (cl != NULL) -+ newConnection(cl, (KEYBOARD_DEVICE|POINTER_DEVICE), 1, 1, 1); -+#endif -+ -+ ChangeWindowProperty(pWin, -+ pProp->propertyName, pProp->type, -+ pProp->format, PropModeReplace, -+ 0, NULL, -+ FALSE -+ ); -+ -+ free(host); -+ } -+ pProp = pProp->next; -+ } -+} -+ -+int -+rfbBitsPerPixel(int depth) -+{ -+ if (depth == 1) return 1; -+ else if (depth <= 8) return 8; -+ else if (depth <= 16) return 16; -+ else return 32; -+} -+ -+void -+rfbUserAllow(int sock, int accept) -+{ -+ rfbClientPtr cl; -+ -+ for (cl = rfbClientHead; cl; cl = cl->next) { -+ if (cl->sock == sock) { -+ cl->userAccepted = accept; -+ } -+ } -+} -+ -+/* -+ * rfbNewClientConnection is called from sockets.c when a new connection -+ * comes in. -+ */ -+ -+void -+rfbNewClientConnection(ScreenPtr pScreen, int sock) -+{ -+ rfbClientPtr cl; -+ -+ cl = rfbNewClient(pScreen, sock); -+ -+ GenerateVncConnectedEvent(sock); -+ -+#if XFREE86VNC -+ /* Someone is connected - disable VT switching */ -+ xf86EnableVTSwitch(FALSE); -+#endif -+ -+#ifdef CORBA -+ if (cl != NULL) -+ newConnection(cl, (KEYBOARD_DEVICE|POINTER_DEVICE), 1, 1, 1); -+#endif -+} -+ -+ -+/* -+ * rfbReverseConnection is called by the CORBA stuff to make an outward -+ * connection to a "listening" RFB client. -+ */ -+ -+rfbClientPtr -+rfbReverseConnection(ScreenPtr pScreen, char *host, int port) -+{ -+ int sock; -+ rfbClientPtr cl; -+ -+ if ((sock = rfbConnect(pScreen, host, port)) < 0) -+ return (rfbClientPtr)NULL; -+ -+ cl = rfbNewClient(pScreen, sock); -+ -+ if (cl) { -+ cl->reverseConnection = TRUE; -+ } -+ -+ return cl; -+} -+ -+ -+#ifdef CHROMIUM -+/* -+ * rfbSetClip -- -+ * Generate expose event. -+ * This function is overkill and should be cleaned up, but it -+ * works for now. -+ */ -+ -+void -+rfbSetClip (WindowPtr pWin, BOOL enable) -+{ -+ ScreenPtr pScreen = pWin->drawable.pScreen; -+ WindowPtr pChild; -+ Bool WasViewable = (Bool)(pWin->viewable); -+ Bool anyMarked = FALSE; -+ RegionPtr pOldClip = NULL; -+#ifdef DO_SAVE_UNDERS -+ Bool dosave = FALSE; -+#endif -+ WindowPtr pLayerWin; -+ BoxRec box; -+ -+ if (WasViewable) -+ { -+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) -+ { -+ (void) (*pScreen->MarkOverlappedWindows)(pChild, -+ pChild, -+ &pLayerWin); -+ } -+ (*pScreen->MarkWindow) (pWin); -+ anyMarked = TRUE; -+ if (pWin->valdata) -+ { -+ if (HasBorder (pWin)) -+ { -+ RegionPtr borderVisible; -+ -+ borderVisible = REGION_CREATE(pScreen, NullBox, 1); -+ REGION_SUBTRACT(pScreen, borderVisible, -+ &pWin->borderClip, &pWin->winSize); -+ pWin->valdata->before.borderVisible = borderVisible; -+ } -+ pWin->valdata->before.resized = TRUE; -+ } -+ } -+ -+ /* -+ * Use REGION_BREAK to avoid optimizations in ValidateTree -+ * that assume the root borderClip can't change well, normally -+ * it doesn't...) -+ */ -+ if (enable) -+ { -+ box.x1 = 0; -+ box.y1 = 0; -+ box.x2 = pScreen->width; -+ box.y2 = pScreen->height; -+ REGION_INIT (pScreen, &pWin->winSize, &box, 1); -+ REGION_INIT (pScreen, &pWin->borderSize, &box, 1); -+ if (WasViewable) -+ REGION_RESET(pScreen, &pWin->borderClip, &box); -+ pWin->drawable.width = pScreen->width; -+ pWin->drawable.height = pScreen->height; -+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); -+ } -+ else -+ { -+ REGION_EMPTY(pScreen, &pWin->borderClip); -+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); -+ } -+ -+ ResizeChildrenWinSize (pWin, 0, 0, 0, 0); -+ -+ if (WasViewable) -+ { -+ if (pWin->backStorage) -+ { -+ pOldClip = REGION_CREATE(pScreen, NullBox, 1); -+ REGION_COPY(pScreen, pOldClip, &pWin->clipList); -+ } -+ -+ if (pWin->firstChild) -+ { -+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild, -+ pWin->firstChild, -+ (WindowPtr *)NULL); -+ } -+ else -+ { -+ (*pScreen->MarkWindow) (pWin); -+ anyMarked = TRUE; -+ } -+ -+#ifdef DO_SAVE_UNDERS -+ if (DO_SAVE_UNDERS(pWin)) -+ { -+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin); -+ } -+#endif /* DO_SAVE_UNDERS */ -+ -+ if (anyMarked) -+ (*pScreen->ValidateTree)(pWin, NullWindow, VTOther); -+ } -+ -+ if (WasViewable) -+ { -+ if (anyMarked) -+ (*pScreen->HandleExposures)(pWin); -+#ifdef DO_SAVE_UNDERS -+ if (dosave) -+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin); -+#endif /* DO_SAVE_UNDERS */ -+ if (anyMarked && pScreen->PostValidateTree) -+ (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther); -+ } -+ if (pWin->realized) -+ WindowsRestructured (); -+ FlushAllOutput (); -+} -+#endif /* CHROMIUM */ -+ -+/* -+ * rfbNewClient is called when a new connection has been made by whatever -+ * means. -+ */ -+ -+static rfbClientPtr -+rfbNewClient(ScreenPtr pScreen, int sock) -+{ -+ rfbProtocolVersionMsg pv; -+ rfbClientPtr cl; -+ BoxRec box; -+ struct sockaddr_in addr; -+ SOCKLEN_T addrlen = sizeof(struct sockaddr_in); -+ VNCSCREENPTR(pScreen); -+ int i; -+ -+ if (rfbClientHead == NULL) { -+ /* no other clients - make sure we don't think any keys are pressed */ -+ KbdReleaseAllKeys(); -+ } else { -+ rfbLog(" (other clients"); -+ for (cl = rfbClientHead; cl; cl = cl->next) { -+ rfbLog(" %s",cl->host); -+ } -+ rfbLog(")\n"); -+ } -+ -+ cl = (rfbClientPtr)malloc(sizeof(rfbClientRec)); -+ -+#ifdef CHROMIUM -+ cl->chromium_port = 0; /* no GL application on this port, yet */ -+#endif -+ cl->userAccepted = 0; /* user hasn't even approached this yet .... */ -+ cl->sock = sock; -+ getpeername(sock, (struct sockaddr *)&addr, &addrlen); -+ cl->host = strdup(inet_ntoa(addr.sin_addr)); -+ cl->login = NULL; -+ -+ /* Dispatch client input to rfbProcessClientProtocolVersion(). */ -+ cl->state = RFB_PROTOCOL_VERSION; -+ -+ cl->viewOnly = FALSE; -+ cl->reverseConnection = FALSE; -+ cl->readyForSetColourMapEntries = FALSE; -+ cl->useCopyRect = FALSE; -+ cl->preferredEncoding = rfbEncodingRaw; -+ cl->correMaxWidth = 48; -+ cl->correMaxHeight = 48; -+ cl->pScreen = pScreen; -+ -+ REGION_NULL(pScreen,&cl->copyRegion); -+ cl->copyDX = 0; -+ cl->copyDY = 0; -+ -+ box.x1 = box.y1 = 0; -+ box.x2 = pVNC->width; -+ box.y2 = pVNC->height; -+ REGION_INIT(pScreen,&cl->modifiedRegion,&box,0); -+ -+ REGION_NULL(pScreen,&cl->requestedRegion); -+ -+ cl->deferredUpdateScheduled = FALSE; -+ cl->deferredUpdateTimer = NULL; -+ -+ cl->format = pVNC->rfbServerFormat; -+ cl->translateFn = rfbTranslateNone; -+ cl->translateLookupTable = NULL; -+ -+ cl->tightCompressLevel = TIGHT_DEFAULT_COMPRESSION; -+ cl->tightQualityLevel = -1; -+ for (i = 0; i < 4; i++) -+ cl->zsActive[i] = FALSE; -+ -+ cl->enableCursorShapeUpdates = FALSE; -+ cl->enableCursorPosUpdates = FALSE; -+ cl->enableLastRectEncoding = FALSE; -+#ifdef CHROMIUM -+ cl->enableChromiumEncoding = FALSE; -+#endif -+ -+ cl->next = rfbClientHead; -+ rfbClientHead = cl; -+ -+ rfbResetStats(cl); -+ -+ cl->compStreamInited = FALSE; -+ cl->compStream.total_in = 0; -+ cl->compStream.total_out = 0; -+ cl->compStream.zalloc = Z_NULL; -+ cl->compStream.zfree = Z_NULL; -+ cl->compStream.opaque = Z_NULL; -+ -+ cl->zlibCompressLevel = 5; -+ -+ sprintf(pv,rfbProtocolVersionFormat,rfbProtocolMajorVersion, -+ rfbProtocolMinorVersion); -+ -+ if (WriteExact(sock, pv, sz_rfbProtocolVersionMsg) < 0) { -+ rfbLogPerror("rfbNewClient: write"); -+ rfbCloseSock(pScreen, sock); -+ return NULL; -+ } -+ -+ return cl; -+} -+ -+ -+/* -+ * rfbClientConnectionGone is called from sockets.c just after a connection -+ * has gone away. -+ */ -+ -+void -+rfbClientConnectionGone(int sock) -+{ -+ rfbClientPtr cl, prev; -+ int i; -+#if XFREE86VNC -+ int allowvt = TRUE; -+#endif -+ -+ for (prev = NULL, cl = rfbClientHead; cl; prev = cl, cl = cl->next) { -+ if (sock == cl->sock) -+ break; -+ } -+ -+ if (!cl) { -+ rfbLog("rfbClientConnectionGone: unknown socket %d\n",sock); -+ return; -+ } -+ -+ rfbLog("rfbClientConnectionGone\n"); -+ -+ if (cl->login != NULL) { -+ rfbLog("VNC Client %s (%s) gone\n", cl->login, cl->host); -+ free(cl->login); -+ } else { -+ rfbLog("VNC Client %s gone\n", cl->host); -+ } -+ free(cl->host); -+ -+ /* Release the compression state structures if any. */ -+ if ( cl->compStreamInited == TRUE ) { -+ deflateEnd( &(cl->compStream) ); -+ } -+ -+ for (i = 0; i < 4; i++) { -+ if (cl->zsActive[i]) -+ deflateEnd(&cl->zsStruct[i]); -+ } -+ -+ if (pointerClient == cl) -+ pointerClient = NULL; -+ -+#ifdef CORBA -+ destroyConnection(cl); -+#endif -+ -+ if (prev) -+ prev->next = cl->next; -+ else -+ rfbClientHead = cl->next; -+ -+ REGION_UNINIT(cl->pScreen,&cl->copyRegion); -+ REGION_UNINIT(cl->pScreen,&cl->modifiedRegion); -+ TimerFree(cl->deferredUpdateTimer); -+ -+ rfbPrintStats(cl); -+ -+ if (cl->translateLookupTable) free(cl->translateLookupTable); -+ -+ free(cl); -+ -+ GenerateVncDisconnectedEvent(sock); -+ -+#if XFREE86VNC -+ for (cl = rfbClientHead; cl; cl = cl->next) { -+ /* still someone connected */ -+ allowvt = FALSE; -+ } -+ -+ xf86EnableVTSwitch(allowvt); -+#endif -+} -+ -+ -+/* -+ * rfbProcessClientMessage is called when there is data to read from a client. -+ */ -+ -+void -+rfbProcessClientMessage(ScreenPtr pScreen, int sock) -+{ -+ rfbClientPtr cl; -+ -+ for (cl = rfbClientHead; cl; cl = cl->next) { -+ if (sock == cl->sock) -+ break; -+ } -+ -+ if (!cl) { -+ rfbLog("rfbProcessClientMessage: unknown socket %d\n",sock); -+ rfbCloseSock(pScreen, sock); -+ return; -+ } -+ -+#ifdef CORBA -+ if (isClosePending(cl)) { -+ rfbLog("Closing connection to client %s\n", cl->host); -+ rfbCloseSock(pScreen, sock); -+ return; -+ } -+#endif -+ -+ switch (cl->state) { -+ case RFB_PROTOCOL_VERSION: -+ rfbProcessClientProtocolVersion(cl); -+ break; -+ case RFB_SECURITY_TYPE: /* protocol 3.7 */ -+ rfbProcessClientSecurityType(cl); -+ break; -+ case RFB_TUNNELING_TYPE: /* protocol 3.7t */ -+ rfbProcessClientTunnelingType(cl); -+ break; -+ case RFB_AUTH_TYPE: /* protocol 3.7t */ -+ rfbProcessClientAuthType(cl); -+ break; -+ case RFB_AUTHENTICATION: -+ rfbVncAuthProcessResponse(cl); -+ break; -+ case RFB_INITIALISATION: -+ rfbProcessClientInitMessage(cl); -+ break; -+ default: -+ rfbProcessClientNormalMessage(cl); -+ } -+} -+ -+ -+/* -+ * rfbProcessClientProtocolVersion is called when the client sends its -+ * protocol version. -+ */ -+ -+static void -+rfbProcessClientProtocolVersion(rfbClientPtr cl) -+{ -+ rfbProtocolVersionMsg pv; -+ int n, major, minor; -+ -+ if ((n = ReadExact(cl->sock, pv, sz_rfbProtocolVersionMsg)) <= 0) { -+ if (n == 0) -+ rfbLog("rfbProcessClientProtocolVersion: client gone\n"); -+ else -+ rfbLogPerror("rfbProcessClientProtocolVersion: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ pv[sz_rfbProtocolVersionMsg] = 0; -+ if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) { -+ rfbLog("rfbProcessClientProtocolVersion: not a valid RFB client\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ rfbLog("Using protocol version %d.%d\n", major, minor); -+ -+ if (major != rfbProtocolMajorVersion) { -+ rfbLog("RFB protocol version mismatch - server %d.%d, client %d.%d\n", -+ rfbProtocolMajorVersion,rfbProtocolMinorVersion,major,minor); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ /* Always use one of the two standard versions of the RFB protocol. */ -+ cl->protocol_minor_ver = minor; -+ if (minor > rfbProtocolMinorVersion) { -+ cl->protocol_minor_ver = rfbProtocolMinorVersion; -+ } else if (minor < rfbProtocolMinorVersion) { -+ cl->protocol_minor_ver = rfbProtocolFallbackMinorVersion; -+ } -+ if (minor != rfbProtocolMinorVersion && -+ minor != rfbProtocolFallbackMinorVersion) { -+ rfbLog("Non-standard protocol version %d.%d, using %d.%d instead\n", -+ major, minor, rfbProtocolMajorVersion, cl->protocol_minor_ver); -+ } -+ -+ /* TightVNC protocol extensions are not enabled yet. */ -+ cl->protocol_tightvnc = FALSE; -+ -+ rfbAuthNewClient(cl); -+} -+ -+/* -+ * rfbClientConnFailed is called when a client connection has failed -+ * before the authentication stage. -+ */ -+ -+void -+rfbClientConnFailed(rfbClientPtr cl, char *reason) -+{ -+ int headerLen, reasonLen; -+ char buf[8]; -+ -+ headerLen = (cl->protocol_minor_ver >= 7) ? 1 : 4; -+ reasonLen = strlen(reason); -+ ((CARD32 *)buf)[0] = 0; -+ ((CARD32 *)buf)[1] = Swap32IfLE(reasonLen); -+ -+ if ( WriteExact(cl->sock, buf, headerLen) < 0 || -+ WriteExact(cl->sock, buf + 4, 4) < 0 || -+ WriteExact(cl->sock, reason, reasonLen) < 0 ) { -+ rfbLogPerror("rfbClientConnFailed: write"); -+ } -+ -+ rfbCloseSock(cl->pScreen, cl->sock); -+} -+ -+ -+/* -+ * rfbProcessClientInitMessage is called when the client sends its -+ * initialisation message. -+ */ -+ -+static void -+rfbProcessClientInitMessage(rfbClientPtr cl) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ rfbClientInitMsg ci; -+ char buf[256]; -+ rfbServerInitMsg *si = (rfbServerInitMsg *)buf; -+ struct passwd *user; -+ int len, n; -+ rfbClientPtr otherCl, nextCl; -+ -+ if ((n = ReadExact(cl->sock, (char *)&ci,sz_rfbClientInitMsg)) <= 0) { -+ if (n == 0) -+ rfbLog("rfbProcessClientInitMessage: client gone\n"); -+ else -+ rfbLogPerror("rfbProcessClientInitMessage: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ si->framebufferWidth = Swap16IfLE(pVNC->width); -+ si->framebufferHeight = Swap16IfLE(pVNC->height); -+ si->format = pVNC->rfbServerFormat; -+ si->format.redMax = Swap16IfLE(si->format.redMax); -+ si->format.greenMax = Swap16IfLE(si->format.greenMax); -+ si->format.blueMax = Swap16IfLE(si->format.blueMax); -+ -+ user = getpwuid(getuid()); -+ -+ if (strlen(desktopName) > 128) /* sanity check on desktop name len */ -+ desktopName[128] = 0; -+ -+ if (user) { -+ sprintf(buf + sz_rfbServerInitMsg, "%s's %s desktop (%s:%s)", -+ user->pw_name, desktopName, rfbThisHost, display); -+ } else { -+ sprintf(buf + sz_rfbServerInitMsg, "%s desktop (%s:%s)", -+ desktopName, rfbThisHost, display); -+ } -+ len = strlen(buf + sz_rfbServerInitMsg); -+ si->nameLength = Swap32IfLE(len); -+ -+ if (WriteExact(cl->sock, buf, sz_rfbServerInitMsg + len) < 0) { -+ rfbLogPerror("rfbProcessClientInitMessage: write"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ if (cl->protocol_tightvnc) -+ rfbSendInteractionCaps(cl); /* protocol 3.7t */ -+ -+ /* Dispatch client input to rfbProcessClientNormalMessage(). */ -+ cl->state = RFB_NORMAL; -+ -+ if (!cl->reverseConnection && -+ (pVNC->rfbNeverShared || (!pVNC->rfbAlwaysShared && !ci.shared))) { -+ -+ if (pVNC->rfbDontDisconnect) { -+ for (otherCl = rfbClientHead; otherCl; otherCl = otherCl->next) { -+ if ((otherCl != cl) && (otherCl->state == RFB_NORMAL)) { -+ rfbLog("-dontdisconnect: Not shared & existing client\n"); -+ rfbLog(" refusing new client %s\n", cl->host); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ } -+ } else { -+ for (otherCl = rfbClientHead; otherCl; otherCl = nextCl) { -+ nextCl = otherCl->next; -+ if ((otherCl != cl) && (otherCl->state == RFB_NORMAL)) { -+ rfbLog("Not shared - closing connection to client %s\n", -+ otherCl->host); -+ rfbCloseSock(otherCl->pScreen, otherCl->sock); -+ } -+ } -+ } -+ } -+} -+ -+ -+/* -+ * rfbSendInteractionCaps is called after sending the server -+ * initialisation message, only if the protocol version is 3.130. -+ * In this function, we send the lists of supported protocol messages -+ * and encodings. -+ */ -+ -+/* Update these constants on changing capability lists below! */ -+#define N_SMSG_CAPS 0 -+#define N_CMSG_CAPS 0 -+#define N_ENC_CAPS 12 -+ -+void -+rfbSendInteractionCaps(rfbClientPtr cl) -+{ -+ rfbInteractionCapsMsg intr_caps; -+ rfbCapabilityInfo enc_list[N_ENC_CAPS]; -+ int i; -+ -+ /* Fill in the header structure sent prior to capability lists. */ -+ intr_caps.nServerMessageTypes = Swap16IfLE(N_SMSG_CAPS); -+ intr_caps.nClientMessageTypes = Swap16IfLE(N_CMSG_CAPS); -+ intr_caps.nEncodingTypes = Swap16IfLE(N_ENC_CAPS); -+ intr_caps.pad = 0; -+ -+ /* Supported server->client message types. */ -+ /* For future file transfer support: -+ i = 0; -+ SetCapInfo(&smsg_list[i++], rfbFileListData, rfbTightVncVendor); -+ SetCapInfo(&smsg_list[i++], rfbFileDownloadData, rfbTightVncVendor); -+ SetCapInfo(&smsg_list[i++], rfbFileUploadCancel, rfbTightVncVendor); -+ SetCapInfo(&smsg_list[i++], rfbFileDownloadFailed, rfbTightVncVendor); -+ if (i != N_SMSG_CAPS) { -+ rfbLog("rfbSendInteractionCaps: assertion failed, i != N_SMSG_CAPS\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ */ -+ -+ /* Supported client->server message types. */ -+ /* For future file transfer support: -+ i = 0; -+ SetCapInfo(&cmsg_list[i++], rfbFileListRequest, rfbTightVncVendor); -+ SetCapInfo(&cmsg_list[i++], rfbFileDownloadRequest, rfbTightVncVendor); -+ SetCapInfo(&cmsg_list[i++], rfbFileUploadRequest, rfbTightVncVendor); -+ SetCapInfo(&cmsg_list[i++], rfbFileUploadData, rfbTightVncVendor); -+ SetCapInfo(&cmsg_list[i++], rfbFileDownloadCancel, rfbTightVncVendor); -+ SetCapInfo(&cmsg_list[i++], rfbFileUploadFailed, rfbTightVncVendor); -+ if (i != N_CMSG_CAPS) { -+ rfbLog("rfbSendInteractionCaps: assertion failed, i != N_CMSG_CAPS\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ */ -+ -+ /* Encoding types. */ -+ i = 0; -+ SetCapInfo(&enc_list[i++], rfbEncodingCopyRect, rfbStandardVendor); -+ SetCapInfo(&enc_list[i++], rfbEncodingRRE, rfbStandardVendor); -+ SetCapInfo(&enc_list[i++], rfbEncodingCoRRE, rfbStandardVendor); -+ SetCapInfo(&enc_list[i++], rfbEncodingHextile, rfbStandardVendor); -+ SetCapInfo(&enc_list[i++], rfbEncodingZlib, rfbTridiaVncVendor); -+ SetCapInfo(&enc_list[i++], rfbEncodingTight, rfbTightVncVendor); -+ SetCapInfo(&enc_list[i++], rfbEncodingCompressLevel0, rfbTightVncVendor); -+ SetCapInfo(&enc_list[i++], rfbEncodingQualityLevel0, rfbTightVncVendor); -+ SetCapInfo(&enc_list[i++], rfbEncodingXCursor, rfbTightVncVendor); -+ SetCapInfo(&enc_list[i++], rfbEncodingRichCursor, rfbTightVncVendor); -+ SetCapInfo(&enc_list[i++], rfbEncodingPointerPos, rfbTightVncVendor); -+ SetCapInfo(&enc_list[i++], rfbEncodingLastRect, rfbTightVncVendor); -+ if (i != N_ENC_CAPS) { -+ rfbLog("rfbSendInteractionCaps: assertion failed, i != N_ENC_CAPS\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ /* Send header and capability lists */ -+ if (WriteExact(cl->sock, (char *)&intr_caps, -+ sz_rfbInteractionCapsMsg) < 0 || -+ WriteExact(cl->sock, (char *)&enc_list[0], -+ sz_rfbCapabilityInfo * N_ENC_CAPS) < 0) { -+ rfbLogPerror("rfbSendInteractionCaps: write"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ /* Dispatch client input to rfbProcessClientNormalMessage(). */ -+ cl->state = RFB_NORMAL; -+} -+ -+ -+/* -+ * rfbProcessClientNormalMessage is called when the client has sent a normal -+ * protocol message. -+ */ -+ -+static void -+rfbProcessClientNormalMessage(rfbClientPtr cl) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ int n; -+ rfbClientToServerMsg msg; -+ char *str; -+ -+ if (pVNC->rfbUserAccept) { -+ /* -+ * We've asked for another level of user authentication -+ * If the user has not validated this connected, don't -+ * process it. -+ */ -+ /* -+ * NOTE: we do it here, so the vncviewer knows it's -+ * connected, but waiting for the first screen update -+ */ -+ if (cl->userAccepted == VNC_USER_UNDEFINED) { -+ usleep(10); -+ return; -+ } -+ if (cl->userAccepted == VNC_USER_DISCONNECT) { -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ } -+ -+ if ((n = ReadExact(cl->sock, (char *)&msg, 1)) <= 0) { -+ if (n != 0) -+ rfbLogPerror("rfbProcessClientNormalMessage: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ switch (msg.type) { -+ -+ case rfbSetPixelFormat: -+ -+ if ((n = ReadExact(cl->sock, ((char *)&msg) + 1, -+ sz_rfbSetPixelFormatMsg - 1)) <= 0) { -+ if (n != 0) -+ rfbLogPerror("rfbProcessClientNormalMessage: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ cl->format.bitsPerPixel = msg.spf.format.bitsPerPixel; -+ cl->format.depth = msg.spf.format.depth; -+ cl->format.bigEndian = (msg.spf.format.bigEndian ? 1 : 0); -+ cl->format.trueColour = (msg.spf.format.trueColour ? 1 : 0); -+ cl->format.redMax = Swap16IfLE(msg.spf.format.redMax); -+ cl->format.greenMax = Swap16IfLE(msg.spf.format.greenMax); -+ cl->format.blueMax = Swap16IfLE(msg.spf.format.blueMax); -+ cl->format.redShift = msg.spf.format.redShift; -+ cl->format.greenShift = msg.spf.format.greenShift; -+ cl->format.blueShift = msg.spf.format.blueShift; -+ -+ cl->readyForSetColourMapEntries = TRUE; -+ -+ rfbSetTranslateFunction(cl); -+ return; -+ -+ -+ case rfbFixColourMapEntries: -+ if ((n = ReadExact(cl->sock, ((char *)&msg) + 1, -+ sz_rfbFixColourMapEntriesMsg - 1)) <= 0) { -+ if (n != 0) -+ rfbLogPerror("rfbProcessClientNormalMessage: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ rfbLog("rfbProcessClientNormalMessage: %s", -+ "FixColourMapEntries unsupported\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ -+ -+ case rfbSetEncodings: -+ { -+ int i; -+ CARD32 enc; -+ -+ if ((n = ReadExact(cl->sock, ((char *)&msg) + 1, -+ sz_rfbSetEncodingsMsg - 1)) <= 0) { -+ if (n != 0) -+ rfbLogPerror("rfbProcessClientNormalMessage: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ msg.se.nEncodings = Swap16IfLE(msg.se.nEncodings); -+ -+ cl->preferredEncoding = -1; -+ cl->useCopyRect = FALSE; -+ cl->enableCursorShapeUpdates = FALSE; -+ cl->enableCursorPosUpdates = FALSE; -+ cl->enableLastRectEncoding = FALSE; -+#ifdef CHROMIUM -+ cl->enableChromiumEncoding = FALSE; -+#endif -+ cl->tightCompressLevel = TIGHT_DEFAULT_COMPRESSION; -+ cl->tightQualityLevel = -1; -+ -+ for (i = 0; i < msg.se.nEncodings; i++) { -+ if ((n = ReadExact(cl->sock, (char *)&enc, 4)) <= 0) { -+ if (n != 0) -+ rfbLogPerror("rfbProcessClientNormalMessage: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ enc = Swap32IfLE(enc); -+ -+ switch (enc) { -+ -+ case rfbEncodingCopyRect: -+ cl->useCopyRect = TRUE; -+ rfbLog("Using copyrect encoding for client %s\n", -+ cl->host); -+ break; -+ case rfbEncodingRaw: -+ if (cl->preferredEncoding == -1) { -+ cl->preferredEncoding = enc; -+ rfbLog("Using raw encoding for client %s\n", -+ cl->host); -+ } -+ break; -+ case rfbEncodingRRE: -+ if (cl->preferredEncoding == -1) { -+ cl->preferredEncoding = enc; -+ rfbLog("Using rre encoding for client %s\n", -+ cl->host); -+ } -+ break; -+ case rfbEncodingCoRRE: -+ if (cl->preferredEncoding == -1) { -+ cl->preferredEncoding = enc; -+ rfbLog("Using CoRRE encoding for client %s\n", -+ cl->host); -+ } -+ break; -+ case rfbEncodingHextile: -+ if (cl->preferredEncoding == -1) { -+ cl->preferredEncoding = enc; -+ rfbLog("Using hextile encoding for client %s\n", -+ cl->host); -+ } -+ break; -+ case rfbEncodingZlib: -+ if (cl->preferredEncoding == -1) { -+ cl->preferredEncoding = enc; -+ rfbLog("Using zlib encoding for client %s\n", -+ cl->host); -+ } -+ break; -+ case rfbEncodingTight: -+ if (cl->preferredEncoding == -1) { -+ cl->preferredEncoding = enc; -+ rfbLog("Using tight encoding for client %s\n", -+ cl->host); -+ } -+ break; -+ case rfbEncodingXCursor: -+ rfbLog("Enabling X-style cursor updates for client %s\n", -+ cl->host); -+ cl->enableCursorShapeUpdates = TRUE; -+ cl->useRichCursorEncoding = FALSE; -+ cl->cursorWasChanged = TRUE; -+ break; -+ case rfbEncodingRichCursor: -+ if (!cl->enableCursorShapeUpdates) { -+ rfbLog("Enabling full-color cursor updates for client " -+ "%s\n", cl->host); -+ cl->enableCursorShapeUpdates = TRUE; -+ cl->useRichCursorEncoding = TRUE; -+ cl->cursorWasChanged = TRUE; -+ } -+ break; -+ case rfbEncodingPointerPos: -+ if (!cl->enableCursorPosUpdates) { -+ rfbLog("Enabling cursor position updates for client %s\n", -+ cl->host); -+ cl->enableCursorPosUpdates = TRUE; -+ cl->cursorWasMoved = TRUE; -+ cl->cursorX = -1; -+ cl->cursorY = -1; -+ } -+ break; -+ case rfbEncodingLastRect: -+ if (!cl->enableLastRectEncoding) { -+ rfbLog("Enabling LastRect protocol extension for client " -+ "%s\n", cl->host); -+ cl->enableLastRectEncoding = TRUE; -+ } -+ break; -+#ifdef CHROMIUM -+ case rfbEncodingChromium: -+ case rfbEncodingChromium2: -+ if (!cl->enableChromiumEncoding) { -+ cl->enableChromiumEncoding = TRUE; -+ /* This tells OpenGL apps/replicate SPUs that new viewer -+ * has attached. -+ */ -+ GenerateVncChromiumConnectedEvent(cl->sock); -+ if (enc == rfbEncodingChromium) { -+ /* Generate exposures for all windows */ -+ WindowPtr pWin = cl->pScreen->root; -+ rfbSetClip(pWin, 1); -+ } -+ else { -+ /* don't generate exposures for Chromium2 because -+ * that confused DMX. -+ */ -+ } -+ } -+ break; -+#endif -+ default: -+ if ( enc >= (CARD32)rfbEncodingCompressLevel0 && -+ enc <= (CARD32)rfbEncodingCompressLevel9 ) { -+ cl->zlibCompressLevel = enc & 0x0F; -+ cl->tightCompressLevel = enc & 0x0F; -+ rfbLog("Using compression level %d for client %s\n", -+ cl->tightCompressLevel, cl->host); -+ } else if ( enc >= (CARD32)rfbEncodingQualityLevel0 && -+ enc <= (CARD32)rfbEncodingQualityLevel9 ) { -+ cl->tightQualityLevel = enc & 0x0F; -+ rfbLog("Using image quality level %d for client %s\n", -+ cl->tightQualityLevel, cl->host); -+ } else { -+ rfbLog("rfbProcessClientNormalMessage: ignoring unknown " -+ "encoding %d\n", (int)enc); -+ } -+ } -+ } -+ -+ if (cl->preferredEncoding == -1) { -+ cl->preferredEncoding = rfbEncodingRaw; -+ rfbLog("No encoding specified - using raw encoding for client %s\n", -+ cl->host); -+ } -+ -+ if (cl->enableCursorPosUpdates && !cl->enableCursorShapeUpdates) { -+ rfbLog("Disabling cursor position updates for client %s\n", -+ cl->host); -+ cl->enableCursorPosUpdates = FALSE; -+ } -+ -+#if XFREE86VNC -+ /* -+ * With XFree86 and the hardware cursor's we need to put up the -+ * cursor again, and if we've detected a cursor shapeless client -+ * we need to disable hardware cursors. -+ */ -+ if (!cl->enableCursorShapeUpdates) -+ pVNC->SWCursor = (Bool *)TRUE; -+ else -+ pVNC->SWCursor = (Bool *)FALSE; -+ -+ { -+ int x, y; -+ miPointerGetPosition(inputInfo.pointer, &x, &y); -+ (*pVNC->spriteFuncs->SetCursor)(inputInfo.pointer, cl->pScreen, pVNC->pCurs, x, y); -+ } -+#endif -+ -+ return; -+ } -+ -+ -+ case rfbFramebufferUpdateRequest: -+ { -+ RegionRec tmpRegion; -+ BoxRec box; -+ -+#ifdef CORBA -+ addCapability(cl, DISPLAY_DEVICE); -+#endif -+ -+ if ((n = ReadExact(cl->sock, ((char *)&msg) + 1, -+ sz_rfbFramebufferUpdateRequestMsg-1)) <= 0) { -+ if (n != 0) -+ rfbLogPerror("rfbProcessClientNormalMessage: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ box.x1 = Swap16IfLE(msg.fur.x); -+ box.y1 = Swap16IfLE(msg.fur.y); -+ box.x2 = box.x1 + Swap16IfLE(msg.fur.w); -+ box.y2 = box.y1 + Swap16IfLE(msg.fur.h); -+ SAFE_REGION_INIT(cl->pScreen,&tmpRegion,&box,0); -+ -+ REGION_UNION(cl->pScreen, &cl->requestedRegion, &cl->requestedRegion, -+ &tmpRegion); -+ -+ if (!cl->readyForSetColourMapEntries) { -+ /* client hasn't sent a SetPixelFormat so is using server's */ -+ cl->readyForSetColourMapEntries = TRUE; -+ if (!cl->format.trueColour) { -+ if (!rfbSetClientColourMap(cl, 0, 0)) { -+ REGION_UNINIT(cl->pScreen,&tmpRegion); -+ return; -+ } -+ } -+ } -+ -+ if (!msg.fur.incremental) { -+ REGION_UNION(cl->pScreen,&cl->modifiedRegion,&cl->modifiedRegion, -+ &tmpRegion); -+ REGION_SUBTRACT(cl->pScreen,&cl->copyRegion,&cl->copyRegion, -+ &tmpRegion); -+ } -+ -+#ifndef DMXVNC -+ /* don't try to send any pixel data - we'll crash */ -+ if (FB_UPDATE_PENDING(cl)) { -+ rfbSendFramebufferUpdate(cl->pScreen, cl); -+ } -+#endif -+ -+ REGION_UNINIT(cl->pScreen,&tmpRegion); -+ return; -+ } -+ -+ case rfbKeyEvent: -+ -+ cl->rfbKeyEventsRcvd++; -+ -+ if ((n = ReadExact(cl->sock, ((char *)&msg) + 1, -+ sz_rfbKeyEventMsg - 1)) <= 0) { -+ if (n != 0) -+ rfbLogPerror("rfbProcessClientNormalMessage: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+#ifdef CORBA -+ addCapability(cl, KEYBOARD_DEVICE); -+ -+ if (!isKeyboardEnabled(cl)) -+ return; -+#endif -+ /*ErrorF("Key event: %d\n", msg.ke.key);*/ -+ if (!pVNC->rfbViewOnly && !cl->viewOnly) { -+ KbdAddEvent(msg.ke.down, (KeySym)Swap32IfLE(msg.ke.key), cl); -+ } -+ return; -+ -+ -+ case rfbPointerEvent: -+ -+ cl->rfbPointerEventsRcvd++; -+ -+ if ((n = ReadExact(cl->sock, ((char *)&msg) + 1, -+ sz_rfbPointerEventMsg - 1)) <= 0) { -+ if (n != 0) -+ rfbLogPerror("rfbProcessClientNormalMessage: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+#ifdef CORBA -+ addCapability(cl, POINTER_DEVICE); -+ -+ if (!isPointerEnabled(cl)) -+ return; -+#endif -+ -+ if (pointerClient && (pointerClient != cl)) -+ return; -+ -+ if (msg.pe.buttonMask == 0) -+ pointerClient = NULL; -+ else -+ pointerClient = cl; -+ -+ if (!pVNC->rfbViewOnly && !cl->viewOnly) { -+ cl->cursorX = (int)Swap16IfLE(msg.pe.x); -+ cl->cursorY = (int)Swap16IfLE(msg.pe.y); -+ PtrAddEvent(msg.pe.buttonMask, cl->cursorX, cl->cursorY, cl); -+ } -+ return; -+ -+ -+ case rfbClientCutText: -+ -+ if ((n = ReadExact(cl->sock, ((char *)&msg) + 1, -+ sz_rfbClientCutTextMsg - 1)) <= 0) { -+ if (n != 0) -+ rfbLogPerror("rfbProcessClientNormalMessage: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ msg.cct.length = Swap32IfLE(msg.cct.length); -+ -+ str = (char *)malloc(msg.cct.length); -+ -+ if ((n = ReadExact(cl->sock, str, msg.cct.length)) <= 0) { -+ if (n != 0) -+ rfbLogPerror("rfbProcessClientNormalMessage: read"); -+ free(str); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ /* NOTE: We do not accept cut text from a view-only client */ -+ if (!cl->viewOnly) -+ rfbSetXCutText(str, msg.cct.length); -+ -+ free(str); -+ return; -+ -+#ifdef CHROMIUM -+ case rfbChromiumStop: -+ if ((n = ReadExact(cl->sock, ((char *)&msg) + 1, -+ sz_rfbChromiumStopMsg - 1)) <= 0) { -+ if (n != 0) -+ rfbLogPerror("rfbProcessClientNormalMessage: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ /* would we use msg.csd.port ??? */ -+ -+ cl->chromium_port = 0; -+ -+ /* tear down window information */ -+ { -+ CRWindowTable *wt, *nextWt = NULL; -+ -+ for (wt = windowTable; wt; wt = nextWt) { -+ nextWt = wt->next; -+ free(wt); -+ } -+ -+ windowTable = NULL; -+ } -+ -+ return; -+ -+ case rfbChromiumExpose: -+ if ((n = ReadExact(cl->sock, ((char *)&msg) + 1, -+ sz_rfbChromiumExposeMsg - 1)) <= 0) { -+ if (n != 0) -+ rfbLogPerror("rfbProcessClientNormalMessage: read"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+ -+ /* find the window and re-expose it */ -+ { -+ CRWindowTable *wt, *nextWt = NULL; -+ -+ for (wt = windowTable; wt; wt = nextWt) { -+ nextWt = wt->next; -+ if (wt->CRwinId == msg.cse.winid) { -+ WindowPtr pWin; -+ dixLookupResourceByType((pointer)&pWin, wt->XwinId, RT_WINDOW, NullClient, DixUnknownAccess); -+ if (pWin) { -+ miSendExposures(pWin, &pWin->clipList, -+ pWin->drawable.x, -+ pWin->drawable.y); -+ FlushAllOutput(); -+ } -+ } -+ } -+ } -+ -+ return; -+#endif -+ -+ default: -+ -+ rfbLog("rfbProcessClientNormalMessage: unknown message type %d\n", -+ msg.type); -+ rfbLog(" ... closing connection\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return; -+ } -+} -+ -+ -+ -+/* -+ * rfbSendFramebufferUpdate - send the currently pending framebuffer update to -+ * the RFB client. -+ */ -+ -+Bool -+rfbSendFramebufferUpdate(ScreenPtr pScreen, rfbClientPtr cl) -+{ -+ VNCSCREENPTR(pScreen); -+ int i; -+ int nUpdateRegionRects; -+ rfbFramebufferUpdateMsg *fu = (rfbFramebufferUpdateMsg *)pVNC->updateBuf; -+ RegionRec updateRegion, updateCopyRegion; -+ int dx, dy; -+ Bool sendCursorShape = FALSE; -+ Bool sendCursorPos = FALSE; -+ -+ /* -+ * If this client understands cursor shape updates, cursor should be -+ * removed from the framebuffer. Otherwise, make sure it's put up. -+ */ -+ -+#if !XFREE86VNC -+ if (cl->enableCursorShapeUpdates) { -+ if (pVNC->cursorIsDrawn) -+ rfbSpriteRemoveCursor(pScreen); -+ if (!pVNC->cursorIsDrawn && cl->cursorWasChanged) -+ sendCursorShape = TRUE; -+ } else { -+ if (!pVNC->cursorIsDrawn) -+ rfbSpriteRestoreCursor(pScreen); -+ } -+#else -+ if (cl->enableCursorShapeUpdates) -+ if (cl->cursorWasChanged) -+ sendCursorShape = TRUE; -+#endif -+ -+ /* -+ * Do we plan to send cursor position update? -+ */ -+ -+ if (cl->enableCursorPosUpdates && cl->cursorWasMoved) -+ sendCursorPos = TRUE; -+ -+ /* -+ * The modifiedRegion may overlap the destination copyRegion. We remove -+ * any overlapping bits from the copyRegion (since they'd only be -+ * overwritten anyway). -+ */ -+ -+ REGION_SUBTRACT(pScreen, &cl->copyRegion, &cl->copyRegion, -+ &cl->modifiedRegion); -+ -+ /* -+ * The client is interested in the region requestedRegion. The region -+ * which should be updated now is the intersection of requestedRegion -+ * and the union of modifiedRegion and copyRegion. If it's empty then -+ * no update is needed. -+ */ -+ -+ REGION_NULL(pScreen,&updateRegion); -+ REGION_UNION(pScreen, &updateRegion, &cl->copyRegion, -+ &cl->modifiedRegion); -+ REGION_INTERSECT(pScreen, &updateRegion, &cl->requestedRegion, -+ &updateRegion); -+ -+ if ( !REGION_NOTEMPTY(pScreen,&updateRegion) && -+ !sendCursorShape && !sendCursorPos ) { -+ REGION_UNINIT(pScreen,&updateRegion); -+ return TRUE; -+ } -+ -+ /* -+ * We assume that the client doesn't have any pixel data outside the -+ * requestedRegion. In other words, both the source and destination of a -+ * copy must lie within requestedRegion. So the region we can send as a -+ * copy is the intersection of the copyRegion with both the requestedRegion -+ * and the requestedRegion translated by the amount of the copy. We set -+ * updateCopyRegion to this. -+ */ -+ -+ REGION_NULL(pScreen,&updateCopyRegion); -+ REGION_INTERSECT(pScreen, &updateCopyRegion, &cl->copyRegion, -+ &cl->requestedRegion); -+ REGION_TRANSLATE(pScreen, &cl->requestedRegion, cl->copyDX, cl->copyDY); -+ REGION_INTERSECT(pScreen, &updateCopyRegion, &updateCopyRegion, -+ &cl->requestedRegion); -+ dx = cl->copyDX; -+ dy = cl->copyDY; -+ -+ /* -+ * Next we remove updateCopyRegion from updateRegion so that updateRegion -+ * is the part of this update which is sent as ordinary pixel data (i.e not -+ * a copy). -+ */ -+ -+ REGION_SUBTRACT(pScreen, &updateRegion, &updateRegion, &updateCopyRegion); -+ -+ /* -+ * Finally we leave modifiedRegion to be the remainder (if any) of parts of -+ * the screen which are modified but outside the requestedRegion. We also -+ * empty both the requestedRegion and the copyRegion - note that we never -+ * carry over a copyRegion for a future update. -+ */ -+ -+ REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, -+ &cl->copyRegion); -+ REGION_SUBTRACT(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, -+ &updateRegion); -+ REGION_SUBTRACT(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, -+ &updateCopyRegion); -+ -+ REGION_EMPTY(pScreen, &cl->requestedRegion); -+ REGION_EMPTY(pScreen, &cl->copyRegion); -+ cl->copyDX = 0; -+ cl->copyDY = 0; -+ -+ /* -+ * Now send the update. -+ */ -+ -+ cl->rfbFramebufferUpdateMessagesSent++; -+ -+ if (cl->preferredEncoding == rfbEncodingCoRRE) { -+ nUpdateRegionRects = 0; -+ -+ for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) { -+ int x = REGION_RECTS(&updateRegion)[i].x1; -+ int y = REGION_RECTS(&updateRegion)[i].y1; -+ int w = REGION_RECTS(&updateRegion)[i].x2 - x; -+ int h = REGION_RECTS(&updateRegion)[i].y2 - y; -+ nUpdateRegionRects += (((w-1) / cl->correMaxWidth + 1) -+ * ((h-1) / cl->correMaxHeight + 1)); -+ } -+ } else if (cl->preferredEncoding == rfbEncodingZlib) { -+ nUpdateRegionRects = 0; -+ -+ for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) { -+ int x = REGION_RECTS(&updateRegion)[i].x1; -+ int y = REGION_RECTS(&updateRegion)[i].y1; -+ int w = REGION_RECTS(&updateRegion)[i].x2 - x; -+ int h = REGION_RECTS(&updateRegion)[i].y2 - y; -+ nUpdateRegionRects += (((h-1) / (ZLIB_MAX_SIZE( w ) / w)) + 1); -+ } -+ } else if (cl->preferredEncoding == rfbEncodingTight) { -+ nUpdateRegionRects = 0; -+ -+ for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) { -+ int x = REGION_RECTS(&updateRegion)[i].x1; -+ int y = REGION_RECTS(&updateRegion)[i].y1; -+ int w = REGION_RECTS(&updateRegion)[i].x2 - x; -+ int h = REGION_RECTS(&updateRegion)[i].y2 - y; -+ int n = rfbNumCodedRectsTight(cl, x, y, w, h); -+ if (n == 0) { -+ nUpdateRegionRects = 0xFFFF; -+ break; -+ } -+ nUpdateRegionRects += n; -+ } -+ } else { -+ nUpdateRegionRects = REGION_NUM_RECTS(&updateRegion); -+ } -+ -+ fu->type = rfbFramebufferUpdate; -+ if (nUpdateRegionRects != 0xFFFF) { -+ fu->nRects = Swap16IfLE(REGION_NUM_RECTS(&updateCopyRegion) + -+ nUpdateRegionRects + -+ !!sendCursorShape + !!sendCursorPos); -+ } else { -+ fu->nRects = 0xFFFF; -+ } -+ pVNC->ublen = sz_rfbFramebufferUpdateMsg; -+ -+ if (sendCursorShape) { -+ cl->cursorWasChanged = FALSE; -+ if (!rfbSendCursorShape(cl, pScreen)) -+ return FALSE; -+ } -+ -+ if (sendCursorPos) { -+ cl->cursorWasMoved = FALSE; -+ if (!rfbSendCursorPos(cl, pScreen)) -+ return FALSE; -+ } -+ -+ if (REGION_NOTEMPTY(pScreen,&updateCopyRegion)) { -+ if (!rfbSendCopyRegion(cl,&updateCopyRegion,dx,dy)) { -+ REGION_UNINIT(pScreen,&updateRegion); -+ REGION_UNINIT(pScreen,&updateCopyRegion); -+ return FALSE; -+ } -+ } -+ -+ REGION_UNINIT(pScreen,&updateCopyRegion); -+ -+ for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) { -+ int x = REGION_RECTS(&updateRegion)[i].x1; -+ int y = REGION_RECTS(&updateRegion)[i].y1; -+ int w = REGION_RECTS(&updateRegion)[i].x2 - x; -+ int h = REGION_RECTS(&updateRegion)[i].y2 - y; -+ -+ cl->rfbRawBytesEquivalent += (sz_rfbFramebufferUpdateRectHeader -+ + w * (cl->format.bitsPerPixel / 8) * h); -+ -+ switch (cl->preferredEncoding) { -+ case rfbEncodingRaw: -+ if (!rfbSendRectEncodingRaw(cl, x, y, w, h)) { -+ REGION_UNINIT(pScreen,&updateRegion); -+ return FALSE; -+ } -+ break; -+ case rfbEncodingRRE: -+ if (!rfbSendRectEncodingRRE(cl, x, y, w, h)) { -+ REGION_UNINIT(pScreen,&updateRegion); -+ return FALSE; -+ } -+ break; -+ case rfbEncodingCoRRE: -+ if (!rfbSendRectEncodingCoRRE(cl, x, y, w, h)) { -+ REGION_UNINIT(pScreen,&updateRegion); -+ return FALSE; -+ } -+ break; -+ case rfbEncodingHextile: -+ if (!rfbSendRectEncodingHextile(cl, x, y, w, h)) { -+ REGION_UNINIT(pScreen,&updateRegion); -+ return FALSE; -+ } -+ break; -+ case rfbEncodingZlib: -+ if (!rfbSendRectEncodingZlib(cl, x, y, w, h)) { -+ REGION_UNINIT(pScreen,&updateRegion); -+ return FALSE; -+ } -+ break; -+ case rfbEncodingTight: -+ if (!rfbSendRectEncodingTight(cl, x, y, w, h)) { -+ REGION_UNINIT(pScreen,&updateRegion); -+ return FALSE; -+ } -+ break; -+ } -+ } -+ -+ REGION_UNINIT(pScreen,&updateRegion); -+ -+ if (nUpdateRegionRects == 0xFFFF && !rfbSendLastRectMarker(cl)) -+ return FALSE; -+ -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ -+ return TRUE; -+} -+ -+ -+ -+/* -+ * Send the copy region as a string of CopyRect encoded rectangles. -+ * The only slightly tricky thing is that we should send the messages in -+ * the correct order so that an earlier CopyRect will not corrupt the source -+ * of a later one. -+ */ -+ -+static Bool -+rfbSendCopyRegion(rfbClientPtr cl, -+ RegionPtr reg, -+ int dx, int dy) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ int nrects, nrectsInBand, x_inc, y_inc, thisRect, firstInNextBand; -+ int x, y, w, h; -+ rfbFramebufferUpdateRectHeader rect; -+ rfbCopyRect cr; -+ -+ nrects = REGION_NUM_RECTS(reg); -+ -+ if (dx <= 0) { -+ x_inc = 1; -+ } else { -+ x_inc = -1; -+ } -+ -+ if (dy <= 0) { -+ thisRect = 0; -+ y_inc = 1; -+ } else { -+ thisRect = nrects - 1; -+ y_inc = -1; -+ } -+ -+ while (nrects > 0) { -+ -+ firstInNextBand = thisRect; -+ nrectsInBand = 0; -+ -+ while ((nrects > 0) && -+ (REGION_RECTS(reg)[firstInNextBand].y1 -+ == REGION_RECTS(reg)[thisRect].y1)) -+ { -+ firstInNextBand += y_inc; -+ nrects--; -+ nrectsInBand++; -+ } -+ -+ if (x_inc != y_inc) { -+ thisRect = firstInNextBand - y_inc; -+ } -+ -+ while (nrectsInBand > 0) { -+ if ((pVNC->ublen + sz_rfbFramebufferUpdateRectHeader -+ + sz_rfbCopyRect) > UPDATE_BUF_SIZE) -+ { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ x = REGION_RECTS(reg)[thisRect].x1; -+ y = REGION_RECTS(reg)[thisRect].y1; -+ w = REGION_RECTS(reg)[thisRect].x2 - x; -+ h = REGION_RECTS(reg)[thisRect].y2 - y; -+ -+ rect.r.x = Swap16IfLE(x); -+ rect.r.y = Swap16IfLE(y); -+ rect.r.w = Swap16IfLE(w); -+ rect.r.h = Swap16IfLE(h); -+ rect.encoding = Swap32IfLE(rfbEncodingCopyRect); -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect, -+ sz_rfbFramebufferUpdateRectHeader); -+ pVNC->ublen += sz_rfbFramebufferUpdateRectHeader; -+ -+ cr.srcX = Swap16IfLE(x - dx); -+ cr.srcY = Swap16IfLE(y - dy); -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&cr, sz_rfbCopyRect); -+ pVNC->ublen += sz_rfbCopyRect; -+ -+ cl->rfbRectanglesSent[rfbEncodingCopyRect]++; -+ cl->rfbBytesSent[rfbEncodingCopyRect] -+ += sz_rfbFramebufferUpdateRectHeader + sz_rfbCopyRect; -+ -+ thisRect += x_inc; -+ nrectsInBand--; -+ } -+ -+ thisRect = firstInNextBand; -+ } -+ -+ return TRUE; -+} -+ -+ -+/* -+ * Send a given rectangle in raw encoding (rfbEncodingRaw). -+ */ -+ -+Bool -+rfbSendRectEncodingRaw(rfbClientPtr cl, int x, int y, int w, int h) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ rfbFramebufferUpdateRectHeader rect; -+ int nlines; -+ int bytesPerLine = w * (cl->format.bitsPerPixel / 8); -+ int newy = y; -+ -+ /* Flush the buffer to guarantee correct alignment for translateFn(). */ -+ if (pVNC->ublen > 0) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ rect.r.x = Swap16IfLE(x); -+ rect.r.y = Swap16IfLE(y); -+ rect.r.w = Swap16IfLE(w); -+ rect.r.h = Swap16IfLE(h); -+ rect.encoding = Swap32IfLE(rfbEncodingRaw); -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader); -+ pVNC->ublen += sz_rfbFramebufferUpdateRectHeader; -+ -+ cl->rfbRectanglesSent[rfbEncodingRaw]++; -+ cl->rfbBytesSent[rfbEncodingRaw] -+ += sz_rfbFramebufferUpdateRectHeader + bytesPerLine * h; -+ -+ nlines = (UPDATE_BUF_SIZE - pVNC->ublen) / bytesPerLine; -+ -+ while (TRUE) { -+ if (nlines > h) -+ nlines = h; -+ -+ (*cl->translateFn)(cl->pScreen, cl->translateLookupTable, &pVNC->rfbServerFormat, -+ &cl->format, &pVNC->updateBuf[pVNC->ublen], -+ pVNC->paddedWidthInBytes, w, nlines, x, newy); -+ -+ pVNC->ublen += nlines * bytesPerLine; -+ h -= nlines; -+ newy += nlines; -+ -+ if (h == 0) /* rect fitted in buffer, do next one */ -+ return TRUE; -+ -+ /* buffer full - flush partial rect and do another nlines */ -+ -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ -+ nlines = (UPDATE_BUF_SIZE - pVNC->ublen) / bytesPerLine; -+ if (nlines == 0) { -+ rfbLog("rfbSendRectEncodingRaw: send buffer too small for %d " -+ "bytes per line\n", bytesPerLine); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return FALSE; -+ } -+ } -+} -+ -+ -+/* -+ * Send an empty rectangle with encoding field set to value of -+ * rfbEncodingLastRect to notify client that this is the last -+ * rectangle in framebuffer update ("LastRect" extension of RFB -+ * protocol). -+ */ -+ -+static Bool -+rfbSendLastRectMarker(rfbClientPtr cl) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ rfbFramebufferUpdateRectHeader rect; -+ -+ if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ rect.encoding = Swap32IfLE(rfbEncodingLastRect); -+ rect.r.x = 0; -+ rect.r.y = 0; -+ rect.r.w = 0; -+ rect.r.h = 0; -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader); -+ pVNC->ublen += sz_rfbFramebufferUpdateRectHeader; -+ -+ cl->rfbLastRectMarkersSent++; -+ cl->rfbLastRectBytesSent += sz_rfbFramebufferUpdateRectHeader; -+ -+ return TRUE; -+} -+ -+ -+/* -+ * Send the contents of pVNC->updateBuf. Returns 1 if successful, -1 if -+ * not (errno should be set). -+ */ -+ -+Bool -+rfbSendUpdateBuf(rfbClientPtr cl) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ -+ /* -+ int i; -+ for (i = 0; i < pVNC->ublen; i++) { -+ rfbLog("%02x ",((unsigned char *)pVNC->updateBuf)[i]); -+ } -+ rfbLog("\n"); -+ */ -+ -+ if (pVNC->ublen > 0 && WriteExact(cl->sock, (char*)pVNC->updateBuf, pVNC->ublen) < 0) { -+ rfbLogPerror("rfbSendUpdateBuf: write"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return FALSE; -+ } -+ -+ pVNC->ublen = 0; -+ return TRUE; -+} -+ -+ -+ -+/* -+ * rfbSendSetColourMapEntries sends a SetColourMapEntries message to the -+ * client, using values from the currently installed colormap. -+ */ -+ -+Bool -+rfbSendSetColourMapEntries(rfbClientPtr cl, int firstColour, -+ int nColours) -+{ -+#if !XFREE86VNC -+ VNCSCREENPTR(cl->pScreen); -+#endif -+ char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2]; -+ rfbSetColourMapEntriesMsg *scme = (rfbSetColourMapEntriesMsg *)buf; -+ CARD16 *rgb = (CARD16 *)(&buf[sz_rfbSetColourMapEntriesMsg]); -+ EntryPtr pent; -+ EntryPtr redEntry, greenEntry, blueEntry; -+ unsigned short redPart, greenPart, bluePart; -+ int i, len; -+ -+ scme->type = rfbSetColourMapEntries; -+ scme->nColours = Swap16IfLE(nColours); -+ -+ len = sz_rfbSetColourMapEntriesMsg; -+ -+ /* PseudoColor */ -+#if XFREE86VNC -+ if (GetInstalledmiColormap(cl->pScreen)->class == PseudoColor) { -+#else -+ if (pVNC->rfbInstalledColormap->class == PseudoColor) { -+#endif -+ scme->firstColour = Swap16IfLE(firstColour); -+#if XFREE86VNC -+ pent = (EntryPtr)&GetInstalledmiColormap(cl->pScreen)->red[firstColour]; -+#else -+ pent = (EntryPtr)&pVNC->rfbInstalledColormap->red[firstColour]; -+#endif -+ for (i = 0; i < nColours; i++) { -+ if (pent->fShared) { -+ rgb[i*3] = Swap16IfLE(pent->co.shco.red->color); -+ rgb[i*3+1] = Swap16IfLE(pent->co.shco.green->color); -+ rgb[i*3+2] = Swap16IfLE(pent->co.shco.blue->color); -+ } else { -+ rgb[i*3] = Swap16IfLE(pent->co.local.red); -+ rgb[i*3+1] = Swap16IfLE(pent->co.local.green); -+ rgb[i*3+2] = Swap16IfLE(pent->co.local.blue); -+ } -+ pent++; -+ } -+ } -+ -+ else { -+ -+ /* Break the DirectColor pixel into its r/g/b components */ -+#if XFREE86VNC -+ redPart = (firstColour & GetInstalledmiColormap(cl->pScreen)->pVisual->redMask) -+ >> GetInstalledmiColormap(cl->pScreen)->pVisual->offsetRed; -+ greenPart = (firstColour & GetInstalledmiColormap(cl->pScreen)->pVisual->greenMask) -+ >> GetInstalledmiColormap(cl->pScreen)->pVisual->offsetGreen; -+ bluePart = (firstColour & GetInstalledmiColormap(cl->pScreen)->pVisual->blueMask) -+ >> GetInstalledmiColormap(cl->pScreen)->pVisual->offsetBlue; -+#else -+ redPart = (firstColour & pVNC->rfbInstalledColormap->pVisual->redMask) -+ >> pVNC->rfbInstalledColormap->pVisual->offsetRed; -+ greenPart = (firstColour & pVNC->rfbInstalledColormap->pVisual->greenMask) -+ >> pVNC->rfbInstalledColormap->pVisual->offsetGreen; -+ bluePart = (firstColour & pVNC->rfbInstalledColormap->pVisual->blueMask) -+ >> pVNC->rfbInstalledColormap->pVisual->offsetBlue; -+#endif -+ -+ /* -+ * The firstColour field is only 16 bits. To support 24-bit pixels we -+ * sneak the red component in the 8-bit padding field which we renamed -+ * to redIndex. Green and blue are in firstColour (MSB, LSB respectively). -+ */ -+ scme->redIndex = Swap16IfLE(redPart); -+ scme->firstColour = Swap16IfLE((greenPart << 8) | bluePart); -+ -+#if XFREE86VNC -+ redEntry = (EntryPtr)&GetInstalledmiColormap(cl->pScreen)->red[redPart]; -+ greenEntry = (EntryPtr)&GetInstalledmiColormap(cl->pScreen)->green[greenPart]; -+ blueEntry = (EntryPtr)&GetInstalledmiColormap(cl->pScreen)->blue[bluePart]; -+#else -+ redEntry = (EntryPtr)&pVNC->rfbInstalledColormap->red[redPart]; -+ greenEntry = (EntryPtr)&pVNC->rfbInstalledColormap->green[greenPart]; -+ blueEntry = (EntryPtr)&pVNC->rfbInstalledColormap->blue[bluePart]; -+#endif -+ for (i = 0; i < nColours; i++) { -+ if (redEntry->fShared) -+ rgb[i*3] = Swap16IfLE(redEntry->co.shco.red->color); -+ else -+ rgb[i*3] = Swap16IfLE(redEntry->co.local.red); -+ -+ if (greenEntry->fShared) -+ rgb[i*3+1] = Swap16IfLE(greenEntry->co.shco.green->color); -+ else -+ rgb[i*3+1] = Swap16IfLE(greenEntry->co.local.green); -+ -+ if (blueEntry->fShared) -+ rgb[i*3+2] = Swap16IfLE(blueEntry->co.shco.blue->color); -+ else -+ rgb[i*3+2] = Swap16IfLE(blueEntry->co.local.blue); -+ -+ redEntry++; -+ greenEntry++; -+ blueEntry++; -+ } -+ } -+ -+ len += nColours * 3 * 2; -+ -+ if (WriteExact(cl->sock, buf, len) < 0) { -+ rfbLogPerror("rfbSendSetColourMapEntries: write"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return FALSE; -+ } -+ return TRUE; -+} -+ -+ -+/* -+ * rfbSendBell sends a Bell message to all the clients. -+ */ -+ -+void -+rfbSendBell(void) -+{ -+ rfbClientPtr cl, nextCl; -+ rfbBellMsg b; -+ -+ for (cl = rfbClientHead; cl; cl = nextCl) { -+ nextCl = cl->next; -+ b.type = rfbBell; -+ if (WriteExact(cl->sock, (char *)&b, sz_rfbBellMsg) < 0) { -+ rfbLogPerror("rfbSendBell: write"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ } -+ } -+} -+ -+#ifdef CHROMIUM -+#ifdef sun -+extern int inet_aton(const char *cp, struct in_addr *inp); -+#endif -+ -+ -+/** -+ * This sends a ChromiumStart message to all VNC viewers running on the -+ * host named by ipaddress. -+ * This is done in response to an OpenGL/Chromium app calling -+ * XVncChromiumStart(). -+ */ -+void -+rfbSendChromiumStart(unsigned int ipaddress, unsigned int crServerPort, -+ unsigned int mothershipPort) -+{ -+ rfbClientPtr cl, nextCl; -+ rfbChromiumStartMsg scd; -+ struct in_addr ip; -+ unsigned int vncipaddress; -+ -+ /*rfbLog("Enter %s\n", __func__);*/ -+ /* loop over vnc viewers/clients */ -+ for (cl = rfbClientHead; cl; cl = nextCl) { -+ nextCl = cl->next; -+ /*rfbLog("%s: cl=%p enableCr=%d\n", __func__, -+ (void*) cl, cl->enableChromiumEncoding); -+ */ -+ if (!cl->enableChromiumEncoding) { -+ /* viewer is not chromium-enhanced */ -+ continue; -+ } -+ inet_aton(cl->host, &ip); -+ memcpy(&vncipaddress, &ip, sizeof(unsigned int)); -+ rfbLog("%s: ipaddr=0x%x vncipaddr=0x%x cl->port=%d\n", -+ __func__, ipaddress, vncipaddress, cl->chromium_port); -+ if (ipaddress == vncipaddress /**&& !cl->chromium_port**/) { -+ cl->chromium_port = crServerPort; -+ cl->chromium_msport = mothershipPort; -+ scd.type = rfbChromiumStart; -+ scd.crServerPort = crServerPort; -+ scd.mothershipPort = mothershipPort; -+ if (WriteExact(cl->sock, (char *)&scd, -+ sz_rfbChromiumStartMsg) < 0) { -+ rfbLogPerror("rfbSendChromiumStart: write"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ } -+ /* We only start one client at a time, so break now! */ -+ break; -+ } -+ } -+ /*rfbLog("Leave %s\n", __func__);*/ -+} -+ -+ -+/** -+ * Begin monitoring the given X windowid. -+ * When we detect size/position/visibility changes we'll send a -+ * rfbChromiumMoveResizeWindow, rfbChromiumClipList, or rfbChromiumWindowShow -+ * message to the VNC viewer, passing the corresponding Chromium window id. -+ */ -+void -+rfbChromiumMonitorWindowID(unsigned int cr_windowid, unsigned long xwindowid) -+{ -+ CRWindowTable *newRec, *wt, *nextWt = NULL; -+ -+ if (xwindowid && !cr_windowid) { -+ /* stop monitoring the X window, remove from list */ -+ CRWindowTable *prev = NULL; -+ for (wt = windowTable; wt; wt = nextWt) { -+ nextWt = wt->next; -+ if (wt->XwinId == xwindowid) { -+ /* remove */ -+ if (prev) -+ prev->next = wt->next; -+ else -+ windowTable = wt->next; -+ free(wt); -+ } -+ else { -+ prev = wt; -+ } -+ } -+ return; -+ } -+ -+ /* See if we're already monitoring this window */ -+ for (wt = windowTable; wt; wt = nextWt) { -+ nextWt = wt->next; -+ /* and if so, update it's window ID */ -+ if (wt->CRwinId == cr_windowid) { -+ wt->XwinId = xwindowid; -+ return; -+ } -+ } -+ -+ /* o.k, new window so create new slot information */ -+ newRec = (CRWindowTable *)malloc(sizeof(CRWindowTable)); -+ if (!newRec) { -+ rfbLog("Out of memory allocating CRWindowTable.\n"); -+ return; -+ } -+ -+ newRec->next = NULL; -+ newRec->CRwinId = cr_windowid; -+ newRec->XwinId = xwindowid; -+ newRec->clipRects = NULL; -+ newRec->numRects = 0; -+ -+ if (!windowTable) { -+ windowTable = newRec; -+ } -+ else { -+ for (wt = windowTable; wt; wt = nextWt) { -+ nextWt = wt->next; -+ if (!wt->next) /* found the next slot */ -+ wt->next = newRec; -+ } -+ } -+} -+ -+ -+void -+rfbSendChromiumMoveResizeWindow(unsigned int winid, int x, int y, unsigned int w, unsigned int h) -+{ -+ rfbClientPtr cl, nextCl; -+ rfbChromiumMoveResizeWindowMsg scm; -+ -+ for (cl = rfbClientHead; cl; cl = nextCl) { -+ nextCl = cl->next; -+ if (!cl->enableChromiumEncoding) -+ continue; -+ if (cl->chromium_port) { -+ scm.type = rfbChromiumMoveResizeWindow; -+ scm.winid = winid; -+ scm.x = x; -+ scm.y = y; -+ scm.w = w; -+ scm.h = h; -+ if (WriteExact(cl->sock, (char *)&scm, -+ sz_rfbChromiumMoveResizeWindowMsg) < 0) { -+ rfbLogPerror("rfbSendChromiumMoveResizeWindow: write\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ continue; -+ } -+ } -+ } -+} -+ -+void -+rfbSendChromiumClipList(unsigned int winid, BoxPtr pClipRects, int numClipRects) -+{ -+ rfbClientPtr cl, nextCl; -+ rfbChromiumClipListMsg sccl; -+ int len = sizeof(BoxRec) * numClipRects; -+ -+ for (cl = rfbClientHead; cl; cl = nextCl) { -+ nextCl = cl->next; -+ if (!cl->enableChromiumEncoding) -+ continue; -+ if (cl->chromium_port) { -+ sccl.type = rfbChromiumClipList; -+ sccl.winid = winid; -+ sccl.length = Swap32IfLE(len); -+ if (WriteExact(cl->sock, (char *)&sccl, -+ sz_rfbChromiumClipListMsg) < 0) { -+ rfbLogPerror("rfbSendChromiumClipList: write\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ continue; -+ } -+ if (WriteExact(cl->sock, (char *)pClipRects, len) < 0) { -+ rfbLogPerror("rfbSendChromiumClipList: write\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ continue; -+ } -+ } -+ } -+} -+ -+void -+rfbSendChromiumWindowShow(unsigned int winid, unsigned int show) -+{ -+ rfbClientPtr cl, nextCl; -+ rfbChromiumWindowShowMsg scws; -+ -+ for (cl = rfbClientHead; cl; cl = nextCl) { -+ nextCl = cl->next; -+ if (!cl->enableChromiumEncoding) -+ continue; -+ if (cl->chromium_port) { -+ scws.type = rfbChromiumWindowShow; -+ scws.winid = winid; -+ scws.show = show; -+ if (WriteExact(cl->sock, (char *)&scws, -+ sz_rfbChromiumWindowShowMsg) < 0) { -+ rfbLogPerror("rfbSendChromiumWindowShow: write\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ continue; -+ } -+ } -+ } -+} -+ -+void -+rfbSendChromiumWindowDestroy(unsigned int winid) -+{ -+ rfbClientPtr cl, nextCl; -+ rfbChromiumWindowDestroyMsg scwd; -+ -+ for (cl = rfbClientHead; cl; cl = nextCl) { -+ nextCl = cl->next; -+ if (!cl->enableChromiumEncoding) -+ continue; -+ if (cl->chromium_port) { -+ scwd.type = rfbChromiumWindowDestroy; -+ scwd.winid = winid; -+ if (WriteExact(cl->sock, (char *)&scwd, -+ sz_rfbChromiumWindowDestroyMsg) < 0) { -+ rfbLogPerror("rfbSendChromiumWindowDestroy: write\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ continue; -+ } -+ } -+ } -+} -+#endif /* CHROMIUM */ -+ -+/* -+ * rfbSendServerCutText sends a ServerCutText message to all the clients. -+ */ -+ -+void -+rfbSendServerCutText(char *str, int len) -+{ -+ rfbClientPtr cl, nextCl = NULL; -+ rfbServerCutTextMsg sct; -+ -+ for (cl = rfbClientHead; cl; cl = nextCl) { -+ if (cl->state != RFB_NORMAL) continue; -+ nextCl = cl->next; -+ sct.type = rfbServerCutText; -+ sct.length = Swap32IfLE(len); -+ if (WriteExact(cl->sock, (char *)&sct, -+ sz_rfbServerCutTextMsg) < 0) { -+ rfbLogPerror("rfbSendServerCutText: write\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ continue; -+ } -+ if (WriteExact(cl->sock, str, len) < 0) { -+ rfbLogPerror("rfbSendServerCutText: write\n"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ } -+ } -+} -+ -+ -+ -+ -+/***************************************************************************** -+ * -+ * UDP can be used for keyboard and pointer events when the underlying -+ * network is highly reliable. This is really here to support ORL's -+ * videotile, whose TCP implementation doesn't like sending lots of small -+ * packets (such as 100s of pen readings per second!). -+ */ -+ -+void -+rfbNewUDPConnection(int sock) -+{ -+ if (write(sock, &ptrAcceleration, 1) < 0) { -+ rfbLogPerror("rfbNewUDPConnection: write"); -+ } -+} -+ -+/* -+ * Because UDP is a message based service, we can't read the first byte and -+ * then the rest of the packet separately like we do with TCP. We will always -+ * get a whole packet delivered in one go, so we ask read() for the maximum -+ * number of bytes we can possibly get. -+ */ -+ -+void -+rfbProcessUDPInput(ScreenPtr pScreen, int sock) -+{ -+ VNCSCREENPTR(pScreen); -+ int n; -+ rfbClientToServerMsg msg; -+ -+ if ((n = read(sock, (char *)&msg, sizeof(msg))) <= 0) { -+ if (n < 0) { -+ rfbLogPerror("rfbProcessUDPInput: read"); -+ } -+ rfbDisconnectUDPSock(pScreen); -+ return; -+ } -+ -+ switch (msg.type) { -+ -+ case rfbKeyEvent: -+ if (n != sz_rfbKeyEventMsg) { -+ rfbLog("rfbProcessUDPInput: key event incorrect length\n"); -+ rfbDisconnectUDPSock(pScreen); -+ return; -+ } -+ if (!pVNC->rfbViewOnly) { -+ KbdAddEvent(msg.ke.down, (KeySym)Swap32IfLE(msg.ke.key), 0); -+ } -+ break; -+ -+ case rfbPointerEvent: -+ if (n != sz_rfbPointerEventMsg) { -+ rfbLog("rfbProcessUDPInput: ptr event incorrect length\n"); -+ rfbDisconnectUDPSock(pScreen); -+ return; -+ } -+ if (!pVNC->rfbViewOnly) { -+ PtrAddEvent(msg.pe.buttonMask, -+ Swap16IfLE(msg.pe.x), Swap16IfLE(msg.pe.y), 0); -+ } -+ break; -+ -+ default: -+ rfbLog("rfbProcessUDPInput: unknown message type %d\n", -+ msg.type); -+ rfbDisconnectUDPSock(pScreen); -+ } -+} -diff -pruN xorg-server-1.12.1.orig/hw/vnc/rre.c xorg-server-1.12.1/hw/vnc/rre.c ---- xorg-server-1.12.1.orig/hw/vnc/rre.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/rre.c 2012-04-18 14:45:21.581820891 -0500 -@@ -0,0 +1,317 @@ -+/* -+ * rre.c -+ * -+ * Routines to implement Rise-and-Run-length Encoding (RRE). This -+ * code is based on krw's original javatel rfbserver. -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#include -+#include "rfb.h" -+ -+/* -+ * rreBeforeBuf contains pixel data in the client's format. -+ * rreAfterBuf contains the RRE encoded version. If the RRE encoded version is -+ * larger than the raw data or if it exceeds rreAfterBufSize then -+ * raw encoding is used instead. -+ */ -+ -+static int rreBeforeBufSize = 0; -+static unsigned char *rreBeforeBuf = NULL; -+ -+static int rreAfterBufSize = 0; -+static unsigned char *rreAfterBuf = NULL; -+static int rreAfterBufLen; -+ -+static int subrectEncode8(CARD8 *data, int w, int h); -+static int subrectEncode16(CARD16 *data, int w, int h); -+static int subrectEncode32(CARD32 *data, int w, int h); -+static CARD32 getBgColour(char *data, int size, int bpp); -+ -+ -+/* -+ * rfbSendRectEncodingRRE - send a given rectangle using RRE encoding. -+ */ -+ -+Bool -+rfbSendRectEncodingRRE(rfbClientPtr cl, -+ int x, int y, int w, int h) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ rfbFramebufferUpdateRectHeader rect; -+ rfbRREHeader hdr; -+ int nSubrects; -+ int i; -+ int maxRawSize = (pVNC->width * pVNC->height -+ * (cl->format.bitsPerPixel / 8)); -+ -+ if (rreBeforeBufSize < maxRawSize) { -+ rreBeforeBufSize = maxRawSize; -+ if (rreBeforeBuf == NULL) -+ rreBeforeBuf = (unsigned char *)malloc(rreBeforeBufSize); -+ else -+ rreBeforeBuf = (unsigned char *)realloc(rreBeforeBuf, rreBeforeBufSize); -+ } -+ -+ if (rreAfterBufSize < maxRawSize) { -+ rreAfterBufSize = maxRawSize; -+ if (rreAfterBuf == NULL) -+ rreAfterBuf = (unsigned char *)malloc(rreAfterBufSize); -+ else -+ rreAfterBuf = (unsigned char *)realloc(rreAfterBuf, rreAfterBufSize); -+ } -+ -+ (*cl->translateFn)(cl->pScreen, cl->translateLookupTable, -+ &pVNC->rfbServerFormat, -+ &cl->format, rreBeforeBuf, -+ pVNC->paddedWidthInBytes, w, h, x, y); -+ -+ switch (cl->format.bitsPerPixel) { -+ case 8: -+ nSubrects = subrectEncode8((CARD8 *)rreBeforeBuf, w, h); -+ break; -+ case 16: -+ nSubrects = subrectEncode16((CARD16 *)rreBeforeBuf, w, h); -+ break; -+ case 32: -+ nSubrects = subrectEncode32((CARD32 *)rreBeforeBuf, w, h); -+ break; -+ default: -+ rfbLog("getBgColour: bpp %d?\n",cl->format.bitsPerPixel); -+ exit(1); -+ } -+ -+ if (nSubrects < 0) { -+ -+ /* RRE encoding was too large, use raw */ -+ -+ return rfbSendRectEncodingRaw(cl, x, y, w, h); -+ } -+ -+ cl->rfbRectanglesSent[rfbEncodingRRE]++; -+ cl->rfbBytesSent[rfbEncodingRRE] += (sz_rfbFramebufferUpdateRectHeader -+ + sz_rfbRREHeader + rreAfterBufLen); -+ -+ if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader -+ > UPDATE_BUF_SIZE) -+ { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ rect.r.x = Swap16IfLE(x); -+ rect.r.y = Swap16IfLE(y); -+ rect.r.w = Swap16IfLE(w); -+ rect.r.h = Swap16IfLE(h); -+ rect.encoding = Swap32IfLE(rfbEncodingRRE); -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect, -+ sz_rfbFramebufferUpdateRectHeader); -+ pVNC->ublen += sz_rfbFramebufferUpdateRectHeader; -+ -+ hdr.nSubrects = Swap32IfLE(nSubrects); -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&hdr, sz_rfbRREHeader); -+ pVNC->ublen += sz_rfbRREHeader; -+ -+ for (i = 0; i < rreAfterBufLen;) { -+ -+ int bytesToCopy = UPDATE_BUF_SIZE - pVNC->ublen; -+ -+ if (i + bytesToCopy > rreAfterBufLen) { -+ bytesToCopy = rreAfterBufLen - i; -+ } -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], &rreAfterBuf[i], bytesToCopy); -+ -+ pVNC->ublen += bytesToCopy; -+ i += bytesToCopy; -+ -+ if (pVNC->ublen == UPDATE_BUF_SIZE) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ } -+ -+ return TRUE; -+} -+ -+ -+ -+/* -+ * subrectEncode() encodes the given multicoloured rectangle as a background -+ * colour overwritten by single-coloured rectangles. It returns the number -+ * of subrectangles in the encoded buffer, or -1 if subrect encoding won't -+ * fit in the buffer. It puts the encoded rectangles in rreAfterBuf. The -+ * single-colour rectangle partition is not optimal, but does find the biggest -+ * horizontal or vertical rectangle top-left anchored to each consecutive -+ * coordinate position. -+ * -+ * The coding scheme is simply [...] where each -+ * is []. -+ */ -+ -+#define DEFINE_SUBRECT_ENCODE(bpp) \ -+static int \ -+ subrectEncode##bpp(CARD##bpp *data, int w, int h) \ -+{ \ -+ CARD##bpp cl; \ -+ rfbRectangle subrect; \ -+ int x,y; \ -+ int i,j; \ -+ int hx=0,hy,vx=0,vy; \ -+ int hyflag; \ -+ CARD##bpp *seg; \ -+ CARD##bpp *line; \ -+ int hw,hh,vw,vh; \ -+ int thex,they,thew,theh; \ -+ int numsubs = 0; \ -+ int newLen; \ -+ CARD##bpp bg = (CARD##bpp)getBgColour((char*)data,w*h,bpp); \ -+ \ -+ *((CARD##bpp*)rreAfterBuf) = bg; \ -+ \ -+ rreAfterBufLen = (bpp/8); \ -+ \ -+ for (y=0; y 0) && (i >= hx)) {hy += 1;} else {hyflag = 0;} \ -+ } \ -+ vy = j-1; \ -+ \ -+ /* We now have two possible subrects: (x,y,hx,hy) and (x,y,vx,vy) \ -+ * We'll choose the bigger of the two. \ -+ */ \ -+ hw = hx-x+1; \ -+ hh = hy-y+1; \ -+ vw = vx-x+1; \ -+ vh = vy-y+1; \ -+ \ -+ thex = x; \ -+ they = y; \ -+ \ -+ if ((hw*hh) > (vw*vh)) { \ -+ thew = hw; \ -+ theh = hh; \ -+ } else { \ -+ thew = vw; \ -+ theh = vh; \ -+ } \ -+ \ -+ subrect.x = Swap16IfLE(thex); \ -+ subrect.y = Swap16IfLE(they); \ -+ subrect.w = Swap16IfLE(thew); \ -+ subrect.h = Swap16IfLE(theh); \ -+ \ -+ newLen = rreAfterBufLen + (bpp/8) + sz_rfbRectangle; \ -+ if ((newLen > (w * h * (bpp/8))) || (newLen > rreAfterBufSize)) \ -+ return -1; \ -+ \ -+ numsubs += 1; \ -+ *((CARD##bpp*)(rreAfterBuf + rreAfterBufLen)) = cl; \ -+ rreAfterBufLen += (bpp/8); \ -+ memcpy(&rreAfterBuf[rreAfterBufLen],&subrect,sz_rfbRectangle); \ -+ rreAfterBufLen += sz_rfbRectangle; \ -+ \ -+ /* \ -+ * Now mark the subrect as done. \ -+ */ \ -+ for (j=they; j < (they+theh); j++) { \ -+ for (i=thex; i < (thex+thew); i++) { \ -+ data[j*w+i] = bg; \ -+ } \ -+ } \ -+ } \ -+ } \ -+ } \ -+ \ -+ return numsubs; \ -+} -+ -+DEFINE_SUBRECT_ENCODE(8) -+DEFINE_SUBRECT_ENCODE(16) -+DEFINE_SUBRECT_ENCODE(32) -+ -+ -+/* -+ * getBgColour() gets the most prevalent colour in a byte array. -+ */ -+static CARD32 -+getBgColour(char *data, int size, int bpp) -+{ -+ -+#define NUMCLRS 256 -+ -+ static int counts[NUMCLRS]; -+ int i,j,k; -+ -+ int maxcount = 0; -+ CARD8 maxclr = 0; -+ -+ if (bpp != 8) { -+ if (bpp == 16) { -+ return ((CARD16 *)data)[0]; -+ } else if (bpp == 32) { -+ return ((CARD32 *)data)[0]; -+ } else { -+ rfbLog("getBgColour: bpp %d?\n",bpp); -+ exit(1); -+ } -+ } -+ -+ for (i=0; i= NUMCLRS) { -+ rfbLog("getBgColour: unusual colour = %d\n", k); -+ exit(1); -+ } -+ counts[k] += 1; -+ if (counts[k] > maxcount) { -+ maxcount = counts[k]; -+ maxclr = ((CARD8 *)data)[j]; -+ } -+ } -+ -+ return maxclr; -+} -diff -pruN xorg-server-1.12.1.orig/hw/vnc/sockets.c xorg-server-1.12.1/hw/vnc/sockets.c ---- xorg-server-1.12.1.orig/hw/vnc/sockets.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/sockets.c 2012-04-18 14:45:21.582820879 -0500 -@@ -0,0 +1,648 @@ -+/* -+ * sockets.c - deal with TCP & UDP sockets. -+ * -+ * This code should be independent of any changes in the RFB protocol. It just -+ * deals with the X server scheduling stuff, calling rfbNewClientConnection and -+ * rfbProcessClientMessage to actually deal with the protocol. If a socket -+ * needs to be closed for any reason then rfbCloseSock should be called, and -+ * this in turn will call rfbClientConnectionGone. To make an active -+ * connection out, call rfbConnect - note that this does _not_ call -+ * rfbNewClientConnection. -+ * -+ * This file is divided into two types of function. Those beginning with -+ * "rfb" are specific to sockets using the RFB protocol. Those without the -+ * "rfb" prefix are more general socket routines (which are used by the http -+ * code). -+ * -+ * Thanks to Karl Hakimian for pointing out that some platforms return EAGAIN -+ * not EWOULDBLOCK. -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "windowstr.h" -+ -+#ifndef USE_LIBWRAP -+#define USE_LIBWRAP 0 -+#endif -+#if USE_LIBWRAP -+#include -+#include -+int allow_severity = LOG_INFO; -+int deny_severity = LOG_WARNING; -+#endif -+ -+#include "rfb.h" -+ -+int rfbMaxClientWait = 20000; /* time (ms) after which we decide client has -+ gone away - needed to stop us hanging */ -+ -+static struct sockaddr_in udpRemoteAddr; -+ -+/* -+ * rfbInitSockets sets up the TCP and UDP sockets to listen for RFB -+ * connections. It does nothing if called again. -+ */ -+ -+Bool -+rfbInitSockets(ScreenPtr pScreen) -+{ -+ VNCSCREENPTR(pScreen); -+ -+ if (inetdSock != -1) { -+ const int one = 1; -+ -+ if (fcntl(inetdSock, F_SETFL, O_NONBLOCK) < 0) { -+ rfbLogPerror("fcntl"); -+ return FALSE; -+ } -+ -+ if (setsockopt(inetdSock, IPPROTO_TCP, TCP_NODELAY, -+ (char *)&one, sizeof(one)) < 0) { -+ rfbLogPerror("setsockopt"); -+ return FALSE; -+ } -+ -+ AddEnabledDevice(inetdSock); -+ FD_ZERO(&pVNC->allFds); -+ FD_SET(inetdSock, &pVNC->allFds); -+ pVNC->maxFd = inetdSock; -+ return TRUE; -+ } -+ -+ if (pVNC->rfbPort == 0) { -+ pVNC->rfbPort = 5900 + atoi(display) + pScreen->myNum; -+ } -+ -+ if ((pVNC->rfbListenSock = ListenOnTCPPort(pScreen, pVNC->rfbPort)) < 0) { -+ rfbLogPerror("ListenOnTCPPort"); -+ pVNC->rfbPort = 0; -+ return FALSE; -+ } -+ -+ rfbLog("Listening for VNC connections on TCP port %d\n", pVNC->rfbPort); -+ -+ AddEnabledDevice(pVNC->rfbListenSock); -+ -+ FD_ZERO(&pVNC->allFds); -+ FD_SET(pVNC->rfbListenSock, &pVNC->allFds); -+ pVNC->maxFd = pVNC->rfbListenSock; -+ -+ if (pVNC->udpPort != 0) { -+ rfbLog("rfbInitSockets: listening for input on UDP port %d\n",pVNC->udpPort); -+ -+ if ((pVNC->udpSock = ListenOnUDPPort(pScreen, pVNC->udpPort)) < 0) { -+ rfbLogPerror("ListenOnUDPPort"); -+ return FALSE; -+ } -+ AddEnabledDevice(pVNC->udpSock); -+ FD_SET(pVNC->udpSock, &pVNC->allFds); -+ pVNC->maxFd = max(pVNC->udpSock,pVNC->maxFd); -+ } -+ -+ return TRUE; -+} -+ -+ -+/* -+ * rfbCheckFds is called from ProcessInputEvents to check for input on the RFB -+ * socket(s). If there is input to process, the appropriate function in the -+ * RFB server code will be called (rfbNewClientConnection, -+ * rfbProcessClientMessage, etc). -+ */ -+ -+void -+rfbCheckFds(ScreenPtr pScreen) -+{ -+ VNCSCREENPTR(pScreen); -+#if XFREE86VNC -+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; -+#endif -+ int nfds; -+ fd_set fds; -+ struct timeval tv; -+ struct sockaddr_in addr; -+ SOCKLEN_T addrlen = sizeof(addr); -+ char buf[6]; -+ const int one = 1; -+ int sock; -+ static Bool inetdInitDone = FALSE; -+ -+ if (!inetdInitDone && inetdSock != -1) { -+ rfbNewClientConnection(pScreen, inetdSock); -+ inetdInitDone = TRUE; -+ } -+ -+ memcpy((char *)&fds, (char *)&pVNC->allFds, sizeof(fd_set)); -+ tv.tv_sec = 0; -+ tv.tv_usec = 0; -+ nfds = select(pVNC->maxFd + 1, &fds, NULL, NULL, &tv); -+ if (nfds == 0) { -+ return; -+ } -+ if (nfds < 0) { -+ if (errno != EINTR) -+ rfbLogPerror("rfbCheckFds: select"); -+ return; -+ } -+ -+ if (pVNC->rfbListenSock != -1 && FD_ISSET(pVNC->rfbListenSock, &fds)) { -+ -+ if ((sock = accept(pVNC->rfbListenSock, -+ (struct sockaddr *)&addr, &addrlen)) < 0) { -+ rfbLogPerror("rfbCheckFds: accept"); -+ return; -+ } -+ -+ if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { -+ rfbLogPerror("rfbCheckFds: fcntl"); -+ close(sock); -+ return; -+ } -+ -+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, -+ (char *)&one, sizeof(one)) < 0) { -+ rfbLogPerror("rfbCheckFds: setsockopt"); -+ close(sock); -+ return; -+ } -+ -+ rfbLog("\n"); -+ -+#if USE_LIBWRAP -+ if (!hosts_ctl("Xvnc", STRING_UNKNOWN, inet_ntoa(addr.sin_addr), -+ STRING_UNKNOWN)) { -+ rfbLog("Rejected connection from client %s\n", -+ inet_ntoa(addr.sin_addr)); -+ close(sock); -+ return; -+ } -+#endif -+ -+ rfbLog("Got VNC connection from client %s\n", inet_ntoa(addr.sin_addr)); -+ -+ AddEnabledDevice(sock); -+ FD_SET(sock, &pVNC->allFds); -+ pVNC->maxFd = max(sock,pVNC->maxFd); -+ -+ rfbNewClientConnection(pScreen, sock); -+ -+ FD_CLR(pVNC->rfbListenSock, &fds); -+ if (--nfds == 0) -+ return; -+ } -+ -+ if ((pVNC->udpSock != -1) && FD_ISSET(pVNC->udpSock, &fds)) { -+ -+ if (recvfrom(pVNC->udpSock, buf, 1, MSG_PEEK, -+ (struct sockaddr *)&addr, &addrlen) < 0) { -+ -+ rfbLogPerror("rfbCheckFds: UDP: recvfrom"); -+ rfbDisconnectUDPSock(pScreen); -+ -+ } else { -+ -+ if (!pVNC->udpSockConnected || -+ (memcmp(&addr, &udpRemoteAddr, addrlen) != 0)) -+ { -+ /* new remote end */ -+ rfbLog("rfbCheckFds: UDP: got connection\n"); -+ -+ memcpy(&udpRemoteAddr, &addr, addrlen); -+ pVNC->udpSockConnected = TRUE; -+ -+ if (connect(pVNC->udpSock, -+ (struct sockaddr *)&addr, addrlen) < 0) { -+ rfbLogPerror("rfbCheckFds: UDP: connect"); -+ rfbDisconnectUDPSock(pScreen); -+ return; -+ } -+ -+ rfbNewUDPConnection(pVNC->udpSock); -+ } -+ -+ rfbProcessUDPInput(pScreen, pVNC->udpSock); -+ } -+ -+ FD_CLR(pVNC->udpSock, &fds); -+ if (--nfds == 0) -+ return; -+ } -+ -+ for (sock = 0; sock <= pVNC->maxFd; sock++) { -+ if (FD_ISSET(sock, &fds) && FD_ISSET(sock, &pVNC->allFds)) { -+#if XFREE86VNC -+ if (!pScrn->vtSema) -+ rfbCloseSock(pScreen, sock); -+ else -+#endif -+ rfbProcessClientMessage(pScreen, sock); -+ } -+ } -+} -+ -+ -+void -+rfbDisconnectUDPSock(ScreenPtr pScreen) -+{ -+ VNCSCREENPTR(pScreen); -+ pVNC->udpSockConnected = FALSE; -+} -+ -+ -+void -+rfbCloseSock(ScreenPtr pScreen, int sock) -+{ -+ VNCSCREENPTR(pScreen); -+ close(sock); -+ RemoveEnabledDevice(sock); -+ FD_CLR(sock, &pVNC->allFds); -+ rfbClientConnectionGone(sock); -+ if (sock == inetdSock) -+ GiveUp(0); -+} -+ -+#if 0 -+/* -+ * rfbWaitForClient can be called to wait for the RFB client to send us a -+ * message. When one is received it is processed by calling -+ * rfbProcessClientMessage(). -+ */ -+ -+void -+rfbWaitForClient(sock) -+ int sock; -+{ -+ int n; -+ fd_set fds; -+ struct timeval tv; -+ -+ FD_ZERO(&fds); -+ FD_SET(sock, &fds); -+ tv.tv_sec = rfbMaxClientWait / 1000; -+ tv.tv_usec = (rfbMaxClientWait % 1000) * 1000; -+ n = select(sock+1, &fds, NULL, NULL, &tv); -+ if (n < 0) { -+ rfbLogPerror("rfbWaitForClient: select"); -+ exit(1); -+ } -+ if (n == 0) { -+ rfbCloseSock(sock); -+ return; -+ } -+ -+ rfbProcessClientMessage(sock); -+} -+#endif -+ -+/* -+ * rfbConnect is called to make a connection out to a given TCP address. -+ */ -+ -+int -+rfbConnect(ScreenPtr pScreen, char *host, int port) -+{ -+ VNCSCREENPTR(pScreen); -+ int sock; -+ int one = 1; -+ -+ rfbLog("\n"); -+ rfbLog("Making connection to client on host %s port %d\n", -+ host,port); -+ -+ if ((sock = ConnectToTcpAddr(host, port)) < 0) { -+ rfbLogPerror("connection failed"); -+ return -1; -+ } -+ -+ if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { -+ rfbLogPerror("fcntl failed"); -+ close(sock); -+ return -1; -+ } -+ -+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, -+ (char *)&one, sizeof(one)) < 0) { -+ rfbLogPerror("setsockopt failed"); -+ close(sock); -+ return -1; -+ } -+ -+ AddEnabledDevice(sock); -+ FD_SET(sock, &pVNC->allFds); -+ pVNC->maxFd = max(sock,pVNC->maxFd); -+ -+ return sock; -+} -+ -+ -+ -+ -+/* -+ * ReadExact reads an exact number of bytes on a TCP socket. Returns 1 if -+ * those bytes have been read, 0 if the other end has closed, or -1 if an error -+ * occurred (errno is set to ETIMEDOUT if it timed out). -+ */ -+ -+int -+ReadExact(int sock, char *buf, int len) -+{ -+ int n; -+ fd_set fds; -+ int tries = 5; -+ struct timeval tv; -+ -+ while (len > 0) { -+ n = read(sock, buf, len); -+ -+ if (n > 0) { -+ -+ buf += n; -+ len -= n; -+ -+ } else if (n == 0) { -+ -+ return 0; -+ -+ } else { -+ if (errno != EWOULDBLOCK && errno != EAGAIN) { -+ return n; -+ } -+ -+ do { -+ FD_ZERO(&fds); -+ FD_SET(sock, &fds); -+ tv.tv_sec = rfbMaxClientWait / 1000; -+ tv.tv_usec = (rfbMaxClientWait % 1000) * 1000; -+ n = select(sock+1, &fds, NULL, NULL, &tv); -+ tries--; -+ -+ /* We really need to retry if we get EINTR, so spin */ -+ /* If after 5 attempts we're still broke, abort.... */ -+ -+ } while ((n < 0 && errno == EINTR) && tries > 0); -+ -+ if (n < 0) { -+ rfbLogPerror("ReadExact: select"); -+ return n; -+ } -+ if (n == 0) { -+ errno = ETIMEDOUT; -+ return -1; -+ } -+ } -+ } -+ return 1; -+} -+ -+ -+ -+/* -+ * WriteExact writes an exact number of bytes on a TCP socket. Returns 1 if -+ * those bytes have been written, or -1 if an error occurred (errno is set to -+ * ETIMEDOUT if it timed out). -+ */ -+ -+int -+WriteExact(int sock, char *buf, int len) -+{ -+ int n; -+ fd_set fds; -+ struct timeval tv; -+#if 0 -+ int totalTimeWaited = 0; -+#endif -+ -+ while (len > 0) { -+ n = write(sock, buf, len); -+ -+ if (n > 0) { -+ -+ buf += n; -+ len -= n; -+ -+ } else if (n == 0) { -+ -+ rfbLog("WriteExact: write returned 0?\n"); -+ return -1; -+ -+ } else { -+ if (errno != EWOULDBLOCK && errno != EAGAIN) { -+ return n; -+ } -+ -+#if 0 -+ /* Retry every 5 seconds until we exceed rfbMaxClientWait. We -+ need to do this because select doesn't necessarily return -+ immediately when the other end has gone away */ -+ -+ FD_ZERO(&fds); -+ FD_SET(sock, &fds); -+ tv.tv_sec = 5; -+ tv.tv_usec = 0; -+#else -+ /* We're in the WakeupHandler now, so don't wait */ -+ -+ FD_ZERO(&fds); -+ FD_SET(sock, &fds); -+ tv.tv_sec = 0; -+ tv.tv_usec = 0; -+#endif -+ n = select(sock+1, NULL, &fds, NULL, &tv); -+#if 0 -+ if (n < 0) { -+ rfbLogPerror("WriteExact: select"); -+ return n; -+ } -+ if (n == 0) { -+ totalTimeWaited += 5000; -+ if (totalTimeWaited >= rfbMaxClientWait) { -+ errno = ETIMEDOUT; -+ return -1; -+ } -+ } else { -+ totalTimeWaited = 0; -+ } -+#endif -+ } -+ } -+ return 1; -+} -+ -+ -+int -+ListenOnTCPPort(ScreenPtr pScreen, int port) -+{ -+ VNCSCREENPTR(pScreen); -+ struct sockaddr_in addr; -+ int sock; -+ int one = 1; -+ -+ memset(&addr, 0, sizeof(addr)); -+ addr.sin_family = AF_INET; -+ addr.sin_port = htons(port); -+ addr.sin_addr.s_addr = pVNC->interface.s_addr; -+ -+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { -+ return -1; -+ } -+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, -+ (char *)&one, sizeof(one)) < 0) { -+ close(sock); -+ return -1; -+ } -+ if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { -+ close(sock); -+ return -1; -+ } -+ if (listen(sock, 5) < 0) { -+ close(sock); -+ return -1; -+ } -+ -+ return sock; -+} -+ -+ -+int -+ConnectToTcpAddr(char *host, int port) -+{ -+ struct hostent *hp; -+ int sock, n; -+ struct sockaddr_in addr; -+ int tries = 5; -+ -+ memset(&addr, 0, sizeof(addr)); -+ addr.sin_family = AF_INET; -+ addr.sin_port = htons(port); -+ -+ if ((addr.sin_addr.s_addr = inet_addr(host)) == -1) -+ { -+ if (!(hp = gethostbyname(host))) { -+ errno = EINVAL; -+ return -1; -+ } -+ addr.sin_addr.s_addr = *(unsigned long *)hp->h_addr; -+ } -+ -+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { -+ return -1; -+ } -+ -+ do { -+ sock = socket(AF_INET, SOCK_STREAM, 0); -+ tries--; -+ -+ /* We really need to retry if we get EINTR, so spin */ -+ /* If after 5 attempts we're still broke, abort.... */ -+ -+ } while ((sock < 0 && errno == EINTR) && tries > 0); -+ -+ if (sock < 0) { -+ return -1; -+ } -+ -+ tries = 5; -+ -+ do { -+ n = connect(sock, (struct sockaddr *)&addr, (sizeof(addr))); -+ tries--; -+ -+ /* We really need to retry if we get EINTR, so spin */ -+ /* If after 5 attempts we're still broke, abort.... */ -+ -+ } while ((n < 0 && errno == EINTR) && tries > 0); -+ -+ if (n < 0) { -+ close(sock); -+ return -1; -+ } -+ -+ return sock; -+} -+ -+ -+int -+ListenOnUDPPort(ScreenPtr pScreen, int port) -+{ -+ VNCSCREENPTR(pScreen); -+ struct sockaddr_in addr; -+ int sock; -+ int one = 1; -+ -+ memset(&addr, 0, sizeof(addr)); -+ addr.sin_family = AF_INET; -+ addr.sin_port = htons(port); -+ addr.sin_addr.s_addr = pVNC->interface.s_addr; -+ -+ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { -+ return -1; -+ } -+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, -+ (char *)&one, sizeof(one)) < 0) { -+ return -1; -+ } -+ if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { -+ return -1; -+ } -+ -+ return sock; -+} -+ -+#if 0 -+/* -+ * rdpInitSockets sets up the TCP for RDP -+ * connections. It does nothing if called again. -+ */ -+ -+Bool -+rdpInitSockets(ScreenPtr pScreen) -+{ -+ VNCSCREENPTR(pScreen); -+ -+ if ((pVNC->rdpListenSock = ListenOnTCPPort(pScreen, pVNC->rdpPort)) < 0) { -+ rfbLogPerror("ListenOnTCPPort"); -+ pVNC->rdpPort = 0; -+ return FALSE; -+ } -+ -+ rfbLog("Listening for RDP connections on TCP port %d\n", pVNC->rdpPort); -+ -+ AddEnabledDevice(pVNC->rdpListenSock); -+ -+ return TRUE; -+} -+#endif -diff -pruN xorg-server-1.12.1.orig/hw/vnc/sprite.c xorg-server-1.12.1/hw/vnc/sprite.c ---- xorg-server-1.12.1.orig/hw/vnc/sprite.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/sprite.c 2012-04-18 14:45:21.583820867 -0500 -@@ -0,0 +1,2088 @@ -+/* -+ * sprite.c -+ * -+ * software sprite routines - based on misprite -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+ -+/* $XConsortium: misprite.c,v 5.47 94/04/17 20:27:53 dpw Exp $ */ -+ -+/* -+ -+Copyright (c) 1989 X Consortium -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+Except as contained in this notice, the name of the X Consortium shall not be -+used in advertising or otherwise to promote the sale, use or other dealings -+in this Software without prior written authorization from the X Consortium. -+*/ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#include "rfb.h" -+# include -+# include -+# include -+# include -+# include "misc.h" -+# include "pixmapstr.h" -+# include "input.h" -+# include "mi.h" -+# include "cursorstr.h" -+# include "scrnintstr.h" -+# include "colormapst.h" -+# include "windowstr.h" -+# include "gcstruct.h" -+# include "mipointer.h" -+# include "spritest.h" -+# include "dixfontstr.h" -+ -+/* -+ * screen wrappers -+ */ -+ -+static Bool rfbSpriteCloseScreen(int i, ScreenPtr pScreen); -+static void rfbSpriteGetImage(DrawablePtr pDrawable, int sx, int sy, -+ int w, int h, unsigned int format, -+ unsigned long planemask, char *pdstLine); -+static void rfbSpriteGetSpans(DrawablePtr pDrawable, int wMax, -+ DDXPointPtr ppt, int *pwidth, int nspans, -+ char *pdstStart); -+static void rfbSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, -+ int width, int height, -+ unsigned int subWIndowMode); -+static Bool rfbSpriteCreateGC(GCPtr pGC); -+static void rfbSpriteInstallColormap(ColormapPtr pMap); -+static void rfbSpriteStoreColors(ColormapPtr pMap, int ndef, -+ xColorItem *pdef); -+ -+static void rfbSpriteCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, -+ RegionPtr pRegion); -+static void rfbSpriteClearToBackground(WindowPtr pWin, int x, int y, -+ int w, int h, -+ Bool generateExposures); -+ -+static void rfbSpriteComputeSaved(ScreenPtr pScreen); -+ -+static DevPrivateKeyRec rfbSpriteScreenKeyRec; -+#define rfbSpriteScreenKey (&rfbSpriteScreenKeyRec) -+ -+ -+#define SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = \ -+ ((rfbSpriteScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, \ -+ rfbSpriteScreenKey))->field) -+ -+#define SCREEN_EPILOGUE(pScreen, field, wrapper)\ -+ ((pScreen)->field = wrapper) -+ -+/* -+ * GC func wrappers -+ */ -+ -+static void rfbSpriteValidateGC(GCPtr pGC, unsigned long stateChanges, -+ DrawablePtr pDrawable); -+static void rfbSpriteCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst); -+static void rfbSpriteDestroyGC(GCPtr pGC); -+static void rfbSpriteChangeGC(GCPtr pGC, unsigned long mask); -+static void rfbSpriteChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects); -+static void rfbSpriteDestroyClip(GCPtr pGC); -+static void rfbSpriteCopyClip(GCPtr pgcDst, GCPtr pgcSrc); -+ -+static GCFuncs rfbSpriteGCFuncs = { -+ rfbSpriteValidateGC, -+ rfbSpriteChangeGC, -+ rfbSpriteCopyGC, -+ rfbSpriteDestroyGC, -+ rfbSpriteChangeClip, -+ rfbSpriteDestroyClip, -+ rfbSpriteCopyClip, -+}; -+ -+static DevPrivateKeyRec rfbSpriteGCKeyRec; -+#define rfbSpriteGCKey (&rfbSpriteGCKeyRec) -+ -+#define GC_FUNC_PROLOGUE(pGC) \ -+ rfbSpriteGCPtr pGCPriv = \ -+ (rfbSpriteGCPtr)dixLookupPrivate(&(pGC)->devPrivates, rfbSpriteGCKey); \ -+ (pGC)->funcs = pGCPriv->wrapFuncs; \ -+ if (pGCPriv->wrapOps) \ -+ (pGC)->ops = pGCPriv->wrapOps; -+ -+#define GC_FUNC_EPILOGUE(pGC) \ -+ pGCPriv->wrapFuncs = (pGC)->funcs; \ -+ (pGC)->funcs = &rfbSpriteGCFuncs; \ -+ if (pGCPriv->wrapOps) \ -+ { \ -+ pGCPriv->wrapOps = (pGC)->ops; \ -+ (pGC)->ops = &rfbSpriteGCOps; \ -+ } -+ -+/* -+ * GC op wrappers -+ */ -+ -+static void rfbSpriteFillSpans(DrawablePtr pDrawable, GCPtr pGC, -+ int nInit, DDXPointPtr pptInit, -+ int *pwidthInit, int fSorted); -+static void rfbSpriteSetSpans(DrawablePtr pDrawable, GCPtr pGC, -+ char *psrc, DDXPointPtr ppt, int *pwidth, -+ int nspans, int fSorted); -+static void rfbSpritePutImage(DrawablePtr pDrawable, GCPtr pGC, -+ int depth, int x, int y, int w, int h, -+ int leftPad, int format, char *pBits); -+static RegionPtr rfbSpriteCopyArea(DrawablePtr pSrc, DrawablePtr pDst, -+ GCPtr pGC, int srcx, int srcy, int w, -+ int h, int dstx, int dsty); -+static RegionPtr rfbSpriteCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, -+ GCPtr pGC, int srcx, int srcy, int w, -+ int h, int dstx, int dsty, -+ unsigned long plane); -+static void rfbSpritePolyPoint(DrawablePtr pDrawable, GCPtr pGC, -+ int mode, int npt, xPoint *pptInit); -+static void rfbSpritePolylines(DrawablePtr pDrawable, GCPtr pGC, -+ int mode, int npt, DDXPointPtr pptInit); -+static void rfbSpritePolySegment(DrawablePtr pDrawable, GCPtr pGC, -+ int nseg, xSegment *pSegs); -+static void rfbSpritePolyRectangle(DrawablePtr pDrawable, GCPtr pGC, -+ int nrects, xRectangle *pRects); -+static void rfbSpritePolyArc(DrawablePtr pDrawable, GCPtr pGC, -+ int narcs, xArc *parcs); -+static void rfbSpriteFillPolygon(DrawablePtr pDrawable, GCPtr pGC, -+ int shape, int mode, int count, -+ DDXPointPtr pPts); -+static void rfbSpritePolyFillRect(DrawablePtr pDrawable, GCPtr pGC, -+ int nrectFill, xRectangle *prectInit); -+static void rfbSpritePolyFillArc(DrawablePtr pDrawable, GCPtr pGC, -+ int narcs, xArc *parcs); -+static int rfbSpritePolyText8(DrawablePtr pDrawable, GCPtr pGC, -+ int x, int y, int count, char *chars); -+static int rfbSpritePolyText16(DrawablePtr pDrawable, GCPtr pGC, -+ int x, int y, int count, -+ unsigned short *chars); -+static void rfbSpriteImageText8(DrawablePtr pDrawable, GCPtr pGC, -+ int x, int y, int count, char *chars); -+static void rfbSpriteImageText16(DrawablePtr pDrawable, GCPtr pGC, -+ int x, int y, int count, -+ unsigned short *chars); -+static void rfbSpriteImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, -+ int x, int y, unsigned int nglyph, -+ CharInfoPtr *ppci, -+ pointer pglyphBase); -+static void rfbSpritePolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, -+ int x, int y, unsigned int nglyph, -+ CharInfoPtr *ppci, -+ pointer pglyphBase); -+static void rfbSpritePushPixels(GCPtr pGC, PixmapPtr pBitMap, -+ DrawablePtr pDst, int w, int h, -+ int x, int y); -+#ifdef NEED_LINEHELPER -+static void rfbSpriteLineHelper(); -+#endif -+ -+static GCOps rfbSpriteGCOps = { -+ rfbSpriteFillSpans, rfbSpriteSetSpans, rfbSpritePutImage, -+ rfbSpriteCopyArea, rfbSpriteCopyPlane, rfbSpritePolyPoint, -+ rfbSpritePolylines, rfbSpritePolySegment, rfbSpritePolyRectangle, -+ rfbSpritePolyArc, rfbSpriteFillPolygon, rfbSpritePolyFillRect, -+ rfbSpritePolyFillArc, rfbSpritePolyText8, rfbSpritePolyText16, -+ rfbSpriteImageText8, rfbSpriteImageText16, rfbSpriteImageGlyphBlt, -+ rfbSpritePolyGlyphBlt, rfbSpritePushPixels -+#ifdef NEED_LINEHELPER -+ , rfbSpriteLineHelper -+#endif -+}; -+ -+/* -+ * testing only -- remove cursor for every draw. Eventually, -+ * each draw operation will perform a bounding box check against -+ * the saved cursor area -+ */ -+ -+#define GC_SETUP_CHEAP(pDrawable) \ -+ rfbSpriteScreenPtr pScreenPriv = (rfbSpriteScreenPtr) \ -+ dixLookupPrivate(&pDrawable->pScreen->devPrivates, \ -+ rfbSpriteScreenKey); -+ -+#define GC_SETUP(pDrawable, pGC) \ -+ GC_SETUP_CHEAP(pDrawable) \ -+ rfbSpriteGCPtr pGCPrivate = \ -+ (rfbSpriteGCPtr)dixLookupPrivate(&(pGC)->devPrivates, rfbSpriteGCKey); \ -+ GCFuncs *oldFuncs = pGC->funcs; -+ -+#define GC_SETUP_AND_CHECK(pDrawable, pGC) \ -+ GC_SETUP(pDrawable, pGC); \ -+ if (GC_CHECK((WindowPtr)pDrawable)) \ -+ rfbSpriteRemoveCursor (pDrawable->pScreen); -+ -+#define GC_CHECK(pWin) \ -+ (pVNC->cursorIsDrawn && \ -+ (pScreenPriv->pCacheWin == pWin ? \ -+ pScreenPriv->isInCacheWin : ( \ -+ (pScreenPriv->pCacheWin = (pWin)) , \ -+ (pScreenPriv->isInCacheWin = \ -+ (pWin)->drawable.x < pScreenPriv->saved.x2 && \ -+ pScreenPriv->saved.x1 < (pWin)->drawable.x + \ -+ (int) (pWin)->drawable.width && \ -+ (pWin)->drawable.y < pScreenPriv->saved.y2 && \ -+ pScreenPriv->saved.y1 < (pWin)->drawable.y + \ -+ (int) (pWin)->drawable.height &&\ -+ RECT_IN_REGION((pWin)->drawable.pScreen, &(pWin)->borderClip, \ -+ &pScreenPriv->saved) != rgnOUT)))) -+ -+#define GC_OP_PROLOGUE(pGC) { \ -+ (pGC)->funcs = pGCPrivate->wrapFuncs; \ -+ (pGC)->ops = pGCPrivate->wrapOps; \ -+ } -+ -+#define GC_OP_EPILOGUE(pGC) { \ -+ pGCPrivate->wrapOps = (pGC)->ops; \ -+ (pGC)->funcs = oldFuncs; \ -+ (pGC)->ops = &rfbSpriteGCOps; \ -+ } -+ -+/* -+ * pointer-sprite method table -+ */ -+ -+static Bool rfbSpriteRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor); -+static Bool rfbSpriteUnrealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor); -+static void rfbSpriteSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y); -+static void rfbSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y); -+static Bool rfbSpriteInitializeCursor (DeviceIntPtr pDev, ScreenPtr pScreen); -+static void rfbSpriteCleanupCursor (DeviceIntPtr pDev, ScreenPtr pScreen); -+ -+miPointerSpriteFuncRec rfbSpritePointerFuncs = { -+ rfbSpriteRealizeCursor, -+ rfbSpriteUnrealizeCursor, -+ rfbSpriteSetCursor, -+ rfbSpriteMoveCursor, -+ rfbSpriteInitializeCursor, -+ rfbSpriteCleanupCursor, -+}; -+ -+/* -+ * other misc functions -+ */ -+ -+static Bool rfbDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor); -+ -+ -+/* -+ * rfbSpriteInitialize -- called from device-dependent screen -+ * initialization proc after all of the function pointers have -+ * been stored in the screen structure. -+ */ -+ -+Bool -+rfbSpriteInitialize (ScreenPtr pScreen, rfbSpriteCursorFuncPtr cursorFuncs, -+ miPointerScreenFuncPtr screenFuncs) -+{ -+ rfbSpriteScreenPtr pPriv; -+ VisualPtr pVisual; -+ -+ if (!dixRegisterPrivateKey(rfbSpriteScreenKey, PRIVATE_SCREEN, 0)) -+ return FALSE; -+ -+ if (!dixRegisterPrivateKey(rfbSpriteGCKey, PRIVATE_GC, sizeof(rfbSpriteGCRec))) -+ return FALSE; -+ -+ pPriv = (rfbSpriteScreenPtr) malloc (sizeof (rfbSpriteScreenRec)); -+ if (!pPriv) -+ return FALSE; -+ if (!miPointerInitialize (pScreen, &rfbSpritePointerFuncs, screenFuncs,TRUE)) -+ { -+ free ((pointer) pPriv); -+ return FALSE; -+ } -+ for (pVisual = pScreen->visuals; -+ pVisual->vid != pScreen->rootVisual; -+ pVisual++) -+ ; -+ pPriv->pVisual = pVisual; -+ pPriv->CloseScreen = pScreen->CloseScreen; -+ pPriv->GetImage = pScreen->GetImage; -+ pPriv->GetSpans = pScreen->GetSpans; -+ pPriv->SourceValidate = pScreen->SourceValidate; -+ pPriv->CreateGC = pScreen->CreateGC; -+ pPriv->InstallColormap = pScreen->InstallColormap; -+ pPriv->StoreColors = pScreen->StoreColors; -+ pPriv->DisplayCursor = pScreen->DisplayCursor; -+ -+ pPriv->CopyWindow = pScreen->CopyWindow; -+ pPriv->ClearToBackground = pScreen->ClearToBackground; -+ -+ pPriv->pCursor = NULL; -+ pPriv->x = 0; -+ pPriv->y = 0; -+ pPriv->shouldBeUp = FALSE; -+ pPriv->pCacheWin = NullWindow; -+ pPriv->isInCacheWin = FALSE; -+ pPriv->checkPixels = TRUE; -+ pPriv->pInstalledMap = NULL; -+ pPriv->pColormap = NULL; -+ pPriv->funcs = cursorFuncs; -+ pPriv->colors[SOURCE_COLOR].red = 0; -+ pPriv->colors[SOURCE_COLOR].green = 0; -+ pPriv->colors[SOURCE_COLOR].blue = 0; -+ pPriv->colors[MASK_COLOR].red = 0; -+ pPriv->colors[MASK_COLOR].green = 0; -+ pPriv->colors[MASK_COLOR].blue = 0; -+ dixSetPrivate(&pScreen->devPrivates, rfbSpriteScreenKey, pPriv); -+ pScreen->CloseScreen = rfbSpriteCloseScreen; -+ pScreen->GetImage = rfbSpriteGetImage; -+ pScreen->GetSpans = rfbSpriteGetSpans; -+ pScreen->SourceValidate = rfbSpriteSourceValidate; -+ pScreen->CreateGC = rfbSpriteCreateGC; -+ pScreen->InstallColormap = rfbSpriteInstallColormap; -+ pScreen->StoreColors = rfbSpriteStoreColors; -+ -+ pScreen->CopyWindow = rfbSpriteCopyWindow; -+ pScreen->ClearToBackground = rfbSpriteClearToBackground; -+ -+ pScreen->DisplayCursor = rfbDisplayCursor; -+ -+ return TRUE; -+} -+ -+/* -+ * Screen wrappers -+ */ -+ -+/* -+ * CloseScreen wrapper -- unwrap everything, free the private data -+ * and call the wrapped function -+ */ -+ -+static Bool -+rfbSpriteCloseScreen (int i, ScreenPtr pScreen) -+{ -+ rfbSpriteScreenPtr pScreenPriv; -+ -+ pScreenPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ -+ pScreen->CloseScreen = pScreenPriv->CloseScreen; -+ pScreen->GetImage = pScreenPriv->GetImage; -+ pScreen->GetSpans = pScreenPriv->GetSpans; -+ pScreen->SourceValidate = pScreenPriv->SourceValidate; -+ pScreen->CreateGC = pScreenPriv->CreateGC; -+ pScreen->InstallColormap = pScreenPriv->InstallColormap; -+ pScreen->StoreColors = pScreenPriv->StoreColors; -+ -+ pScreen->CopyWindow = pScreenPriv->CopyWindow; -+ pScreen->ClearToBackground = pScreenPriv->ClearToBackground; -+ -+ free ((pointer) pScreenPriv); -+ -+ return (*pScreen->CloseScreen) (pScreen); -+} -+ -+static void -+rfbSpriteGetImage (DrawablePtr pDrawable, -+ int sx, int sy, int w, int h, -+ unsigned int format, -+ unsigned long planemask, -+ char *pdstLine -+) -+{ -+ ScreenPtr pScreen = pDrawable->pScreen; -+ rfbSpriteScreenPtr pScreenPriv; -+ VNCSCREENPTR(pScreen); -+ -+ SCREEN_PROLOGUE (pScreen, GetImage); -+ -+ pScreenPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ -+ if (pDrawable->type == DRAWABLE_WINDOW && -+ pVNC->cursorIsDrawn && -+ ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y, sx, sy, w, h)) -+ { -+ rfbSpriteRemoveCursor (pScreen); -+ } -+ -+ (*pScreen->GetImage) (pDrawable, sx, sy, w, h, -+ format, planemask, pdstLine); -+ -+ SCREEN_EPILOGUE (pScreen, GetImage, rfbSpriteGetImage); -+} -+ -+static void -+rfbSpriteGetSpans (DrawablePtr pDrawable, -+ int wMax, -+ DDXPointPtr ppt, -+ int *pwidth, -+ int nspans, -+ char *pdstStart) -+{ -+ ScreenPtr pScreen = pDrawable->pScreen; -+ rfbSpriteScreenPtr pScreenPriv; -+ VNCSCREENPTR(pScreen); -+ -+ SCREEN_PROLOGUE (pScreen, GetSpans); -+ -+ pScreenPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ -+ if (pDrawable->type == DRAWABLE_WINDOW && pVNC->cursorIsDrawn) -+ { -+ register DDXPointPtr pts; -+ register int *widths; -+ register int nPts; -+ register int xorg, -+ yorg; -+ -+ xorg = pDrawable->x; -+ yorg = pDrawable->y; -+ -+ for (pts = ppt, widths = pwidth, nPts = nspans; -+ nPts--; -+ pts++, widths++) -+ { -+ if (SPN_OVERLAP(&pScreenPriv->saved,pts->y+yorg, -+ pts->x+xorg,*widths)) -+ { -+ rfbSpriteRemoveCursor (pScreen); -+ break; -+ } -+ } -+ } -+ -+ (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); -+ -+ SCREEN_EPILOGUE (pScreen, GetSpans, rfbSpriteGetSpans); -+} -+ -+static void -+rfbSpriteSourceValidate (DrawablePtr pDrawable, int x, int y, int width, int height, -+ unsigned int subWindowMode) -+{ -+ ScreenPtr pScreen = pDrawable->pScreen; -+ rfbSpriteScreenPtr pScreenPriv; -+ VNCSCREENPTR(pScreen); -+ -+ SCREEN_PROLOGUE (pScreen, SourceValidate); -+ -+ pScreenPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ -+ if (pDrawable->type == DRAWABLE_WINDOW && pVNC->cursorIsDrawn && -+ ORG_OVERLAP(&pScreenPriv->saved, pDrawable->x, pDrawable->y, -+ x, y, width, height)) -+ { -+ rfbSpriteRemoveCursor ( pScreen); -+ } -+ -+ if (pScreen->SourceValidate) -+ (*pScreen->SourceValidate) (pDrawable, x, y, width, height, subWindowMode); -+ -+ SCREEN_EPILOGUE (pScreen, SourceValidate, rfbSpriteSourceValidate); -+} -+ -+static Bool -+rfbSpriteCreateGC (GCPtr pGC) -+{ -+ ScreenPtr pScreen = pGC->pScreen; -+ Bool ret; -+ rfbSpriteGCPtr pPriv; -+ -+ SCREEN_PROLOGUE (pScreen, CreateGC); -+ -+ pPriv = (rfbSpriteGCPtr)dixLookupPrivate(&(pGC)->devPrivates, rfbSpriteGCKey); -+ -+ ret = (*pScreen->CreateGC) (pGC); -+ -+ pPriv->wrapOps = NULL; -+ pPriv->wrapFuncs = pGC->funcs; -+ pGC->funcs = &rfbSpriteGCFuncs; -+ -+ SCREEN_EPILOGUE (pScreen, CreateGC, rfbSpriteCreateGC); -+ -+ return ret; -+} -+ -+static void -+rfbSpriteInstallColormap (ColormapPtr pMap) -+{ -+ ScreenPtr pScreen = pMap->pScreen; -+ rfbSpriteScreenPtr pPriv; -+ VNCSCREENPTR(pScreen); -+ -+ pPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ -+ SCREEN_PROLOGUE(pScreen, InstallColormap); -+ -+ (*pScreen->InstallColormap) (pMap); -+ -+ SCREEN_EPILOGUE(pScreen, InstallColormap, rfbSpriteInstallColormap); -+ -+ pPriv->pInstalledMap = pMap; -+ if (pPriv->pColormap != pMap) -+ { -+ pPriv->checkPixels = TRUE; -+ if (pVNC->cursorIsDrawn) -+ rfbSpriteRemoveCursor (pScreen); -+ } -+} -+ -+static void -+rfbSpriteStoreColors (ColormapPtr pMap, -+ int ndef, -+ xColorItem *pdef) -+{ -+ ScreenPtr pScreen = pMap->pScreen; -+ rfbSpriteScreenPtr pPriv; -+ int i; -+ int updated; -+ VisualPtr pVisual; -+ VNCSCREENPTR(pScreen); -+ -+ pPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ -+ SCREEN_PROLOGUE(pScreen, StoreColors); -+ -+ (*pScreen->StoreColors) (pMap, ndef, pdef); -+ -+ SCREEN_EPILOGUE(pScreen, StoreColors, rfbSpriteStoreColors); -+ -+ if (pPriv->pColormap == pMap) -+ { -+ updated = 0; -+ pVisual = pMap->pVisual; -+ if (pVisual->class == DirectColor) -+ { -+ /* Direct color - match on any of the subfields */ -+ -+#define MaskMatch(a,b,mask) ((a) & ((pVisual->mask) == (b)) & (pVisual->mask)) -+ -+#define UpdateDAC(plane,dac,mask) {\ -+ if (MaskMatch (pPriv->colors[plane].pixel,pdef[i].pixel,mask)) {\ -+ pPriv->colors[plane].dac = pdef[i].dac; \ -+ updated = 1; \ -+ } \ -+} -+ -+#define CheckDirect(plane) \ -+ UpdateDAC(plane,red,redMask) \ -+ UpdateDAC(plane,green,greenMask) \ -+ UpdateDAC(plane,blue,blueMask) -+ -+ for (i = 0; i < ndef; i++) -+ { -+ CheckDirect (SOURCE_COLOR) -+ CheckDirect (MASK_COLOR) -+ } -+ } -+ else -+ { -+ /* PseudoColor/GrayScale - match on exact pixel */ -+ for (i = 0; i < ndef; i++) -+ { -+ if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel) -+ { -+ pPriv->colors[SOURCE_COLOR] = pdef[i]; -+ if (++updated == 2) -+ break; -+ } -+ if (pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel) -+ { -+ pPriv->colors[MASK_COLOR] = pdef[i]; -+ if (++updated == 2) -+ break; -+ } -+ } -+ } -+ if (updated) -+ { -+ pPriv->checkPixels = TRUE; -+ if (pVNC->cursorIsDrawn) -+ rfbSpriteRemoveCursor (pScreen); -+ } -+ } -+} -+ -+static void -+rfbSpriteFindColors (ScreenPtr pScreen) -+{ -+ rfbSpriteScreenPtr pScreenPriv = (rfbSpriteScreenPtr) -+ dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ CursorPtr pCursor; -+ xColorItem *sourceColor, *maskColor; -+ -+ pCursor = pScreenPriv->pCursor; -+ sourceColor = &pScreenPriv->colors[SOURCE_COLOR]; -+ maskColor = &pScreenPriv->colors[MASK_COLOR]; -+ if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap || -+ !(pCursor->foreRed == sourceColor->red && -+ pCursor->foreGreen == sourceColor->green && -+ pCursor->foreBlue == sourceColor->blue && -+ pCursor->backRed == maskColor->red && -+ pCursor->backGreen == maskColor->green && -+ pCursor->backBlue == maskColor->blue)) -+ { -+ pScreenPriv->pColormap = pScreenPriv->pInstalledMap; -+ sourceColor->red = pCursor->foreRed; -+ sourceColor->green = pCursor->foreGreen; -+ sourceColor->blue = pCursor->foreBlue; -+ FakeAllocColor (pScreenPriv->pColormap, sourceColor); -+ maskColor->red = pCursor->backRed; -+ maskColor->green = pCursor->backGreen; -+ maskColor->blue = pCursor->backBlue; -+ FakeAllocColor (pScreenPriv->pColormap, maskColor); -+ /* "free" the pixels right away, don't let this confuse you */ -+ FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel); -+ FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel); -+ } -+ pScreenPriv->checkPixels = FALSE; -+} -+ -+/* -+ * Window wrappers -+ */ -+ -+static void -+rfbSpriteCopyWindow ( WindowPtr pWin, -+ DDXPointRec ptOldOrg, -+ RegionPtr pRegion) -+{ -+ ScreenPtr pScreen = pWin->drawable.pScreen; -+ rfbSpriteScreenPtr pScreenPriv; -+ BoxRec cursorBox; -+ int dx, dy; -+ VNCSCREENPTR(pScreen); -+ -+ SCREEN_PROLOGUE (pScreen, CopyWindow); -+ -+ pScreenPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ if (pVNC->cursorIsDrawn) -+ { -+ /* -+ * check both the source and the destination areas. The given -+ * region is source relative, so offset the cursor box by -+ * the delta position -+ */ -+ cursorBox = pScreenPriv->saved; -+ dx = pWin->drawable.x - ptOldOrg.x; -+ dy = pWin->drawable.y - ptOldOrg.y; -+ cursorBox.x1 -= dx; -+ cursorBox.x2 -= dx; -+ cursorBox.y1 -= dy; -+ cursorBox.y2 -= dy; -+ if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT || -+ RECT_IN_REGION( pScreen, pRegion, &cursorBox) != rgnOUT) -+ rfbSpriteRemoveCursor (pScreen); -+ } -+ -+ (*pScreen->CopyWindow) (pWin, ptOldOrg, pRegion); -+ -+ SCREEN_EPILOGUE (pScreen, CopyWindow, rfbSpriteCopyWindow); -+} -+ -+static void -+rfbSpriteClearToBackground (WindowPtr pWin, -+ int x, -+ int y, -+ int w, -+ int h, -+ Bool generateExposures) -+{ -+ ScreenPtr pScreen = pWin->drawable.pScreen; -+ rfbSpriteScreenPtr pScreenPriv; -+ int realw, realh; -+ VNCSCREENPTR(pScreen); -+ -+ SCREEN_PROLOGUE (pScreen, ClearToBackground); -+ -+ pScreenPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ if (GC_CHECK(pWin)) -+ { -+ if (!(realw = w)) -+ realw = (int) pWin->drawable.width - x; -+ if (!(realh = h)) -+ realh = (int) pWin->drawable.height - y; -+ if (ORG_OVERLAP(&pScreenPriv->saved, pWin->drawable.x, pWin->drawable.y, -+ x, y, realw, realh)) -+ { -+ rfbSpriteRemoveCursor (pScreen); -+ } -+ } -+ -+ (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures); -+ -+ SCREEN_EPILOGUE (pScreen, ClearToBackground, rfbSpriteClearToBackground); -+} -+ -+/* -+ * GC Func wrappers -+ */ -+ -+static void -+rfbSpriteValidateGC (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) -+{ -+ GC_FUNC_PROLOGUE (pGC); -+ -+ (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable); -+ -+ pGCPriv->wrapOps = NULL; -+ if (pDrawable->type == DRAWABLE_WINDOW && ((WindowPtr) pDrawable)->viewable) -+ { -+ WindowPtr pWin; -+ RegionPtr pRegion; -+ -+ pWin = (WindowPtr) pDrawable; -+ pRegion = &pWin->clipList; -+ if (pGC->subWindowMode == IncludeInferiors) -+ pRegion = &pWin->borderClip; -+ if (REGION_NOTEMPTY(pDrawable->pScreen, pRegion)) -+ pGCPriv->wrapOps = pGC->ops; -+ } -+ -+ GC_FUNC_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpriteChangeGC (GCPtr pGC, unsigned long mask) -+{ -+ GC_FUNC_PROLOGUE (pGC); -+ -+ (*pGC->funcs->ChangeGC) (pGC, mask); -+ -+ GC_FUNC_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpriteCopyGC (GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) -+{ -+ GC_FUNC_PROLOGUE (pGCDst); -+ -+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); -+ -+ GC_FUNC_EPILOGUE (pGCDst); -+} -+ -+static void -+rfbSpriteDestroyGC (GCPtr pGC) -+{ -+ GC_FUNC_PROLOGUE (pGC); -+ -+ (*pGC->funcs->DestroyGC) (pGC); -+ -+ GC_FUNC_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpriteChangeClip (GCPtr pGC, int type, pointer pvalue, int nrects) -+{ -+ GC_FUNC_PROLOGUE (pGC); -+ -+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); -+ -+ GC_FUNC_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpriteCopyClip(GCPtr pgcDst, GCPtr pgcSrc) -+{ -+ GC_FUNC_PROLOGUE (pgcDst); -+ -+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); -+ -+ GC_FUNC_EPILOGUE (pgcDst); -+} -+ -+static void -+rfbSpriteDestroyClip(GCPtr pGC) -+{ -+ GC_FUNC_PROLOGUE (pGC); -+ -+ (* pGC->funcs->DestroyClip)(pGC); -+ -+ GC_FUNC_EPILOGUE (pGC); -+} -+ -+/* -+ * GC Op wrappers -+ */ -+ -+static void -+rfbSpriteFillSpans( -+ DrawablePtr pDrawable, -+ GCPtr pGC, -+ int nInit, /* number of spans to fill */ -+ DDXPointPtr pptInit, /* pointer to list of start points */ -+ int *pwidthInit, /* pointer to list of n widths */ -+ int fSorted) -+{ -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP(pDrawable, pGC); -+ -+ if (GC_CHECK((WindowPtr) pDrawable)) -+ { -+ register DDXPointPtr pts; -+ register int *widths; -+ register int nPts; -+ -+ for (pts = pptInit, widths = pwidthInit, nPts = nInit; -+ nPts--; -+ pts++, widths++) -+ { -+ if (SPN_OVERLAP(&pScreenPriv->saved,pts->y,pts->x,*widths)) -+ { -+ rfbSpriteRemoveCursor (pDrawable->pScreen); -+ break; -+ } -+ } -+ } -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpriteSetSpans(DrawablePtr pDrawable, -+ GCPtr pGC, -+ char *psrc, -+ register DDXPointPtr ppt, -+ int *pwidth, -+ int nspans, -+ int fSorted) -+{ -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP(pDrawable, pGC); -+ -+ if (GC_CHECK((WindowPtr) pDrawable)) -+ { -+ register DDXPointPtr pts; -+ register int *widths; -+ register int nPts; -+ -+ for (pts = ppt, widths = pwidth, nPts = nspans; -+ nPts--; -+ pts++, widths++) -+ { -+ if (SPN_OVERLAP(&pScreenPriv->saved,pts->y,pts->x,*widths)) -+ { -+ rfbSpriteRemoveCursor(pDrawable->pScreen); -+ break; -+ } -+ } -+ } -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpritePutImage(DrawablePtr pDrawable, -+ GCPtr pGC, -+ int depth, -+ int x, -+ int y, -+ int w, -+ int h, -+ int leftPad, -+ int format, -+ char *pBits) -+{ -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP(pDrawable, pGC); -+ -+ if (GC_CHECK((WindowPtr) pDrawable)) -+ { -+ if (ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y, -+ x,y,w,h)) -+ { -+ rfbSpriteRemoveCursor (pDrawable->pScreen); -+ } -+ } -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+static RegionPtr -+rfbSpriteCopyArea (DrawablePtr pSrc, -+ DrawablePtr pDst, -+ GCPtr pGC, -+ int srcx, -+ int srcy, -+ int w, -+ int h, -+ int dstx, -+ int dsty) -+{ -+ RegionPtr rgn; -+ VNCSCREENPTR(pGC->pScreen); -+ -+ GC_SETUP(pDst, pGC); -+ -+ /* check destination/source overlap. */ -+ if (GC_CHECK((WindowPtr) pDst) && -+ (ORG_OVERLAP(&pScreenPriv->saved,pDst->x,pDst->y,dstx,dsty,w,h) || -+ ((pDst == pSrc) && -+ ORG_OVERLAP(&pScreenPriv->saved,pSrc->x,pSrc->y,srcx,srcy,w,h)))) -+ { -+ rfbSpriteRemoveCursor (pDst->pScreen); -+ } -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ rgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h, -+ dstx, dsty); -+ -+ GC_OP_EPILOGUE (pGC); -+ -+ return rgn; -+} -+ -+static RegionPtr -+rfbSpriteCopyPlane (DrawablePtr pSrc, -+ DrawablePtr pDst, -+ register GCPtr pGC, -+ int srcx, -+ int srcy, -+ int w, -+ int h, -+ int dstx, -+ int dsty, -+ unsigned long plane) -+{ -+ RegionPtr rgn; -+ VNCSCREENPTR(pGC->pScreen); -+ -+ GC_SETUP(pDst, pGC); -+ -+ /* -+ * check destination/source for overlap. -+ */ -+ if (GC_CHECK((WindowPtr) pDst) && -+ (ORG_OVERLAP(&pScreenPriv->saved,pDst->x,pDst->y,dstx,dsty,w,h) || -+ ((pDst == pSrc) && -+ ORG_OVERLAP(&pScreenPriv->saved,pSrc->x,pSrc->y,srcx,srcy,w,h)))) -+ { -+ rfbSpriteRemoveCursor (pDst->pScreen); -+ } -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ rgn = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h, -+ dstx, dsty, plane); -+ -+ GC_OP_EPILOGUE (pGC); -+ -+ return rgn; -+} -+ -+static void -+rfbSpritePolyPoint (DrawablePtr pDrawable, -+ GCPtr pGC, -+ int mode, /* Origin or Previous */ -+ int npt, -+ xPoint *pptInit) -+{ -+ xPoint t; -+ int n; -+ BoxRec cursor; -+ register xPoint *pts; -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP (pDrawable, pGC); -+ -+ if (npt && GC_CHECK((WindowPtr) pDrawable)) -+ { -+ cursor.x1 = pScreenPriv->saved.x1 - pDrawable->x; -+ cursor.y1 = pScreenPriv->saved.y1 - pDrawable->y; -+ cursor.x2 = pScreenPriv->saved.x2 - pDrawable->x; -+ cursor.y2 = pScreenPriv->saved.y2 - pDrawable->y; -+ -+ if (mode == CoordModePrevious) -+ { -+ t.x = 0; -+ t.y = 0; -+ for (pts = pptInit, n = npt; n--; pts++) -+ { -+ t.x += pts->x; -+ t.y += pts->y; -+ if (cursor.x1 <= t.x && t.x <= cursor.x2 && -+ cursor.y1 <= t.y && t.y <= cursor.y2) -+ { -+ rfbSpriteRemoveCursor (pDrawable->pScreen); -+ break; -+ } -+ } -+ } -+ else -+ { -+ for (pts = pptInit, n = npt; n--; pts++) -+ { -+ if (cursor.x1 <= pts->x && pts->x <= cursor.x2 && -+ cursor.y1 <= pts->y && pts->y <= cursor.y2) -+ { -+ rfbSpriteRemoveCursor (pDrawable->pScreen); -+ break; -+ } -+ } -+ } -+ } -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pptInit); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpritePolylines (DrawablePtr pDrawable, -+ GCPtr pGC, -+ int mode, -+ int npt, -+ DDXPointPtr pptInit) -+{ -+ BoxPtr cursor; -+ register DDXPointPtr pts; -+ int n; -+ int x, y, x1, y1, x2, y2; -+ int lw; -+ int extra; -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP (pDrawable, pGC); -+ -+ if (npt && GC_CHECK((WindowPtr) pDrawable)) -+ { -+ cursor = &pScreenPriv->saved; -+ lw = pGC->lineWidth; -+ x = pptInit->x + pDrawable->x; -+ y = pptInit->y + pDrawable->y; -+ -+ if (npt == 1) -+ { -+ extra = lw >> 1; -+ if (LINE_OVERLAP(cursor, x, y, x, y, extra)) -+ rfbSpriteRemoveCursor (pDrawable->pScreen); -+ } -+ else -+ { -+ extra = lw >> 1; -+ /* -+ * mitered joins can project quite a way from -+ * the line end; the 11 degree miter limit limits -+ * this extension to 10.43 * lw / 2, rounded up -+ * and converted to int yields 6 * lw -+ */ -+ if (pGC->joinStyle == JoinMiter) -+ extra = 6 * lw; -+ else if (pGC->capStyle == CapProjecting) -+ extra = lw; -+ for (pts = pptInit + 1, n = npt - 1; n--; pts++) -+ { -+ x1 = x; -+ y1 = y; -+ if (mode == CoordModeOrigin) -+ { -+ x2 = pDrawable->x + pts->x; -+ y2 = pDrawable->y + pts->y; -+ } -+ else -+ { -+ x2 = x + pts->x; -+ y2 = y + pts->y; -+ } -+ x = x2; -+ y = y2; -+ LINE_SORT(x1, y1, x2, y2); -+ if (LINE_OVERLAP(cursor, x1, y1, x2, y2, extra)) -+ { -+ rfbSpriteRemoveCursor (pDrawable->pScreen); -+ break; -+ } -+ } -+ } -+ } -+ GC_OP_PROLOGUE (pGC); -+ -+ (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, pptInit); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpritePolySegment(DrawablePtr pDrawable, -+ GCPtr pGC, -+ int nseg, -+ xSegment *pSegs) -+{ -+ int n; -+ register xSegment *segs; -+ BoxPtr cursor; -+ int x1, y1, x2, y2; -+ int extra; -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP(pDrawable, pGC); -+ -+ if (nseg && GC_CHECK((WindowPtr) pDrawable)) -+ { -+ cursor = &pScreenPriv->saved; -+ extra = pGC->lineWidth >> 1; -+ if (pGC->capStyle == CapProjecting) -+ extra = pGC->lineWidth; -+ for (segs = pSegs, n = nseg; n--; segs++) -+ { -+ x1 = segs->x1 + pDrawable->x; -+ y1 = segs->y1 + pDrawable->y; -+ x2 = segs->x2 + pDrawable->x; -+ y2 = segs->y2 + pDrawable->y; -+ LINE_SORT(x1, y1, x2, y2); -+ if (LINE_OVERLAP(cursor, x1, y1, x2, y2, extra)) -+ { -+ rfbSpriteRemoveCursor (pDrawable->pScreen); -+ break; -+ } -+ } -+ } -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ (*pGC->ops->PolySegment) (pDrawable, pGC, nseg, pSegs); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpritePolyRectangle( DrawablePtr pDrawable, -+ GCPtr pGC, -+ int nrects, -+ xRectangle *pRects) -+{ -+ register xRectangle *rects; -+ BoxPtr cursor; -+ int lw; -+ int n; -+ int x1, y1, x2, y2; -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP (pDrawable, pGC); -+ -+ if (GC_CHECK((WindowPtr) pDrawable)) -+ { -+ lw = pGC->lineWidth >> 1; -+ cursor = &pScreenPriv->saved; -+ for (rects = pRects, n = nrects; n--; rects++) -+ { -+ x1 = rects->x + pDrawable->x; -+ y1 = rects->y + pDrawable->y; -+ x2 = x1 + (int)rects->width; -+ y2 = y1 + (int)rects->height; -+ if (LINE_OVERLAP(cursor, x1, y1, x2, y1, lw) || -+ LINE_OVERLAP(cursor, x2, y1, x2, y2, lw) || -+ LINE_OVERLAP(cursor, x1, y2, x2, y2, lw) || -+ LINE_OVERLAP(cursor, x1, y1, x1, y2, lw)) -+ { -+ rfbSpriteRemoveCursor (pDrawable->pScreen); -+ break; -+ } -+ } -+ } -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ (*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, pRects); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpritePolyArc(DrawablePtr pDrawable, -+ register GCPtr pGC, -+ int narcs, -+ xArc *parcs) -+{ -+ BoxPtr cursor; -+ int lw; -+ int n; -+ register xArc *arcs; -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP (pDrawable, pGC); -+ -+ if (GC_CHECK((WindowPtr) pDrawable)) -+ { -+ lw = pGC->lineWidth >> 1; -+ cursor = &pScreenPriv->saved; -+ for (arcs = parcs, n = narcs; n--; arcs++) -+ { -+ if (ORG_OVERLAP (cursor, pDrawable->x, pDrawable->y, -+ arcs->x - lw, arcs->y - lw, -+ (int) arcs->width + pGC->lineWidth, -+ (int) arcs->height + pGC->lineWidth)) -+ { -+ rfbSpriteRemoveCursor (pDrawable->pScreen); -+ break; -+ } -+ } -+ } -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, parcs); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpriteFillPolygon(register DrawablePtr pDrawable, -+ register GCPtr pGC, -+ int shape, -+ int mode, -+ int count, -+ DDXPointPtr pPts) -+{ -+ int x, y, minx, miny, maxx, maxy; -+ register DDXPointPtr pts; -+ int n; -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP (pDrawable, pGC); -+ -+ if (count && GC_CHECK((WindowPtr) pDrawable)) -+ { -+ x = pDrawable->x; -+ y = pDrawable->y; -+ pts = pPts; -+ minx = maxx = pts->x; -+ miny = maxy = pts->y; -+ pts++; -+ n = count - 1; -+ -+ if (mode == CoordModeOrigin) -+ { -+ for (; n--; pts++) -+ { -+ if (pts->x < minx) -+ minx = pts->x; -+ else if (pts->x > maxx) -+ maxx = pts->x; -+ if (pts->y < miny) -+ miny = pts->y; -+ else if (pts->y > maxy) -+ maxy = pts->y; -+ } -+ minx += x; -+ miny += y; -+ maxx += x; -+ maxy += y; -+ } -+ else -+ { -+ x += minx; -+ y += miny; -+ minx = maxx = x; -+ miny = maxy = y; -+ for (; n--; pts++) -+ { -+ x += pts->x; -+ y += pts->y; -+ if (x < minx) -+ minx = x; -+ else if (x > maxx) -+ maxx = x; -+ if (y < miny) -+ miny = y; -+ else if (y > maxy) -+ maxy = y; -+ } -+ } -+ if (BOX_OVERLAP(&pScreenPriv->saved,minx,miny,maxx,maxy)) -+ rfbSpriteRemoveCursor (pDrawable->pScreen); -+ } -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pPts); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpritePolyFillRect(DrawablePtr pDrawable, -+ GCPtr pGC, -+ int nrectFill, /* number of rectangles to fill */ -+ xRectangle *prectInit /* Pointer to first rectangle to fill */ -+ ) -+{ -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP(pDrawable, pGC); -+ -+ if (GC_CHECK((WindowPtr) pDrawable)) -+ { -+ register int nRect; -+ register xRectangle *pRect; -+ register int xorg, yorg; -+ -+ xorg = pDrawable->x; -+ yorg = pDrawable->y; -+ -+ for (nRect = nrectFill, pRect = prectInit; nRect--; pRect++) { -+ if (ORGRECT_OVERLAP(&pScreenPriv->saved,xorg,yorg,pRect)){ -+ rfbSpriteRemoveCursor(pDrawable->pScreen); -+ break; -+ } -+ } -+ } -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrectFill, prectInit); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpritePolyFillArc(DrawablePtr pDrawable, -+ GCPtr pGC, -+ int narcs, -+ xArc *parcs -+ ) -+{ -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP(pDrawable, pGC); -+ -+ if (GC_CHECK((WindowPtr) pDrawable)) -+ { -+ register int n; -+ BoxPtr cursor; -+ register xArc *arcs; -+ -+ cursor = &pScreenPriv->saved; -+ -+ for (arcs = parcs, n = narcs; n--; arcs++) -+ { -+ if (ORG_OVERLAP(cursor, pDrawable->x, pDrawable->y, -+ arcs->x, arcs->y, -+ (int) arcs->width, (int) arcs->height)) -+ { -+ rfbSpriteRemoveCursor (pDrawable->pScreen); -+ break; -+ } -+ } -+ } -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ (*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, parcs); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+/* -+ * general Poly/Image text function. Extract glyph information, -+ * compute bounding box and remove cursor if it is overlapped. -+ */ -+ -+static Bool -+rfbSpriteTextOverlap (DrawablePtr pDraw, FontPtr font, int x, int y, unsigned int n, CharInfoPtr *charinfo, Bool imageblt, unsigned int w, BoxPtr cursorBox) -+{ -+ ExtentInfoRec extents; -+ -+ x += pDraw->x; -+ y += pDraw->y; -+ -+ if (FONTMINBOUNDS(font,characterWidth) >= 0) -+ { -+ /* compute an approximate (but covering) bounding box */ -+ if (!imageblt || (charinfo[0]->metrics.leftSideBearing < 0)) -+ extents.overallLeft = charinfo[0]->metrics.leftSideBearing; -+ else -+ extents.overallLeft = 0; -+ if (w) -+ extents.overallRight = w - charinfo[n-1]->metrics.characterWidth; -+ else -+ extents.overallRight = FONTMAXBOUNDS(font,characterWidth) -+ * (n - 1); -+ if (imageblt && (charinfo[n-1]->metrics.characterWidth > -+ charinfo[n-1]->metrics.rightSideBearing)) -+ extents.overallRight += charinfo[n-1]->metrics.characterWidth; -+ else -+ extents.overallRight += charinfo[n-1]->metrics.rightSideBearing; -+ if (imageblt && FONTASCENT(font) > FONTMAXBOUNDS(font,ascent)) -+ extents.overallAscent = FONTASCENT(font); -+ else -+ extents.overallAscent = FONTMAXBOUNDS(font, ascent); -+ if (imageblt && FONTDESCENT(font) > FONTMAXBOUNDS(font,descent)) -+ extents.overallDescent = FONTDESCENT(font); -+ else -+ extents.overallDescent = FONTMAXBOUNDS(font,descent); -+ if (!BOX_OVERLAP(cursorBox, -+ x + extents.overallLeft, -+ y - extents.overallAscent, -+ x + extents.overallRight, -+ y + extents.overallDescent)) -+ return FALSE; -+ else if (imageblt && w) -+ return TRUE; -+ /* if it does overlap, fall through and compute exactly, because -+ * taking down the cursor is expensive enough to make this worth it -+ */ -+ } -+ QueryGlyphExtents(font, charinfo, n, &extents); -+ if (imageblt) -+ { -+ if (extents.overallWidth > extents.overallRight) -+ extents.overallRight = extents.overallWidth; -+ if (extents.overallWidth < extents.overallLeft) -+ extents.overallLeft = extents.overallWidth; -+ if (extents.overallLeft > 0) -+ extents.overallLeft = 0; -+ if (extents.fontAscent > extents.overallAscent) -+ extents.overallAscent = extents.fontAscent; -+ if (extents.fontDescent > extents.overallDescent) -+ extents.overallDescent = extents.fontDescent; -+ } -+ return (BOX_OVERLAP(cursorBox, -+ x + extents.overallLeft, -+ y - extents.overallAscent, -+ x + extents.overallRight, -+ y + extents.overallDescent)); -+} -+ -+/* -+ * values for textType: -+ */ -+#define TT_POLY8 0 -+#define TT_IMAGE8 1 -+#define TT_POLY16 2 -+#define TT_IMAGE16 3 -+ -+static int -+rfbSpriteText (DrawablePtr pDraw, GCPtr pGC, int x, int y, unsigned long count, char *chars, FontEncoding fontEncoding, Bool textType, BoxPtr cursorBox) -+{ -+ CharInfoPtr *charinfo; -+ register CharInfoPtr *info; -+ unsigned long i; -+ unsigned int n; -+ int w; -+ -+ Bool imageblt; -+ -+ imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16); -+ -+ charinfo = (CharInfoPtr *) malloc(count * sizeof(CharInfoPtr)); -+ if (!charinfo) -+ return x; -+ -+ GetGlyphs(pGC->font, count, (unsigned char *)chars, -+ fontEncoding, &i, charinfo); -+ n = (unsigned int)i; -+ w = 0; -+ if (!imageblt) -+ for (info = charinfo; i--; info++) -+ w += (*info)->metrics.characterWidth; -+ -+ if (n != 0) { -+ if (rfbSpriteTextOverlap(pDraw, pGC->font, x, y, n, charinfo, imageblt, w, cursorBox)) -+ rfbSpriteRemoveCursor(pDraw->pScreen); -+ -+#ifdef AVOID_GLYPHBLT -+ /* -+ * On displays like Apollos, which do not optimize the GlyphBlt functions because they -+ * convert fonts to their internal form in RealizeFont and optimize text directly, we -+ * want to invoke the text functions here, not the GlyphBlt functions. -+ */ -+ { -+ void (*drawFunc)(DrawablePtr,GCPtr,int,int,int,unsigned short *) = NULL; -+ switch (textType) -+ { -+ case TT_POLY8: -+ drawFunc = (void (*)())pGC->ops->PolyText8; -+ break; -+ case TT_IMAGE8: -+ drawFunc = pGC->ops->ImageText8; -+ break; -+ case TT_POLY16: -+ drawFunc = (void (*)())pGC->ops->PolyText16; -+ break; -+ case TT_IMAGE16: -+ drawFunc = pGC->ops->ImageText16; -+ break; -+ } -+ (*drawFunc) (pDraw, pGC, x, y, (int) count, chars); -+ } -+#else /* don't AVOID_GLYPHBLT */ -+ /* -+ * On the other hand, if the device does use GlyphBlt ultimately to do text, we -+ * don't want to slow it down by invoking the text functions and having them call -+ * GetGlyphs all over again, so we go directly to the GlyphBlt functions here. -+ */ -+ { -+ void (*drawFunc)(DrawablePtr,GCPtr,int,int,unsigned int, CharInfoPtr*, pointer); -+ drawFunc = imageblt ? pGC->ops->ImageGlyphBlt : pGC->ops->PolyGlyphBlt; -+ (*drawFunc) (pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font)); -+ } -+#endif /* AVOID_GLYPHBLT */ -+ } -+ free(charinfo); -+ return x + w; -+} -+ -+static int -+rfbSpritePolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars) -+{ -+ int ret; -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP (pDrawable, pGC); -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ if (GC_CHECK((WindowPtr) pDrawable)) -+ ret = rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count, chars, -+ Linear8Bit, TT_POLY8, &pScreenPriv->saved); -+ else -+ ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars); -+ -+ GC_OP_EPILOGUE (pGC); -+ return ret; -+} -+ -+static int -+rfbSpritePolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars) -+{ -+ int ret; -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP(pDrawable, pGC); -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ if (GC_CHECK((WindowPtr) pDrawable)) -+ ret = rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count, -+ (char *)chars, -+ FONTLASTROW(pGC->font) == 0 ? -+ Linear16Bit : TwoD16Bit, TT_POLY16, &pScreenPriv->saved); -+ else -+ ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars); -+ -+ GC_OP_EPILOGUE (pGC); -+ return ret; -+} -+ -+static void -+rfbSpriteImageText8(DrawablePtr pDrawable, -+ GCPtr pGC, -+ int x, -+ int y, -+ int count, -+ char *chars) -+{ -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP(pDrawable, pGC); -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ if (GC_CHECK((WindowPtr) pDrawable)) -+ (void) rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count, -+ chars, Linear8Bit, TT_IMAGE8, &pScreenPriv->saved); -+ else -+ (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpriteImageText16(DrawablePtr pDrawable, -+ GCPtr pGC, -+ int x, -+ int y, -+ int count, -+ unsigned short *chars) -+{ -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP(pDrawable, pGC); -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ if (GC_CHECK((WindowPtr) pDrawable)) -+ (void) rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count, -+ (char *)chars, -+ FONTLASTROW(pGC->font) == 0 ? -+ Linear16Bit : TwoD16Bit, TT_IMAGE16, &pScreenPriv->saved); -+ else -+ (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpriteImageGlyphBlt(DrawablePtr pDrawable, -+ GCPtr pGC, -+ int x, -+ int y, -+ unsigned int nglyph, -+ CharInfoPtr *ppci, /* array of character info */ -+ pointer pglyphBase) /* start of array of glyphs */ -+{ -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP(pDrawable, pGC); -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ if (GC_CHECK((WindowPtr) pDrawable) && -+ rfbSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, TRUE, 0, &pScreenPriv->saved)) -+ { -+ rfbSpriteRemoveCursor(pDrawable->pScreen); -+ } -+ (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpritePolyGlyphBlt(DrawablePtr pDrawable, -+ GCPtr pGC, -+ int x, -+ int y, -+ unsigned int nglyph, -+ CharInfoPtr *ppci, /* array of character info */ -+ pointer pglyphBase) /* start of array of glyphs */ -+{ -+ VNCSCREENPTR(pDrawable->pScreen); -+ -+ GC_SETUP (pDrawable, pGC); -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ if (GC_CHECK((WindowPtr) pDrawable) && -+ rfbSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, FALSE, 0, &pScreenPriv->saved)) -+ { -+ rfbSpriteRemoveCursor(pDrawable->pScreen); -+ } -+ (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+static void -+rfbSpritePushPixels(GCPtr pGC, -+ PixmapPtr pBitMap, -+ DrawablePtr pDrawable, -+ int w, -+ int h, -+ int x, -+ int y) -+{ -+ VNCSCREENPTR(pDrawable->pScreen); -+ GC_SETUP(pDrawable, pGC); -+ -+ if (GC_CHECK((WindowPtr) pDrawable) && -+ ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y,x,y,w,h)) -+ { -+ rfbSpriteRemoveCursor (pDrawable->pScreen); -+ } -+ -+ GC_OP_PROLOGUE (pGC); -+ -+ (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y); -+ -+ GC_OP_EPILOGUE (pGC); -+} -+ -+#ifdef NEED_LINEHELPER -+/* -+ * I don't expect this routine will ever be called, as the GC -+ * will have been unwrapped for the line drawing -+ */ -+ -+static void -+rfbSpriteLineHelper() -+{ -+ FatalError("rfbSpriteLineHelper called\n"); -+} -+#endif -+ -+/* -+ * miPointer interface routines -+ */ -+ -+#define SPRITE_PAD 8 -+ -+static Bool -+rfbSpriteRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) -+{ -+ rfbSpriteScreenPtr pScreenPriv; -+ -+ pScreenPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ if (pCursor == pScreenPriv->pCursor) -+ pScreenPriv->checkPixels = TRUE; -+ return (*pScreenPriv->funcs->RealizeCursor) (pScreen, pCursor); -+} -+ -+static Bool -+rfbSpriteUnrealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) -+{ -+ rfbSpriteScreenPtr pScreenPriv; -+ -+ pScreenPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ return (*pScreenPriv->funcs->UnrealizeCursor) (pScreen, pCursor); -+} -+ -+static void -+rfbSpriteSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y) -+{ -+ rfbSpriteScreenPtr pScreenPriv; -+ rfbClientPtr cl, nextCl; -+ VNCSCREENPTR(pScreen); -+ -+ pScreenPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ if (!pCursor) -+ { -+ pScreenPriv->shouldBeUp = FALSE; -+ if (pVNC->cursorIsDrawn) -+ rfbSpriteRemoveCursor (pScreen); -+ pScreenPriv->pCursor = 0; -+ return; -+ } -+ pScreenPriv->shouldBeUp = TRUE; -+ if (pScreenPriv->x == x && -+ pScreenPriv->y == y && -+ pScreenPriv->pCursor == pCursor && -+ !pScreenPriv->checkPixels) -+ { -+ return; -+ } -+ pScreenPriv->x = x; -+ pScreenPriv->y = y; -+ pScreenPriv->pCacheWin = NullWindow; -+ if (pScreenPriv->checkPixels || pScreenPriv->pCursor != pCursor) -+ { -+ pScreenPriv->pCursor = pCursor; -+ rfbSpriteFindColors (pScreen); -+ } -+ if (pVNC->cursorIsDrawn) { -+ int sx, sy; -+ /* -+ * check to see if the old saved region -+ * encloses the new sprite, in which case we use -+ * the flicker-free MoveCursor primitive. -+ */ -+ sx = pScreenPriv->x - (int)pCursor->bits->xhot; -+ sy = pScreenPriv->y - (int)pCursor->bits->yhot; -+ if (sx + (int) pCursor->bits->width >= pScreenPriv->saved.x1 && -+ sx < pScreenPriv->saved.x2 && -+ sy + (int) pCursor->bits->height >= pScreenPriv->saved.y1 && -+ sy < pScreenPriv->saved.y2 && -+ (int) pCursor->bits->width + (2 * SPRITE_PAD) == -+ pScreenPriv->saved.x2 - pScreenPriv->saved.x1 && -+ (int) pCursor->bits->height + (2 * SPRITE_PAD) == -+ pScreenPriv->saved.y2 - pScreenPriv->saved.y1 -+ ) -+ { -+ pVNC->cursorIsDrawn = FALSE; -+ if (!(sx >= pScreenPriv->saved.x1 && -+ sx + (int)pCursor->bits->width < pScreenPriv->saved.x2 && -+ sy >= pScreenPriv->saved.y1 && -+ sy + (int)pCursor->bits->height < pScreenPriv->saved.y2)) -+ { -+ int oldx1, oldy1, dx, dy; -+ -+ oldx1 = pScreenPriv->saved.x1; -+ oldy1 = pScreenPriv->saved.y1; -+ dx = oldx1 - (sx - SPRITE_PAD); -+ dy = oldy1 - (sy - SPRITE_PAD); -+ pScreenPriv->saved.x1 -= dx; -+ pScreenPriv->saved.y1 -= dy; -+ pScreenPriv->saved.x2 -= dx; -+ pScreenPriv->saved.y2 -= dy; -+ (void) (*pScreenPriv->funcs->ChangeSave) (pScreen, -+ pScreenPriv->saved.x1, -+ pScreenPriv->saved.y1, -+ pScreenPriv->saved.x2 - pScreenPriv->saved.x1, -+ pScreenPriv->saved.y2 - pScreenPriv->saved.y1, -+ dx, dy); -+ } -+ (void) (*pScreenPriv->funcs->MoveCursor) (pScreen, pCursor, -+ pScreenPriv->saved.x1, -+ pScreenPriv->saved.y1, -+ pScreenPriv->saved.x2 - pScreenPriv->saved.x1, -+ pScreenPriv->saved.y2 - pScreenPriv->saved.y1, -+ sx - pScreenPriv->saved.x1, -+ sy - pScreenPriv->saved.y1, -+ pScreenPriv->colors[SOURCE_COLOR].pixel, -+ pScreenPriv->colors[MASK_COLOR].pixel); -+ pVNC->cursorIsDrawn = TRUE; -+ } -+ else -+ { -+ rfbSpriteRemoveCursor (pScreen); -+ } -+ } -+#if 0 -+ if (!pVNC->cursorIsDrawn && pScreenPriv->pCursor) -+ rfbSpriteRestoreCursor (pScreen); -+#endif -+ if (pVNC->cursorIsDrawn) -+ rfbSpriteRemoveCursor (pScreen); -+ -+ for (cl = rfbClientHead; cl; cl = nextCl) { -+ nextCl = cl->next; -+ if (cl->enableCursorPosUpdates) { -+ if (x == cl->cursorX && y == cl->cursorY) { -+ cl->cursorWasMoved = FALSE; -+ continue; -+ } -+ cl->cursorWasMoved = TRUE; -+ } -+ if (REGION_NOTEMPTY(pScreen,&cl->requestedRegion)) { -+ /* cursorIsDrawn is guaranteed to be FALSE here, so we definitely -+ want to send a screen update to the client, even if that's only -+ putting up the cursor */ -+ rfbSendFramebufferUpdate(pScreen, cl); -+ } -+ } -+} -+ -+ -+static Bool -+rfbSpriteInitializeCursor (DeviceIntPtr pDev, ScreenPtr pScreen) -+{ -+ return TRUE; -+} -+ -+static void -+rfbSpriteCleanupCursor (DeviceIntPtr pDev, ScreenPtr pScreen) -+{ -+} -+ -+static void -+rfbSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) -+{ -+ rfbSpriteScreenPtr pScreenPriv; -+ -+ pScreenPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ rfbSpriteSetCursor (pDev, pScreen, pScreenPriv->pCursor, x, y); -+} -+ -+/* -+ * undraw/draw cursor -+ */ -+ -+void -+rfbSpriteRemoveCursor (ScreenPtr pScreen) -+{ -+ rfbSpriteScreenPtr pScreenPriv; -+ VNCSCREENPTR(pScreen); -+ -+ if (!pVNC->cursorIsDrawn) -+ return; -+ -+ pScreenPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ -+ pVNC->dontSendFramebufferUpdate = TRUE; -+ pVNC->cursorIsDrawn = FALSE; -+ pScreenPriv->pCacheWin = NullWindow; -+ if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pScreen, -+ pScreenPriv->saved.x1, -+ pScreenPriv->saved.y1, -+ pScreenPriv->saved.x2 - pScreenPriv->saved.x1, -+ pScreenPriv->saved.y2 - pScreenPriv->saved.y1)) -+ { -+ pVNC->cursorIsDrawn = TRUE; -+ } -+ pVNC->dontSendFramebufferUpdate = FALSE; -+} -+ -+ -+void -+rfbSpriteRestoreCursor (ScreenPtr pScreen) -+{ -+ rfbSpriteScreenPtr pScreenPriv; -+ int x, y; -+ CursorPtr pCursor; -+ VNCSCREENPTR(pScreen); -+ -+ pScreenPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ pCursor = pScreenPriv->pCursor; -+ -+ if (pVNC->cursorIsDrawn || !pCursor) -+ return; -+ -+ pVNC->dontSendFramebufferUpdate = TRUE; -+ -+ rfbSpriteComputeSaved (pScreen); -+ -+ x = pScreenPriv->x - (int)pCursor->bits->xhot; -+ y = pScreenPriv->y - (int)pCursor->bits->yhot; -+ if ((*pScreenPriv->funcs->SaveUnderCursor) (pScreen, -+ pScreenPriv->saved.x1, -+ pScreenPriv->saved.y1, -+ pScreenPriv->saved.x2 - pScreenPriv->saved.x1, -+ pScreenPriv->saved.y2 - pScreenPriv->saved.y1)) -+ { -+ if (pScreenPriv->checkPixels) -+ rfbSpriteFindColors (pScreen); -+ if ((*pScreenPriv->funcs->PutUpCursor) (pScreen, pCursor, x, y, -+ pScreenPriv->colors[SOURCE_COLOR].pixel, -+ pScreenPriv->colors[MASK_COLOR].pixel)) -+ pVNC->cursorIsDrawn = TRUE; -+ } -+ -+ pVNC->dontSendFramebufferUpdate = FALSE; -+} -+ -+/* -+ * compute the desired area of the screen to save -+ */ -+ -+static void -+rfbSpriteComputeSaved (ScreenPtr pScreen) -+{ -+ rfbSpriteScreenPtr pScreenPriv; -+ int x, y, w, h; -+ int wpad, hpad; -+ CursorPtr pCursor; -+ -+ pScreenPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ pCursor = pScreenPriv->pCursor; -+ x = pScreenPriv->x - (int)pCursor->bits->xhot; -+ y = pScreenPriv->y - (int)pCursor->bits->yhot; -+ w = pCursor->bits->width; -+ h = pCursor->bits->height; -+ wpad = SPRITE_PAD; -+ hpad = SPRITE_PAD; -+ pScreenPriv->saved.x1 = x - wpad; -+ pScreenPriv->saved.y1 = y - hpad; -+ pScreenPriv->saved.x2 = pScreenPriv->saved.x1 + w + wpad * 2; -+ pScreenPriv->saved.y2 = pScreenPriv->saved.y1 + h + hpad * 2; -+} -+ -+ -+/* -+ * this function is called when the cursor shape is being changed -+ */ -+ -+static Bool -+rfbDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) -+{ -+ rfbClientPtr cl; -+ rfbSpriteScreenPtr pPriv; -+ Bool status; -+ -+ for (cl = rfbClientHead; cl ; cl = cl->next) { -+ if (cl->enableCursorShapeUpdates) -+ cl->cursorWasChanged = TRUE; -+ } -+ -+ pPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ status = (*pPriv->DisplayCursor)(pDev, pScreen, pCursor); -+ -+ /* send new cursor shape to interested viewers */ -+ for (cl = rfbClientHead; cl ; cl = cl->next) { -+ if (cl->cursorWasChanged) { -+ rfbSendFramebufferUpdate(pScreen, cl); -+ } -+ } -+ -+ return status; -+} -+ -+ -+/* -+ * obtain current cursor pointer -+ */ -+ -+CursorPtr -+rfbSpriteGetCursorPtr (ScreenPtr pScreen) -+{ -+ rfbSpriteScreenPtr pScreenPriv; -+ -+ pScreenPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ -+ return pScreenPriv->pCursor; -+} -+ -+/* -+ * obtain current cursor position -+ */ -+ -+void -+rfbSpriteGetCursorPos (ScreenPtr pScreen, int *px, int *py) -+{ -+ rfbSpriteScreenPtr pScreenPriv; -+ -+ pScreenPriv = (rfbSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates, -+ rfbSpriteScreenKey); -+ -+ *px = pScreenPriv->x; -+ *py = pScreenPriv->y; -+} -+ -diff -pruN xorg-server-1.12.1.orig/hw/vnc/sprite.h xorg-server-1.12.1/hw/vnc/sprite.h ---- xorg-server-1.12.1.orig/hw/vnc/sprite.h 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/sprite.h 2012-04-18 14:45:21.583820867 -0500 -@@ -0,0 +1,131 @@ -+/* -+ * sprite.h -+ * -+ * software-sprite/sprite drawing - based on misprite -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+ -+/* -+ -+Copyright (c) 1989 X Consortium -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+Except as contained in this notice, the name of the X Consortium shall not be -+used in advertising or otherwise to promote the sale, use or other dealings -+in this Software without prior written authorization from the X Consortium. -+*/ -+ -+typedef struct { -+ Bool (*RealizeCursor)( -+ ScreenPtr /*pScreen*/, -+ CursorPtr /*pCursor*/ -+); -+ Bool (*UnrealizeCursor)( -+ ScreenPtr /*pScreen*/, -+ CursorPtr /*pCursor*/ -+); -+ Bool (*PutUpCursor)( -+ ScreenPtr /*pScreen*/, -+ CursorPtr /*pCursor*/, -+ int /*x*/, -+ int /*y*/, -+ unsigned long /*source*/, -+ unsigned long /*mask*/ -+); -+ Bool (*SaveUnderCursor)( -+ ScreenPtr /*pScreen*/, -+ int /*x*/, -+ int /*y*/, -+ int /*w*/, -+ int /*h*/ -+); -+ Bool (*RestoreUnderCursor)( -+ ScreenPtr /*pScreen*/, -+ int /*x*/, -+ int /*y*/, -+ int /*w*/, -+ int /*h*/ -+); -+ Bool (*MoveCursor)( -+ ScreenPtr /*pScreen*/, -+ CursorPtr /*pCursor*/, -+ int /*x*/, -+ int /*y*/, -+ int /*w*/, -+ int /*h*/, -+ int /*dx*/, -+ int /*dy*/, -+ unsigned long /*source*/, -+ unsigned long /*mask*/ -+); -+ Bool (*ChangeSave)( -+ ScreenPtr /*pScreen*/, -+ int /*x*/, -+ int /*y*/, -+ int /*w*/, -+ int /*h*/, -+ int /*dx*/, -+ int /*dy*/ -+); -+ -+} rfbSpriteCursorFuncRec, *rfbSpriteCursorFuncPtr; -+ -+extern Bool rfbSpriteInitialize( -+ ScreenPtr /*pScreen*/, -+ rfbSpriteCursorFuncPtr /*cursorFuncs*/, -+ miPointerScreenFuncPtr /*screenFuncs*/ -+); -+ -+extern void rfbSpriteRestoreCursor( -+ ScreenPtr /*pScreen*/ -+); -+ -+extern void rfbSpriteRemoveCursor( -+ ScreenPtr /*pScreen*/ -+); -+ -+extern CursorPtr rfbSpriteGetCursorPtr( -+ ScreenPtr /*pScreen*/ -+); -+ -+extern void rfbSpriteGetCursorPos( -+ ScreenPtr /*pScreen*/, -+ int * /*px*/, -+ int * /*py*/ -+); -diff -pruN xorg-server-1.12.1.orig/hw/vnc/spritest.h xorg-server-1.12.1/hw/vnc/spritest.h ---- xorg-server-1.12.1.orig/hw/vnc/spritest.h 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/spritest.h 2012-04-18 14:45:21.583820867 -0500 -@@ -0,0 +1,134 @@ -+/* -+ * spritest.h -+ * -+ * sprite structures - based on misprite -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+ -+/* -+ -+Copyright (c) 1989 X Consortium -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+Except as contained in this notice, the name of the X Consortium shall not be -+used in advertising or otherwise to promote the sale, use or other dealings -+in this Software without prior written authorization from the X Consortium. -+*/ -+ -+# include "sprite.h" -+ -+#ifdef RENDER -+# include "picturestr.h" -+#endif -+ -+/* -+ * per screen information -+ */ -+ -+typedef struct { -+ CloseScreenProcPtr CloseScreen; -+ GetImageProcPtr GetImage; -+ GetSpansProcPtr GetSpans; -+ SourceValidateProcPtr SourceValidate; -+ CreateGCProcPtr CreateGC; -+ ScreenBlockHandlerProcPtr BlockHandler; -+ InstallColormapProcPtr InstallColormap; -+ StoreColorsProcPtr StoreColors; -+ CopyWindowProcPtr CopyWindow; -+ ClearToBackgroundProcPtr ClearToBackground; -+ DisplayCursorProcPtr DisplayCursor; -+#ifdef RENDER -+ CompositeProcPtr Composite; -+ GlyphsProcPtr Glyphs; -+#endif -+ -+ CursorPtr pCursor; -+ int x; -+ int y; -+ Bool shouldBeUp; -+ BoxRec saved; -+ WindowPtr pCacheWin; -+ Bool isInCacheWin; -+ Bool checkPixels; -+ xColorItem colors[2]; -+ ColormapPtr pInstalledMap; -+ ColormapPtr pColormap; -+ VisualPtr pVisual; -+ rfbSpriteCursorFuncPtr funcs; -+} rfbSpriteScreenRec, *rfbSpriteScreenPtr; -+ -+#define SOURCE_COLOR 0 -+#define MASK_COLOR 1 -+ -+typedef struct { -+ GCFuncs *wrapFuncs; -+ GCOps *wrapOps; -+} rfbSpriteGCRec, *rfbSpriteGCPtr; -+ -+/* -+ * Overlap BoxPtr and Box elements -+ */ -+#define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \ -+ (((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \ -+ ((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2)) -+ -+/* -+ * Overlap BoxPtr, origins, and rectangle -+ */ -+#define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \ -+ BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h)) -+ -+/* -+ * Overlap BoxPtr, origins and RectPtr -+ */ -+#define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \ -+ ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y, \ -+ (int)((pRect)->width), (int)((pRect)->height)) -+/* -+ * Overlap BoxPtr and horizontal span -+ */ -+#define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y)) -+ -+#define LINE_SORT(x1,y1,x2,y2) \ -+{ int _t; \ -+ if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \ -+ if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } } -+ -+#define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \ -+ BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2)) -diff -pruN xorg-server-1.12.1.orig/hw/vnc/stats.c xorg-server-1.12.1/hw/vnc/stats.c ---- xorg-server-1.12.1.orig/hw/vnc/stats.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/stats.c 2012-04-18 14:45:21.583820867 -0500 -@@ -0,0 +1,117 @@ -+/* -+ * stats.c -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * Copyright (C) 2002 Constantin Kaplinsky. All Rights Reserved. -+ * 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#include -+#include -+#include "rfb.h" -+ -+static char* encNames[] = { -+ "raw", "copyRect", "RRE", "[encoding 3]", "CoRRE", "hextile", -+ "zlib", "tight", "[encoding 8]", "[encoding 9]" -+}; -+ -+ -+void -+rfbResetStats(rfbClientPtr cl) -+{ -+ int i; -+ for (i = 0; i < MAX_ENCODINGS; i++) { -+ cl->rfbBytesSent[i] = 0; -+ cl->rfbRectanglesSent[i] = 0; -+ } -+ cl->rfbLastRectMarkersSent = 0; -+ cl->rfbLastRectBytesSent = 0; -+ cl->rfbCursorShapeBytesSent = 0; -+ cl->rfbCursorShapeUpdatesSent = 0; -+ cl->rfbCursorPosBytesSent = 0; -+ cl->rfbCursorPosUpdatesSent = 0; -+ cl->rfbFramebufferUpdateMessagesSent = 0; -+ cl->rfbRawBytesEquivalent = 0; -+ cl->rfbKeyEventsRcvd = 0; -+ cl->rfbPointerEventsRcvd = 0; -+} -+ -+void -+rfbPrintStats(rfbClientPtr cl) -+{ -+ int i; -+ int totalRectanglesSent = 0; -+ int totalBytesSent = 0; -+ -+ rfbLog("Statistics:\n"); -+ -+ if ((cl->rfbKeyEventsRcvd != 0) || (cl->rfbPointerEventsRcvd != 0)) -+ rfbLog(" key events received %d, pointer events %d\n", -+ cl->rfbKeyEventsRcvd, cl->rfbPointerEventsRcvd); -+ -+ for (i = 0; i < MAX_ENCODINGS; i++) { -+ totalRectanglesSent += cl->rfbRectanglesSent[i]; -+ totalBytesSent += cl->rfbBytesSent[i]; -+ } -+ totalRectanglesSent += (cl->rfbCursorShapeUpdatesSent + -+ cl->rfbCursorPosUpdatesSent + -+ cl->rfbLastRectMarkersSent); -+ totalBytesSent += (cl->rfbCursorShapeBytesSent + -+ cl->rfbCursorPosBytesSent + -+ cl->rfbLastRectBytesSent); -+ -+ rfbLog(" framebuffer updates %d, rectangles %d, bytes %d\n", -+ cl->rfbFramebufferUpdateMessagesSent, totalRectanglesSent, -+ totalBytesSent); -+ -+ if (cl->rfbLastRectMarkersSent != 0) -+ rfbLog(" LastRect markers %d, bytes %d\n", -+ cl->rfbLastRectMarkersSent, cl->rfbLastRectBytesSent); -+ -+ if (cl->rfbCursorShapeUpdatesSent != 0) -+ rfbLog(" cursor shape updates %d, bytes %d\n", -+ cl->rfbCursorShapeUpdatesSent, cl->rfbCursorShapeBytesSent); -+ -+ if (cl->rfbCursorPosUpdatesSent != 0) -+ rfbLog(" cursor position updates %d, bytes %d\n", -+ cl->rfbCursorPosUpdatesSent, cl->rfbCursorPosBytesSent); -+ -+ for (i = 0; i < MAX_ENCODINGS; i++) { -+ if (cl->rfbRectanglesSent[i] != 0) -+ rfbLog(" %s rectangles %d, bytes %d\n", -+ encNames[i], cl->rfbRectanglesSent[i], cl->rfbBytesSent[i]); -+ } -+ -+ if ((totalBytesSent - cl->rfbBytesSent[rfbEncodingCopyRect]) != 0) { -+ rfbLog(" raw bytes equivalent %d, compression ratio %f\n", -+ cl->rfbRawBytesEquivalent, -+ (double)cl->rfbRawBytesEquivalent -+ / (double)(totalBytesSent - -+ cl->rfbBytesSent[rfbEncodingCopyRect] - -+ cl->rfbCursorShapeBytesSent - -+ cl->rfbCursorPosBytesSent - -+ cl->rfbLastRectBytesSent)); -+ } -+} -diff -pruN xorg-server-1.12.1.orig/hw/vnc/symlink-vnc.sh xorg-server-1.12.1/hw/vnc/symlink-vnc.sh ---- xorg-server-1.12.1.orig/hw/vnc/symlink-vnc.sh 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/symlink-vnc.sh 2012-04-18 14:45:21.583820867 -0500 -@@ -0,0 +1,198 @@ -+#!/bin/sh -+ -+# -+# A script that symlinks source files from vnc to modular -+# -+# Author: Soren Sandmann (sandmann@redhat.com) (original) -+# adapted for vnc by Alan Hourihane -+ -+# -+# Things we would like to do -+# -+# - Check that all the relevant files exist -+# - AUTHORS, autogen.sh, configure.ac, ... -+# - Check that we have actually linked everything -+# - if a file doesn't need to be linked, then it needs -+# to be listed as "not-linked" -+# - Compute diffs between all the files (shouldn't be necessary) -+# - possibly check that files are listet in Makefile.am's -+# - Clean target directory of irrelevant files -+# -+ -+check_destinations () { -+ # don't do anything - we are relying on the side -+ # effect of dst_dir -+ true -+} -+ -+check_exist() { -+ # Check whether $1 exists -+ -+ if [ ! -e $1 ] ; then -+ error "$1 not found" -+ fi -+} -+ -+delete_existing() { -+ # Delete $2 -+ -+ rm -f $2 -+} -+ -+link_files() { -+ # Link $1 to $2 -+ -+ if [ ! -e $2 ] ; then -+ ln -s $1 $2 -+ fi -+} -+ -+main() { -+ check_args $1 $2 -+ -+ run check_destinations "Creating destination directories" -+ run check_exist "Checking that the source files exist" -+ run delete_existing "Deleting existing files" -+ run link_files "Linking files" -+} -+ -+## actual symlinking -+ -+symlink_vnc() { -+ src_dir . -+ dst_dir . -+ action d3des.c -+ action d3des.h -+ action auth.c -+ action cmap.c -+ action corre.c -+ action cursor.c -+ action cutpaste.c -+ action dispcur.c -+ action draw.c -+ action hextile.c -+ action httpd.c -+ action kbdptr.c -+ action keyboard.h -+ action loginauth.c -+ action rdp.c -+ action rfb.h -+ action rfbkeyb.c -+ action rfbmouse.c -+ action rfbproto.h -+ action rfbserver.c -+ action rre.c -+ action sockets.c -+ action sprite.c -+ action sprite.h -+ action spritest.h -+ action stats.c -+ action tableinitcmtemplate.c -+ action tableinittctemplate.c -+ action tabletranstemplate.c -+ action tight.c -+ action translate.c -+ action vncauth.c -+ action vncauth.h -+ action vncext.c -+ action xistubs.c -+ action zlib.c -+} -+ -+######### -+# -+# Helper functions -+# -+######### -+ -+error() { -+ echo -+ echo \ \ \ error:\ \ \ $1 -+ exit 1 -+} -+ -+# printing out what's going on -+run_module() { -+ # $1 module -+ # $2 explanation -+ echo -n $EXPLANATION for $1 module ...\ -+ symlink_$1 -+ echo DONE -+} -+ -+run() { -+ # $1 what to do -+ # $2 explanation -+ -+ ACTION=$1 EXPLANATION=$2 run_module vnc -+} -+ -+src_dir() { -+ REAL_SRC_DIR=$SRC_DIR/$1 -+ if [ ! -d $REAL_SRC_DIR ] ; then -+ error "Source directory $REAL_SRC_DIR does not exist" -+ fi -+} -+ -+dst_dir() { -+ REAL_DST_DIR=$DST_DIR/$1 -+ if [ ! -d $REAL_DST_DIR ] ; then -+ mkdir -p $REAL_DST_DIR -+ fi -+} -+ -+action() { -+ if [ -z $2 ] ; then -+ $ACTION $REAL_SRC_DIR/$1 $REAL_DST_DIR/$1 -+ else -+ $ACTION $REAL_SRC_DIR/$1 $REAL_DST_DIR/$2 -+ fi -+} -+ -+usage() { -+ echo symlink.sh src-dir dst-dir -+ echo src-dir: the xc directory of the monolithic source tree -+ echo dst-dir: the modular source tree containing proto, app, lib, ... -+} -+ -+# Check commandline args -+check_args() { -+ if [ -z $1 ] ; then -+ echo Missing source dir -+ usage -+ exit 1 -+ fi -+ -+ if [ -z $2 ] ; then -+ echo Missing destination dir -+ usage -+ exit 1 -+ fi -+ -+ if [ ! -d $1 ] ; then -+ echo $1 is not a dir -+ usage -+ exit 1 -+ fi -+ -+ if [ ! -d $2 ] ; then -+ echo $2 is not a dir -+ usage -+ exit 1 -+ fi -+ -+ if [ $1 = $2 ] ; then -+ echo source and destination can\'t be the same -+ usage -+ exit 1 -+ fi -+ -+ D=`dirname "$relpath"` -+ B=`basename "$relpath"` -+ abspath="`cd \"$D\" 2>/dev/null && pwd || echo \"$D\"`/$B" -+ -+ SRC_DIR=`( cd $1 ; pwd )` -+ DST_DIR=`(cd $2 ; pwd )` -+} -+ -+main $1 $2 -diff -pruN xorg-server-1.12.1.orig/hw/vnc/tableinitcmtemplate.c xorg-server-1.12.1/hw/vnc/tableinitcmtemplate.c ---- xorg-server-1.12.1.orig/hw/vnc/tableinitcmtemplate.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/tableinitcmtemplate.c 2012-04-18 14:45:21.584820855 -0500 -@@ -0,0 +1,95 @@ -+/* -+ * tableinitcmtemplate.c - template for initialising lookup tables for -+ * translation from a colour map to true colour. -+ * -+ * This file shouldn't be compiled. It is included multiple times by -+ * translate.c, each time with a different definition of the macro OUT. -+ * For each value of OUT, this file defines a function which allocates an -+ * appropriately sized lookup table and initialises it. -+ * -+ * I know this code isn't nice to read because of all the macros, but -+ * efficiency is important here. -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#if !defined(OUT) -+#error "This file shouldn't be compiled." -+#error "It is included as part of translate.c" -+#endif -+ -+#define OUT_T CONCAT2E(CARD,OUT) -+#define SwapOUT(x) CONCAT2E(Swap,OUT(x)) -+#define rfbInitColourMapSingleTableOUT \ -+ CONCAT2E(rfbInitColourMapSingleTable,OUT) -+ -+static void -+rfbInitColourMapSingleTableOUT (ScreenPtr pScreen, char **table, rfbPixelFormat *in, -+ rfbPixelFormat *out) -+{ -+ int i, r, g, b; -+ OUT_T *t; -+ EntryPtr pent; -+ int nEntries = 1 << in->bitsPerPixel; -+#ifndef XFREE86VNC -+ VNCSCREENPTR(pScreen); -+#endif -+ -+ if (*table) free(*table); -+ *table = (char *)malloc(nEntries * sizeof(OUT_T)); -+ t = (OUT_T *)*table; -+ -+#if XFREE86VNC -+ pent = (EntryPtr)&GetInstalledmiColormap(pScreen)->red[0]; -+#else -+ pent = (EntryPtr)&pVNC->rfbInstalledColormap->red[0]; -+#endif -+ -+ for (i = 0; i < nEntries; i++) { -+ if (pent->fShared) { -+ r = pent->co.shco.red->color; -+ g = pent->co.shco.green->color; -+ b = pent->co.shco.blue->color; -+ } else { -+ r = pent->co.local.red; -+ g = pent->co.local.green; -+ b = pent->co.local.blue; -+ } -+ t[i] = ((((r * out->redMax + 32767) / 65535) << out->redShift) | -+ (((g * out->greenMax + 32767) / 65535) << out->greenShift) | -+ (((b * out->blueMax + 32767) / 65535) << out->blueShift)); -+#if (OUT != 8) -+ if (out->bigEndian != in->bigEndian) { -+ t[i] = SwapOUT(t[i]); -+ } -+#endif -+ pent++; -+ } -+} -+ -+#undef OUT_T -+#undef SwapOUT -+#undef rfbInitColourMapSingleTableOUT -diff -pruN xorg-server-1.12.1.orig/hw/vnc/tableinittctemplate.c xorg-server-1.12.1/hw/vnc/tableinittctemplate.c ---- xorg-server-1.12.1.orig/hw/vnc/tableinittctemplate.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/tableinittctemplate.c 2012-04-18 14:45:21.584820855 -0500 -@@ -0,0 +1,146 @@ -+/* -+ * tableinittctemplate.c - template for initialising lookup tables for -+ * truecolour to truecolour translation. -+ * -+ * This file shouldn't be compiled. It is included multiple times by -+ * translate.c, each time with a different definition of the macro OUT. -+ * For each value of OUT, this file defines two functions for initialising -+ * lookup tables. One is for truecolour translation using a single lookup -+ * table, the other is for truecolour translation using three separate -+ * lookup tables for the red, green and blue values. -+ * -+ * I know this code isn't nice to read because of all the macros, but -+ * efficiency is important here. -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#if !defined(OUT) -+#error "This file shouldn't be compiled." -+#error "It is included as part of translate.c" -+#endif -+ -+#define OUT_T CONCAT2E(CARD,OUT) -+#define SwapOUT(x) CONCAT2E(Swap,OUT(x)) -+#define rfbInitTrueColourSingleTableOUT \ -+ CONCAT2E(rfbInitTrueColourSingleTable,OUT) -+#define rfbInitTrueColourRGBTablesOUT CONCAT2E(rfbInitTrueColourRGBTables,OUT) -+#define rfbInitOneRGBTableOUT CONCAT2E(rfbInitOneRGBTable,OUT) -+ -+static void -+rfbInitOneRGBTableOUT (OUT_T *table, int inMax, int outMax, int outShift, -+ int swap); -+ -+ -+/* -+ * rfbInitTrueColourSingleTable sets up a single lookup table for truecolour -+ * translation. -+ */ -+ -+static void -+rfbInitTrueColourSingleTableOUT (ScreenPtr pScreen, char **table, rfbPixelFormat *in, -+ rfbPixelFormat *out) -+{ -+ int i; -+ int inRed, inGreen, inBlue, outRed, outGreen, outBlue; -+ OUT_T *t; -+ int nEntries = 1 << in->bitsPerPixel; -+ -+ if (*table) free(*table); -+ *table = (char *)malloc(nEntries * sizeof(OUT_T)); -+ t = (OUT_T *)*table; -+ -+ for (i = 0; i < nEntries; i++) { -+ inRed = (i >> in->redShift) & in->redMax; -+ inGreen = (i >> in->greenShift) & in->greenMax; -+ inBlue = (i >> in->blueShift) & in->blueMax; -+ -+ outRed = (inRed * out->redMax + in->redMax / 2) / in->redMax; -+ outGreen = (inGreen * out->greenMax + in->greenMax / 2) / in->greenMax; -+ outBlue = (inBlue * out->blueMax + in->blueMax / 2) / in->blueMax; -+ -+ t[i] = ((outRed << out->redShift) | -+ (outGreen << out->greenShift) | -+ (outBlue << out->blueShift)); -+#if (OUT != 8) -+ if (out->bigEndian != in->bigEndian) { -+ t[i] = SwapOUT(t[i]); -+ } -+#endif -+ } -+} -+ -+ -+/* -+ * rfbInitTrueColourRGBTables sets up three separate lookup tables for the -+ * red, green and blue values. -+ */ -+ -+static void -+rfbInitTrueColourRGBTablesOUT (ScreenPtr pScreen, char **table, rfbPixelFormat *in, -+ rfbPixelFormat *out) -+{ -+ OUT_T *redTable; -+ OUT_T *greenTable; -+ OUT_T *blueTable; -+ -+ if (*table) free(*table); -+ *table = (char *)malloc((in->redMax + in->greenMax + in->blueMax + 3) -+ * sizeof(OUT_T)); -+ redTable = (OUT_T *)*table; -+ greenTable = redTable + in->redMax + 1; -+ blueTable = greenTable + in->greenMax + 1; -+ -+ rfbInitOneRGBTableOUT (redTable, in->redMax, out->redMax, -+ out->redShift, (out->bigEndian != in->bigEndian)); -+ rfbInitOneRGBTableOUT (greenTable, in->greenMax, out->greenMax, -+ out->greenShift, (out->bigEndian != in->bigEndian)); -+ rfbInitOneRGBTableOUT (blueTable, in->blueMax, out->blueMax, -+ out->blueShift, (out->bigEndian != in->bigEndian)); -+} -+ -+static void -+rfbInitOneRGBTableOUT (OUT_T *table, int inMax, int outMax, int outShift, -+ int swap) -+{ -+ int i; -+ int nEntries = inMax + 1; -+ -+ for (i = 0; i < nEntries; i++) { -+ table[i] = ((i * outMax + inMax / 2) / inMax) << outShift; -+#if (OUT != 8) -+ if (swap) { -+ table[i] = SwapOUT(table[i]); -+ } -+#endif -+ } -+} -+ -+#undef OUT_T -+#undef SwapOUT -+#undef rfbInitTrueColourSingleTableOUT -+#undef rfbInitTrueColourRGBTablesOUT -+#undef rfbInitOneRGBTableOUT -diff -pruN xorg-server-1.12.1.orig/hw/vnc/tabletranstemplate.c xorg-server-1.12.1/hw/vnc/tabletranstemplate.c ---- xorg-server-1.12.1.orig/hw/vnc/tabletranstemplate.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/tabletranstemplate.c 2012-04-18 14:45:21.584820855 -0500 -@@ -0,0 +1,135 @@ -+/* -+ * tabletranstemplate.c - template for translation using lookup tables. -+ * -+ * This file shouldn't be compiled. It is included multiple times by -+ * translate.c, each time with different definitions of the macros IN and OUT. -+ * -+ * For each pair of values IN and OUT, this file defines two functions for -+ * translating a given rectangle of pixel data. One uses a single lookup -+ * table, and the other uses three separate lookup tables for the red, green -+ * and blue values. -+ * -+ * I know this code isn't nice to read because of all the macros, but -+ * efficiency is important here. -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#if !defined(IN) || !defined(OUT) -+#error "This file shouldn't be compiled." -+#error "It is included as part of translate.c" -+#endif -+ -+#define IN_T CONCAT2E(CARD,IN) -+#define OUT_T CONCAT2E(CARD,OUT) -+#define rfbTranslateWithSingleTableINtoOUT \ -+ CONCAT4E(rfbTranslateWithSingleTable,IN,to,OUT) -+#define rfbTranslateWithRGBTablesINtoOUT \ -+ CONCAT4E(rfbTranslateWithRGBTables,IN,to,OUT) -+ -+/* -+ * rfbTranslateWithSingleTableINtoOUT translates a rectangle of pixel data -+ * using a single lookup table. -+ */ -+ -+static void -+rfbTranslateWithSingleTableINtoOUT (ScreenPtr pScreen, char *table, rfbPixelFormat *in, -+ rfbPixelFormat *out, -+ unsigned char *optr, -+ int bytesBetweenInputLines, -+ int width, int height, -+ int x, int y) -+{ -+ IN_T *ip; -+ OUT_T *op = (OUT_T *)optr; -+ OUT_T *opLineEnd; -+ OUT_T *t = (OUT_T *)table; -+ DrawablePtr pDraw = (DrawablePtr)pScreen->root; -+ int truewidth = PixmapBytePad(width, in->bitsPerPixel); -+ unsigned char *iptr = malloc(truewidth * height * in->bitsPerPixel / 8); -+ int ipextra = truewidth - width; -+ (*pScreen->GetImage)(pDraw, x, y, truewidth, height, ZPixmap, ~0, (char*)iptr); -+ ip = (IN_T *)iptr; -+ -+ while (height > 0) { -+ opLineEnd = op + width; -+ -+ while (op < opLineEnd) { -+ *(op++) = t[*(ip++)]; -+ } -+ -+ ip += ipextra; -+ height--; -+ } -+ free(iptr); -+} -+ -+ -+/* -+ * rfbTranslateWithRGBTablesINtoOUT translates a rectangle of pixel data -+ * using three separate lookup tables for the red, green and blue values. -+ */ -+ -+static void -+rfbTranslateWithRGBTablesINtoOUT (ScreenPtr pScreen, char *table, rfbPixelFormat *in, -+ rfbPixelFormat *out, -+ unsigned char *optr, -+ int bytesBetweenInputLines, -+ int width, int height, -+ int x, int y) -+{ -+ IN_T *ip; -+ OUT_T *op = (OUT_T *)optr; -+ OUT_T *opLineEnd; -+ OUT_T *redTable = (OUT_T *)table; -+ OUT_T *greenTable = redTable + in->redMax + 1; -+ OUT_T *blueTable = greenTable + in->greenMax + 1; -+ DrawablePtr pDraw = (DrawablePtr)pScreen->root; -+ int truewidth = PixmapBytePad(width, in->bitsPerPixel); -+ unsigned char *iptr = malloc(truewidth * height * in->bitsPerPixel / 8); -+ int ipextra = truewidth - width; -+ (*pScreen->GetImage)(pDraw, x, y, truewidth, height, ZPixmap, ~0, (char*)iptr); -+ ip = (IN_T *)iptr; -+ -+ while (height > 0) { -+ opLineEnd = op + width; -+ -+ while (op < opLineEnd) { -+ *(op++) = (redTable[(*ip >> in->redShift) & in->redMax] | -+ greenTable[(*ip >> in->greenShift) & in->greenMax] | -+ blueTable[(*ip >> in->blueShift) & in->blueMax]); -+ ip++; -+ } -+ ip += ipextra; -+ height--; -+ } -+ free(iptr); -+} -+ -+#undef IN_T -+#undef OUT_T -+#undef rfbTranslateWithSingleTableINtoOUT -+#undef rfbTranslateWithRGBTablesINtoOUT -diff -pruN xorg-server-1.12.1.orig/hw/vnc/tight.c xorg-server-1.12.1/hw/vnc/tight.c ---- xorg-server-1.12.1.orig/hw/vnc/tight.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/tight.c 2012-04-18 14:45:21.585820842 -0500 -@@ -0,0 +1,1774 @@ -+/* -+ * tight.c -+ * -+ * Routines to implement Tight Encoding -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. -+ * 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#include -+#include "rfb.h" -+#include -+ -+ -+/* Note: The following constant should not be changed. */ -+#define TIGHT_MIN_TO_COMPRESS 12 -+ -+/* The parameters below may be adjusted. */ -+#define MIN_SPLIT_RECT_SIZE 4096 -+#define MIN_SOLID_SUBRECT_SIZE 2048 -+#define MAX_SPLIT_TILE_SIZE 16 -+ -+/* May be set to TRUE with "-lazytight" Xvnc option. */ -+Bool rfbTightDisableGradient = FALSE; -+ -+/* This variable is set on every rfbSendRectEncodingTight() call. */ -+static Bool usePixelFormat24; -+ -+ -+/* Compression level stuff. The following array contains various -+ encoder parameters for each of 10 compression levels (0..9). -+ Last three parameters correspond to JPEG quality levels (0..9). */ -+ -+typedef struct TIGHT_CONF_s { -+ int maxRectSize, maxRectWidth; -+ int monoMinRectSize, gradientMinRectSize; -+ int idxZlibLevel, monoZlibLevel, rawZlibLevel, gradientZlibLevel; -+ int gradientThreshold, gradientThreshold24; -+ int idxMaxColorsDivisor; -+ int jpegQuality, jpegThreshold, jpegThreshold24; -+} TIGHT_CONF; -+ -+static TIGHT_CONF tightConf[10] = { -+ { 512, 32, 6, 65536, 0, 0, 0, 0, 0, 0, 4, 5, 10000, 23000 }, -+ { 2048, 128, 6, 65536, 1, 1, 1, 0, 0, 0, 8, 10, 8000, 18000 }, -+ { 6144, 256, 8, 65536, 3, 3, 2, 0, 0, 0, 24, 15, 6500, 15000 }, -+ { 10240, 1024, 12, 65536, 5, 5, 3, 0, 0, 0, 32, 25, 5000, 12000 }, -+ { 16384, 2048, 12, 65536, 6, 6, 4, 0, 0, 0, 32, 37, 4000, 10000 }, -+ { 32768, 2048, 12, 4096, 7, 7, 5, 4, 150, 380, 32, 50, 3000, 8000 }, -+ { 65536, 2048, 16, 4096, 7, 7, 6, 4, 170, 420, 48, 60, 2000, 5000 }, -+ { 65536, 2048, 16, 4096, 8, 8, 7, 5, 180, 450, 64, 70, 1000, 2500 }, -+ { 65536, 2048, 32, 8192, 9, 9, 8, 6, 190, 475, 64, 75, 500, 1200 }, -+ { 65536, 2048, 32, 8192, 9, 9, 9, 6, 200, 500, 96, 80, 200, 500 } -+}; -+ -+/* Stuff dealing with palettes. */ -+ -+typedef struct COLOR_LIST_s { -+ struct COLOR_LIST_s *next; -+ int idx; -+ CARD32 rgb; -+} COLOR_LIST; -+ -+typedef struct PALETTE_ENTRY_s { -+ COLOR_LIST *listNode; -+ int numPixels; -+} PALETTE_ENTRY; -+ -+typedef struct PALETTE_s { -+ PALETTE_ENTRY entry[256]; -+ COLOR_LIST *hash[256]; -+ COLOR_LIST list[256]; -+} PALETTE; -+ -+static int paletteNumColors, paletteMaxColors; -+static CARD32 monoBackground, monoForeground; -+static PALETTE palette; -+ -+/* Pointers to dynamically-allocated buffers. */ -+ -+static int tightBeforeBufSize = 0; -+static unsigned char *tightBeforeBuf = NULL; -+ -+static int tightAfterBufSize = 0; -+static unsigned char *tightAfterBuf = NULL; -+ -+static int *prevRowBuf = NULL; -+ -+ -+/* Prototypes for static functions. */ -+ -+static void FindBestSolidArea (ScreenPtr pScreen, int x, int y, int w, int h, -+ CARD32 colorValue, int *w_ptr, int *h_ptr); -+static void ExtendSolidArea (ScreenPtr pScreen, int x, int y, int w, int h, -+ CARD32 colorValue, -+ int *x_ptr, int *y_ptr, int *w_ptr, int *h_ptr); -+static Bool CheckSolidTile (ScreenPtr pScreen, int x, int y, int w, int h, -+ CARD32 *colorPtr, Bool needSameColor); -+static Bool CheckSolidTile8 (ScreenPtr pScreen, int x, int y, int w, int h, -+ CARD32 *colorPtr, Bool needSameColor); -+static Bool CheckSolidTile16 (ScreenPtr pScreen, int x, int y, int w, int h, -+ CARD32 *colorPtr, Bool needSameColor); -+static Bool CheckSolidTile32 (ScreenPtr pScreen, int x, int y, int w, int h, -+ CARD32 *colorPtr, Bool needSameColor); -+ -+static Bool SendRectSimple (rfbClientPtr cl, int x, int y, int w, int h); -+static Bool SendSubrect (rfbClientPtr cl, int x, int y, int w, int h); -+static Bool SendTightHeader (rfbClientPtr cl, int x, int y, int w, int h); -+ -+static Bool SendSolidRect (rfbClientPtr cl); -+static Bool SendMonoRect (rfbClientPtr cl, int w, int h); -+static Bool SendIndexedRect (rfbClientPtr cl, int w, int h); -+static Bool SendFullColorRect (rfbClientPtr cl, int w, int h); -+static Bool SendGradientRect (rfbClientPtr cl, int w, int h); -+ -+static Bool CompressData(rfbClientPtr cl, int streamId, int dataLen, -+ int zlibLevel, int zlibStrategy); -+static Bool SendCompressedData(rfbClientPtr cl, int compressedLen); -+ -+static void FillPalette8(int count); -+static void FillPalette16(int count); -+static void FillPalette32(int count); -+ -+static void PaletteReset(void); -+static int PaletteInsert(CARD32 rgb, int numPixels, int bpp); -+ -+static void Pack24(ScreenPtr pScreen, unsigned char *buf, rfbPixelFormat *fmt, int count); -+ -+static void EncodeIndexedRect16(CARD8 *buf, int count); -+static void EncodeIndexedRect32(CARD8 *buf, int count); -+ -+static void EncodeMonoRect8(CARD8 *buf, int w, int h); -+static void EncodeMonoRect16(CARD8 *buf, int w, int h); -+static void EncodeMonoRect32(CARD8 *buf, int w, int h); -+ -+static void FilterGradient24(ScreenPtr pScreen, unsigned char *buf, rfbPixelFormat *fmt, int w, int h); -+static void FilterGradient16(ScreenPtr pScreen, CARD16 *buf, rfbPixelFormat *fmt, int w, int h); -+static void FilterGradient32(ScreenPtr pScreen, CARD32 *buf, rfbPixelFormat *fmt, int w, int h); -+ -+static int DetectSmoothImage(rfbClientPtr cl, rfbPixelFormat *fmt, int w, int h); -+static unsigned long DetectSmoothImage24(rfbClientPtr cl, rfbPixelFormat *fmt, int w, int h); -+static unsigned long DetectSmoothImage16(rfbClientPtr cl, rfbPixelFormat *fmt, int w, int h); -+static unsigned long DetectSmoothImage32(rfbClientPtr cl, rfbPixelFormat *fmt, int w, int h); -+ -+static Bool SendJpegRect(rfbClientPtr cl, const CARD8 *buffer, int w, int h, int quality); -+static void PrepareRowForJpeg(ScreenPtr pScreen, CARD8 *dst, const CARD8 *buffer, int row, int width); -+static void PrepareRowForJpeg24(ScreenPtr pScreen, CARD8 *dst, const CARD8 *buffer, int row, int width); -+static void PrepareRowForJpeg16(ScreenPtr pScreen, CARD8 *dst, const CARD8 *buffer, int row, int width); -+static void PrepareRowForJpeg32(ScreenPtr pScreen, CARD8 *dst, const CARD8 *buffer, int row, int width); -+ -+static void JpegInitDestination(j_compress_ptr cinfo); -+static boolean JpegEmptyOutputBuffer(j_compress_ptr cinfo); -+static void JpegTermDestination(j_compress_ptr cinfo); -+static void JpegSetDstManager(j_compress_ptr cinfo); -+ -+ -+/* -+ * Tight encoding implementation. -+ */ -+ -+int -+rfbNumCodedRectsTight(rfbClientPtr cl, -+ int x, int y, int w, int h) -+{ -+ int maxRectSize, maxRectWidth; -+ int subrectMaxWidth, subrectMaxHeight; -+ -+ /* No matter how many rectangles we will send if LastRect markers -+ are used to terminate rectangle stream. */ -+ if (cl->enableLastRectEncoding && w * h >= MIN_SPLIT_RECT_SIZE) -+ return 0; -+ -+ maxRectSize = tightConf[cl->tightCompressLevel].maxRectSize; -+ maxRectWidth = tightConf[cl->tightCompressLevel].maxRectWidth; -+ -+ if (w > maxRectWidth || w * h > maxRectSize) { -+ subrectMaxWidth = (w > maxRectWidth) ? maxRectWidth : w; -+ subrectMaxHeight = maxRectSize / subrectMaxWidth; -+ return (((w - 1) / maxRectWidth + 1) * -+ ((h - 1) / subrectMaxHeight + 1)); -+ } else { -+ return 1; -+ } -+} -+ -+Bool -+rfbSendRectEncodingTight(rfbClientPtr cl, -+ int x, int y, int w, int h) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ int nMaxRows; -+ CARD32 colorValue; -+ int dx, dy, dw, dh; -+ int x_best, y_best, w_best, h_best; -+ -+ if ( cl->format.depth == 24 && cl->format.redMax == 0xFF && -+ cl->format.greenMax == 0xFF && cl->format.blueMax == 0xFF ) { -+ usePixelFormat24 = TRUE; -+ } else { -+ usePixelFormat24 = FALSE; -+ } -+ -+ if (!cl->enableLastRectEncoding || w * h < MIN_SPLIT_RECT_SIZE) -+ return SendRectSimple(cl, x, y, w, h); -+ -+ /* Make sure we can write at least one pixel into tightBeforeBuf. */ -+ -+ if (tightBeforeBufSize < 4) { -+ tightBeforeBufSize = 4; -+ if (tightBeforeBuf == NULL) -+ tightBeforeBuf = (unsigned char *)malloc(tightBeforeBufSize); -+ else -+ tightBeforeBuf = (unsigned char *)realloc(tightBeforeBuf, -+ tightBeforeBufSize); -+ } -+ -+ /* Calculate maximum number of rows in one non-solid rectangle. */ -+ -+ { -+ int maxRectSize, maxRectWidth, nMaxWidth; -+ -+ maxRectSize = tightConf[cl->tightCompressLevel].maxRectSize; -+ maxRectWidth = tightConf[cl->tightCompressLevel].maxRectWidth; -+ nMaxWidth = (w > maxRectWidth) ? maxRectWidth : w; -+ nMaxRows = maxRectSize / nMaxWidth; -+ } -+ -+ /* Try to find large solid-color areas and send them separately. */ -+ -+ for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) { -+ -+ /* If a rectangle becomes too large, send its upper part now. */ -+ -+ if (dy - y >= nMaxRows) { -+ if (!SendRectSimple(cl, x, y, w, nMaxRows)) -+ return 0; -+ y += nMaxRows; -+ h -= nMaxRows; -+ } -+ -+ dh = (dy + MAX_SPLIT_TILE_SIZE <= y + h) ? -+ MAX_SPLIT_TILE_SIZE : (y + h - dy); -+ -+ for (dx = x; dx < x + w; dx += MAX_SPLIT_TILE_SIZE) { -+ -+ dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w) ? -+ MAX_SPLIT_TILE_SIZE : (x + w - dx); -+ -+ if (CheckSolidTile(cl->pScreen, dx, dy, dw, dh, &colorValue, FALSE)) { -+ -+ /* Get dimensions of solid-color area. */ -+ -+ FindBestSolidArea(cl->pScreen, dx, dy, w - (dx - x), h - (dy - y), -+ colorValue, &w_best, &h_best); -+ -+ /* Make sure a solid rectangle is large enough -+ (or the whole rectangle is of the same color). */ -+ -+ if ( w_best * h_best != w * h && -+ w_best * h_best < MIN_SOLID_SUBRECT_SIZE ) -+ continue; -+ -+ /* Try to extend solid rectangle to maximum size. */ -+ -+ x_best = dx; y_best = dy; -+ ExtendSolidArea(cl->pScreen, x, y, w, h, colorValue, -+ &x_best, &y_best, &w_best, &h_best); -+ -+ /* Send rectangles at top and left to solid-color area. */ -+ -+ if ( y_best != y && -+ !SendRectSimple(cl, x, y, w, y_best-y) ) -+ return FALSE; -+ if ( x_best != x && -+ !rfbSendRectEncodingTight(cl, x, y_best, -+ x_best-x, h_best) ) -+ return FALSE; -+ -+ /* Send solid-color rectangle. */ -+ -+ if (!SendTightHeader(cl, x_best, y_best, w_best, h_best)) -+ return FALSE; -+ -+ (*cl->translateFn)(cl->pScreen, cl->translateLookupTable, -+ &pVNC->rfbServerFormat, -+ &cl->format, tightBeforeBuf, -+ pVNC->paddedWidthInBytes, 1, 1, -+ x_best, y_best); -+ -+ if (!SendSolidRect(cl)) -+ return FALSE; -+ -+ /* Send remaining rectangles (at right and bottom). */ -+ -+ if ( x_best + w_best != x + w && -+ !rfbSendRectEncodingTight(cl, x_best+w_best, y_best, -+ w-(x_best-x)-w_best, h_best) ) -+ return FALSE; -+ if ( y_best + h_best != y + h && -+ !rfbSendRectEncodingTight(cl, x, y_best+h_best, -+ w, h-(y_best-y)-h_best) ) -+ return FALSE; -+ -+ /* Return after all recursive calls are done. */ -+ -+ return TRUE; -+ } -+ -+ } -+ -+ } -+ -+ /* No suitable solid-color rectangles found. */ -+ -+ return SendRectSimple(cl, x, y, w, h); -+} -+ -+static void -+FindBestSolidArea(ScreenPtr pScreen, -+ int x, int y, int w, int h, -+ CARD32 colorValue, -+ int *w_ptr, int *h_ptr) -+{ -+ int dx, dy, dw, dh; -+ int w_prev; -+ int w_best = 0, h_best = 0; -+ -+ w_prev = w; -+ -+ for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) { -+ -+ dh = (dy + MAX_SPLIT_TILE_SIZE <= y + h) ? -+ MAX_SPLIT_TILE_SIZE : (y + h - dy); -+ dw = (w_prev > MAX_SPLIT_TILE_SIZE) ? -+ MAX_SPLIT_TILE_SIZE : w_prev; -+ -+ if (!CheckSolidTile(pScreen, x, dy, dw, dh, &colorValue, TRUE)) -+ break; -+ -+ for (dx = x + dw; dx < x + w_prev;) { -+ dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w_prev) ? -+ MAX_SPLIT_TILE_SIZE : (x + w_prev - dx); -+ if (!CheckSolidTile(pScreen, dx, dy, dw, dh, &colorValue, TRUE)) -+ break; -+ dx += dw; -+ } -+ -+ w_prev = dx - x; -+ if (w_prev * (dy + dh - y) > w_best * h_best) { -+ w_best = w_prev; -+ h_best = dy + dh - y; -+ } -+ } -+ -+ *w_ptr = w_best; -+ *h_ptr = h_best; -+} -+ -+static void -+ExtendSolidArea(ScreenPtr pScreen, int x, int y, int w, int h, -+ CARD32 colorValue, -+ int *x_ptr, int *y_ptr, int *w_ptr, int *h_ptr) -+{ -+ int cx, cy; -+ -+ /* Try to extend the area upwards. */ -+ for ( cy = *y_ptr - 1; -+ cy >= y && CheckSolidTile(pScreen, *x_ptr, cy, *w_ptr, 1, &colorValue, TRUE); -+ cy-- ); -+ *h_ptr += *y_ptr - (cy + 1); -+ *y_ptr = cy + 1; -+ -+ /* ... downwards. */ -+ for ( cy = *y_ptr + *h_ptr; -+ cy < y + h && -+ CheckSolidTile(pScreen, *x_ptr, cy, *w_ptr, 1, &colorValue, TRUE); -+ cy++ ); -+ *h_ptr += cy - (*y_ptr + *h_ptr); -+ -+ /* ... to the left. */ -+ for ( cx = *x_ptr - 1; -+ cx >= x && CheckSolidTile(pScreen, cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE); -+ cx-- ); -+ *w_ptr += *x_ptr - (cx + 1); -+ *x_ptr = cx + 1; -+ -+ /* ... to the right. */ -+ for ( cx = *x_ptr + *w_ptr; -+ cx < x + w && -+ CheckSolidTile(pScreen, cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE); -+ cx++ ); -+ *w_ptr += cx - (*x_ptr + *w_ptr); -+} -+ -+/* -+ * Check if a rectangle is all of the same color. If needSameColor is -+ * set to non-zero, then also check that its color equals to the -+ * *colorPtr value. The result is 1 if the test is successfull, and in -+ * that case new color will be stored in *colorPtr. -+ */ -+ -+static Bool -+CheckSolidTile(ScreenPtr pScreen, int x, int y, int w, int h, CARD32 *colorPtr, -+ Bool needSameColor) -+{ -+ VNCSCREENPTR(pScreen); -+ switch(pVNC->rfbServerFormat.bitsPerPixel) { -+ case 32: -+ return CheckSolidTile32(pScreen, x, y, w, h, colorPtr, needSameColor); -+ case 16: -+ return CheckSolidTile16(pScreen, x, y, w, h, colorPtr, needSameColor); -+ default: -+ return CheckSolidTile8(pScreen, x, y, w, h, colorPtr, needSameColor); -+ } -+} -+ -+#define DEFINE_CHECK_SOLID_FUNCTION(bpp) \ -+ \ -+static Bool \ -+ CheckSolidTile##bpp(ScreenPtr pScreen, int x, int y, int w, int h, \ -+ CARD32 *colorPtr, Bool needSameColor) \ -+{ \ -+ VNCSCREENPTR(pScreen); \ -+ CARD##bpp *fbptr; \ -+ CARD##bpp colorValue; \ -+ int dx, dy; \ -+ \ -+ fbptr = (CARD##bpp *) \ -+ &pVNC->pfbMemory[y * pVNC->paddedWidthInBytes + x * (bpp/8)]; \ -+ \ -+ colorValue = *fbptr; \ -+ if (needSameColor && (CARD32)colorValue != *colorPtr) \ -+ return FALSE; \ -+ \ -+ for (dy = 0; dy < h; dy++) { \ -+ for (dx = 0; dx < w; dx++) { \ -+ if (colorValue != fbptr[dx]) \ -+ return FALSE; \ -+ } \ -+ fbptr = (CARD##bpp *)((CARD8 *)fbptr + pVNC->paddedWidthInBytes); \ -+ } \ -+ \ -+ *colorPtr = (CARD32)colorValue; \ -+ return TRUE; \ -+} -+ -+DEFINE_CHECK_SOLID_FUNCTION(8) -+DEFINE_CHECK_SOLID_FUNCTION(16) -+DEFINE_CHECK_SOLID_FUNCTION(32) -+ -+static Bool -+SendRectSimple(rfbClientPtr cl, int x, int y, int w, int h) -+{ -+ int maxBeforeSize, maxAfterSize; -+ int maxRectSize, maxRectWidth; -+ int subrectMaxWidth, subrectMaxHeight; -+ int dx, dy; -+ int rw, rh; -+ -+ maxRectSize = tightConf[cl->tightCompressLevel].maxRectSize; -+ maxRectWidth = tightConf[cl->tightCompressLevel].maxRectWidth; -+ -+ maxBeforeSize = maxRectSize * (cl->format.bitsPerPixel / 8); -+ maxAfterSize = maxBeforeSize + (maxBeforeSize + 99) / 100 + 12; -+ -+ if (tightBeforeBufSize < maxBeforeSize) { -+ tightBeforeBufSize = maxBeforeSize; -+ if (tightBeforeBuf == NULL) -+ tightBeforeBuf = (unsigned char *)malloc(tightBeforeBufSize); -+ else -+ tightBeforeBuf = (unsigned char *)realloc(tightBeforeBuf, -+ tightBeforeBufSize); -+ } -+ -+ if (tightAfterBufSize < maxAfterSize) { -+ tightAfterBufSize = maxAfterSize; -+ if (tightAfterBuf == NULL) -+ tightAfterBuf = (unsigned char *)malloc(tightAfterBufSize); -+ else -+ tightAfterBuf = (unsigned char *)realloc(tightAfterBuf, -+ tightAfterBufSize); -+ } -+ -+ if (w > maxRectWidth || w * h > maxRectSize) { -+ subrectMaxWidth = (w > maxRectWidth) ? maxRectWidth : w; -+ subrectMaxHeight = maxRectSize / subrectMaxWidth; -+ -+ for (dy = 0; dy < h; dy += subrectMaxHeight) { -+ for (dx = 0; dx < w; dx += maxRectWidth) { -+ rw = (dx + maxRectWidth < w) ? maxRectWidth : w - dx; -+ rh = (dy + subrectMaxHeight < h) ? subrectMaxHeight : h - dy; -+ if (!SendSubrect(cl, x+dx, y+dy, rw, rh)) -+ return FALSE; -+ } -+ } -+ } else { -+ if (!SendSubrect(cl, x, y, w, h)) -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+static Bool -+SendSubrect(rfbClientPtr cl, int x, int y, int w, int h) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ Bool success = FALSE; -+ -+ /* Send pending data if there is more than 128 bytes. */ -+ if (pVNC->ublen > 128) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ if (!SendTightHeader(cl, x, y, w, h)) -+ return FALSE; -+ -+ (*cl->translateFn)(cl->pScreen, cl->translateLookupTable, &pVNC->rfbServerFormat, -+ &cl->format, tightBeforeBuf, -+ pVNC->paddedWidthInBytes, w, h, x, y); -+ -+ paletteMaxColors = w * h / tightConf[cl->tightCompressLevel].idxMaxColorsDivisor; -+ if ( paletteMaxColors < 2 && -+ w * h >= tightConf[cl->tightCompressLevel].monoMinRectSize ) { -+ paletteMaxColors = 2; -+ } -+ switch (cl->format.bitsPerPixel) { -+ case 8: -+ FillPalette8(w * h); -+ break; -+ case 16: -+ FillPalette16(w * h); -+ break; -+ default: -+ FillPalette32(w * h); -+ } -+ -+ switch (paletteNumColors) { -+ case 0: -+ /* Truecolor image */ -+ if (DetectSmoothImage(cl, &cl->format, w, h)) { -+ if (cl->tightQualityLevel != -1) { -+ success = SendJpegRect(cl, tightBeforeBuf, w, h, -+ tightConf[cl->tightQualityLevel].jpegQuality); -+ } else { -+ success = SendGradientRect(cl, w, h); -+ } -+ } else { -+ success = SendFullColorRect(cl, w, h); -+ } -+ break; -+ case 1: -+ /* Solid rectangle */ -+ success = SendSolidRect(cl); -+ break; -+ case 2: -+ /* Two-color rectangle */ -+ success = SendMonoRect(cl, w, h); -+ break; -+ default: -+ /* Up to 256 different colors */ -+ if ( paletteNumColors > 96 && -+ cl->tightQualityLevel != -1 && cl->tightQualityLevel <= 3 && -+ DetectSmoothImage(cl, &cl->format, w, h) ) { -+ success = SendJpegRect(cl, tightBeforeBuf, w, h, -+ tightConf[cl->tightQualityLevel].jpegQuality); -+ } else { -+ success = SendIndexedRect(cl, w, h); -+ } -+ } -+ return success; -+} -+ -+static Bool -+SendTightHeader(rfbClientPtr cl, int x, int y, int w, int h) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ rfbFramebufferUpdateRectHeader rect; -+ -+ if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ rect.r.x = Swap16IfLE(x); -+ rect.r.y = Swap16IfLE(y); -+ rect.r.w = Swap16IfLE(w); -+ rect.r.h = Swap16IfLE(h); -+ rect.encoding = Swap32IfLE(rfbEncodingTight); -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect, -+ sz_rfbFramebufferUpdateRectHeader); -+ pVNC->ublen += sz_rfbFramebufferUpdateRectHeader; -+ -+ cl->rfbRectanglesSent[rfbEncodingTight]++; -+ cl->rfbBytesSent[rfbEncodingTight] += sz_rfbFramebufferUpdateRectHeader; -+ -+ return TRUE; -+} -+ -+/* -+ * Subencoding implementations. -+ */ -+ -+static Bool -+SendSolidRect(rfbClientPtr cl) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ int len; -+ -+ if (usePixelFormat24) { -+ Pack24(cl->pScreen, tightBeforeBuf, &cl->format, 1); -+ len = 3; -+ } else -+ len = cl->format.bitsPerPixel / 8; -+ -+ if (pVNC->ublen + 1 + len > UPDATE_BUF_SIZE) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ pVNC->updateBuf[pVNC->ublen++] = (char)(rfbTightFill << 4); -+ memcpy (&pVNC->updateBuf[pVNC->ublen], tightBeforeBuf, len); -+ pVNC->ublen += len; -+ -+ cl->rfbBytesSent[rfbEncodingTight] += len + 1; -+ -+ return TRUE; -+} -+ -+static Bool -+SendMonoRect(rfbClientPtr cl, int w, int h) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ int streamId = 1; -+ int paletteLen, dataLen; -+ -+ if ( (pVNC->ublen + TIGHT_MIN_TO_COMPRESS + 6 + -+ 2 * cl->format.bitsPerPixel / 8) > UPDATE_BUF_SIZE ) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ /* Prepare tight encoding header. */ -+ dataLen = (w + 7) / 8; -+ dataLen *= h; -+ -+ pVNC->updateBuf[pVNC->ublen++] = (streamId | rfbTightExplicitFilter) << 4; -+ pVNC->updateBuf[pVNC->ublen++] = rfbTightFilterPalette; -+ pVNC->updateBuf[pVNC->ublen++] = 1; -+ -+ /* Prepare palette, convert image. */ -+ switch (cl->format.bitsPerPixel) { -+ -+ case 32: -+ EncodeMonoRect32((CARD8 *)tightBeforeBuf, w, h); -+ -+ ((CARD32 *)tightAfterBuf)[0] = monoBackground; -+ ((CARD32 *)tightAfterBuf)[1] = monoForeground; -+ if (usePixelFormat24) { -+ Pack24(cl->pScreen, tightAfterBuf, &cl->format, 2); -+ paletteLen = 6; -+ } else -+ paletteLen = 8; -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], tightAfterBuf, paletteLen); -+ pVNC->ublen += paletteLen; -+ cl->rfbBytesSent[rfbEncodingTight] += 3 + paletteLen; -+ break; -+ -+ case 16: -+ EncodeMonoRect16((CARD8 *)tightBeforeBuf, w, h); -+ -+ ((CARD16 *)tightAfterBuf)[0] = (CARD16)monoBackground; -+ ((CARD16 *)tightAfterBuf)[1] = (CARD16)monoForeground; -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], tightAfterBuf, 4); -+ pVNC->ublen += 4; -+ cl->rfbBytesSent[rfbEncodingTight] += 7; -+ break; -+ -+ default: -+ EncodeMonoRect8((CARD8 *)tightBeforeBuf, w, h); -+ -+ pVNC->updateBuf[pVNC->ublen++] = (char)monoBackground; -+ pVNC->updateBuf[pVNC->ublen++] = (char)monoForeground; -+ cl->rfbBytesSent[rfbEncodingTight] += 5; -+ } -+ -+ return CompressData(cl, streamId, dataLen, -+ tightConf[cl->tightCompressLevel].monoZlibLevel, -+ Z_DEFAULT_STRATEGY); -+} -+ -+static Bool -+SendIndexedRect(rfbClientPtr cl, int w, int h) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ int streamId = 2; -+ int i, entryLen; -+ -+ if ( (pVNC->ublen + TIGHT_MIN_TO_COMPRESS + 6 + -+ paletteNumColors * cl->format.bitsPerPixel / 8) > UPDATE_BUF_SIZE ) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ /* Prepare tight encoding header. */ -+ pVNC->updateBuf[pVNC->ublen++] = (streamId | rfbTightExplicitFilter) << 4; -+ pVNC->updateBuf[pVNC->ublen++] = rfbTightFilterPalette; -+ pVNC->updateBuf[pVNC->ublen++] = (char)(paletteNumColors - 1); -+ -+ /* Prepare palette, convert image. */ -+ switch (cl->format.bitsPerPixel) { -+ -+ case 32: -+ EncodeIndexedRect32((CARD8 *)tightBeforeBuf, w * h); -+ -+ for (i = 0; i < paletteNumColors; i++) { -+ ((CARD32 *)tightAfterBuf)[i] = -+ palette.entry[i].listNode->rgb; -+ } -+ if (usePixelFormat24) { -+ Pack24(cl->pScreen, tightAfterBuf, &cl->format, paletteNumColors); -+ entryLen = 3; -+ } else -+ entryLen = 4; -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], tightAfterBuf, paletteNumColors * entryLen); -+ pVNC->ublen += paletteNumColors * entryLen; -+ cl->rfbBytesSent[rfbEncodingTight] += 3 + paletteNumColors * entryLen; -+ break; -+ -+ case 16: -+ EncodeIndexedRect16((CARD8 *)tightBeforeBuf, w * h); -+ -+ for (i = 0; i < paletteNumColors; i++) { -+ ((CARD16 *)tightAfterBuf)[i] = -+ (CARD16)palette.entry[i].listNode->rgb; -+ } -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], tightAfterBuf, paletteNumColors * 2); -+ pVNC->ublen += paletteNumColors * 2; -+ cl->rfbBytesSent[rfbEncodingTight] += 3 + paletteNumColors * 2; -+ break; -+ -+ default: -+ return FALSE; /* Should never happen. */ -+ } -+ -+ return CompressData(cl, streamId, w * h, -+ tightConf[cl->tightCompressLevel].idxZlibLevel, -+ Z_DEFAULT_STRATEGY); -+} -+ -+static Bool -+SendFullColorRect(rfbClientPtr cl, int w, int h) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ int streamId = 0; -+ int len; -+ -+ if (pVNC->ublen + TIGHT_MIN_TO_COMPRESS + 1 > UPDATE_BUF_SIZE) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ pVNC->updateBuf[pVNC->ublen++] = 0x00; /* stream id = 0, no flushing, no filter */ -+ cl->rfbBytesSent[rfbEncodingTight]++; -+ -+ if (usePixelFormat24) { -+ Pack24(cl->pScreen, tightBeforeBuf, &cl->format, w * h); -+ len = 3; -+ } else -+ len = cl->format.bitsPerPixel / 8; -+ -+ return CompressData(cl, streamId, w * h * len, -+ tightConf[cl->tightCompressLevel].rawZlibLevel, -+ Z_DEFAULT_STRATEGY); -+} -+ -+static Bool -+SendGradientRect(rfbClientPtr cl, int w, int h) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ int streamId = 3; -+ int len; -+ -+ if (cl->format.bitsPerPixel == 8) -+ return SendFullColorRect(cl, w, h); -+ -+ if (pVNC->ublen + TIGHT_MIN_TO_COMPRESS + 2 > UPDATE_BUF_SIZE) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ if (prevRowBuf == NULL) -+ prevRowBuf = (int *)malloc(2048 * 3 * sizeof(int)); -+ -+ pVNC->updateBuf[pVNC->ublen++] = (streamId | rfbTightExplicitFilter) << 4; -+ pVNC->updateBuf[pVNC->ublen++] = rfbTightFilterGradient; -+ cl->rfbBytesSent[rfbEncodingTight] += 2; -+ -+ if (usePixelFormat24) { -+ FilterGradient24(cl->pScreen, tightBeforeBuf, &cl->format, w, h); -+ len = 3; -+ } else if (cl->format.bitsPerPixel == 32) { -+ FilterGradient32(cl->pScreen, (CARD32 *)tightBeforeBuf, &cl->format, w, h); -+ len = 4; -+ } else { -+ FilterGradient16(cl->pScreen, (CARD16 *)tightBeforeBuf, &cl->format, w, h); -+ len = 2; -+ } -+ -+ return CompressData(cl, streamId, w * h * len, -+ tightConf[cl->tightCompressLevel].gradientZlibLevel, -+ Z_FILTERED); -+} -+ -+/** -+ * Compress the data in the tightBeforeBuf buffer. -+ * \param dataLen - amount of data in tightBeforeBuf to compress, in bytes -+ */ -+static Bool -+CompressData(rfbClientPtr cl, int streamId, int dataLen, int zlibLevel, int zlibStrategy) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ z_streamp pz; -+ int err; -+ -+ if (dataLen < TIGHT_MIN_TO_COMPRESS) { -+ memcpy(&pVNC->updateBuf[pVNC->ublen], tightBeforeBuf, dataLen); -+ pVNC->ublen += dataLen; -+ cl->rfbBytesSent[rfbEncodingTight] += dataLen; -+ return TRUE; -+ } -+ -+ pz = &cl->zsStruct[streamId]; -+ -+ /* Initialize compression stream if needed. */ -+ if (!cl->zsActive[streamId]) { -+ pz->zalloc = Z_NULL; -+ pz->zfree = Z_NULL; -+ pz->opaque = Z_NULL; -+ -+ err = deflateInit2 (pz, zlibLevel, Z_DEFLATED, MAX_WBITS, -+ MAX_MEM_LEVEL, zlibStrategy); -+ if (err != Z_OK) -+ return FALSE; -+ -+ cl->zsActive[streamId] = TRUE; -+ cl->zsLevel[streamId] = zlibLevel; -+ } -+ -+ /* Prepare buffer pointers. */ -+ pz->next_in = (Bytef *)tightBeforeBuf; -+ pz->avail_in = dataLen; -+ pz->next_out = (Bytef *)tightAfterBuf; -+ pz->avail_out = tightAfterBufSize; -+ -+ /* Change compression parameters if needed. */ -+ if (zlibLevel != cl->zsLevel[streamId]) { -+ if (deflateParams (pz, zlibLevel, zlibStrategy) != Z_OK) { -+ return FALSE; -+ } -+ cl->zsLevel[streamId] = zlibLevel; -+ } -+ -+ /* Actual compression. */ -+ if ( deflate (pz, Z_SYNC_FLUSH) != Z_OK || -+ pz->avail_in != 0 || pz->avail_out == 0 ) { -+ return FALSE; -+ } -+ -+ return SendCompressedData(cl, tightAfterBufSize - pz->avail_out); -+} -+ -+static Bool SendCompressedData(rfbClientPtr cl, int compressedLen) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ int i, portionLen; -+ -+ pVNC->updateBuf[pVNC->ublen++] = compressedLen & 0x7F; -+ cl->rfbBytesSent[rfbEncodingTight]++; -+ if (compressedLen > 0x7F) { -+ pVNC->updateBuf[pVNC->ublen-1] |= 0x80; -+ pVNC->updateBuf[pVNC->ublen++] = compressedLen >> 7 & 0x7F; -+ cl->rfbBytesSent[rfbEncodingTight]++; -+ if (compressedLen > 0x3FFF) { -+ pVNC->updateBuf[pVNC->ublen-1] |= 0x80; -+ pVNC->updateBuf[pVNC->ublen++] = compressedLen >> 14 & 0xFF; -+ cl->rfbBytesSent[rfbEncodingTight]++; -+ } -+ } -+ -+ portionLen = UPDATE_BUF_SIZE; -+ for (i = 0; i < compressedLen; i += portionLen) { -+ if (i + portionLen > compressedLen) { -+ portionLen = compressedLen - i; -+ } -+ if (pVNC->ublen + portionLen > UPDATE_BUF_SIZE) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ memcpy(&pVNC->updateBuf[pVNC->ublen], &tightAfterBuf[i], portionLen); -+ pVNC->ublen += portionLen; -+ } -+ cl->rfbBytesSent[rfbEncodingTight] += compressedLen; -+ return TRUE; -+} -+ -+/* -+ * Code to determine how many different colors used in rectangle. -+ */ -+ -+static void -+FillPalette8(int count) -+{ -+ CARD8 *data = (CARD8 *)tightBeforeBuf; -+ CARD8 c0, c1; -+ int i, n0, n1; -+ -+ paletteNumColors = 0; -+ -+ c0 = data[0]; -+ for (i = 1; i < count && data[i] == c0; i++); -+ if (i == count) { -+ paletteNumColors = 1; -+ return; /* Solid rectangle */ -+ } -+ -+ if (paletteMaxColors < 2) -+ return; -+ -+ n0 = i; -+ c1 = data[i]; -+ n1 = 0; -+ for (i++; i < count; i++) { -+ if (data[i] == c0) { -+ n0++; -+ } else if (data[i] == c1) { -+ n1++; -+ } else -+ break; -+ } -+ if (i == count) { -+ if (n0 > n1) { -+ monoBackground = (CARD32)c0; -+ monoForeground = (CARD32)c1; -+ } else { -+ monoBackground = (CARD32)c1; -+ monoForeground = (CARD32)c0; -+ } -+ paletteNumColors = 2; /* Two colors */ -+ } -+} -+ -+#define DEFINE_FILL_PALETTE_FUNCTION(bpp) \ -+ \ -+static void \ -+FillPalette##bpp(int count) \ -+ \ -+{ \ -+ CARD##bpp *data = (CARD##bpp *)tightBeforeBuf; \ -+ CARD##bpp c0, c1, ci = 0; \ -+ int i, n0, n1, ni; \ -+ \ -+ c0 = data[0]; \ -+ for (i = 1; i < count && data[i] == c0; i++); \ -+ if (i >= count) { \ -+ paletteNumColors = 1; /* Solid rectangle */ \ -+ return; \ -+ } \ -+ \ -+ if (paletteMaxColors < 2) { \ -+ paletteNumColors = 0; /* Full-color encoding preferred */ \ -+ return; \ -+ } \ -+ \ -+ n0 = i; \ -+ c1 = data[i]; \ -+ n1 = 0; \ -+ for (i++; i < count; i++) { \ -+ ci = data[i]; \ -+ if (ci == c0) { \ -+ n0++; \ -+ } else if (ci == c1) { \ -+ n1++; \ -+ } else \ -+ break; \ -+ } \ -+ if (i >= count) { \ -+ if (n0 > n1) { \ -+ monoBackground = (CARD32)c0; \ -+ monoForeground = (CARD32)c1; \ -+ } else { \ -+ monoBackground = (CARD32)c1; \ -+ monoForeground = (CARD32)c0; \ -+ } \ -+ paletteNumColors = 2; /* Two colors */ \ -+ return; \ -+ } \ -+ \ -+ PaletteReset(); \ -+ PaletteInsert (c0, (CARD32)n0, bpp); \ -+ PaletteInsert (c1, (CARD32)n1, bpp); \ -+ \ -+ ni = 1; \ -+ for (i++; i < count; i++) { \ -+ if (data[i] == ci) { \ -+ ni++; \ -+ } else { \ -+ if (!PaletteInsert (ci, (CARD32)ni, bpp)) \ -+ return; \ -+ ci = data[i]; \ -+ ni = 1; \ -+ } \ -+ } \ -+ PaletteInsert (ci, (CARD32)ni, bpp); \ -+} -+ -+DEFINE_FILL_PALETTE_FUNCTION(16) -+DEFINE_FILL_PALETTE_FUNCTION(32) -+ -+ -+/* -+ * Functions to operate with palette structures. -+ */ -+ -+#define HASH_FUNC16(rgb) ((int)((((rgb) >> 8) + (rgb)) & 0xFF)) -+#define HASH_FUNC32(rgb) ((int)((((rgb) >> 16) + ((rgb) >> 8)) & 0xFF)) -+ -+static void -+PaletteReset(void) -+{ -+ paletteNumColors = 0; -+ memset(palette.hash, 0, 256 * sizeof(COLOR_LIST *)); -+} -+ -+static int -+PaletteInsert(CARD32 rgb, int numPixels, int bpp) -+{ -+ COLOR_LIST *pnode; -+ COLOR_LIST *prev_pnode = NULL; -+ int hash_key, idx, new_idx, count; -+ -+ hash_key = (bpp == 16) ? HASH_FUNC16(rgb) : HASH_FUNC32(rgb); -+ -+ pnode = palette.hash[hash_key]; -+ -+ while (pnode != NULL) { -+ if (pnode->rgb == rgb) { -+ /* Such palette entry already exists. */ -+ new_idx = idx = pnode->idx; -+ count = palette.entry[idx].numPixels + numPixels; -+ if (new_idx && palette.entry[new_idx-1].numPixels < count) { -+ do { -+ palette.entry[new_idx] = palette.entry[new_idx-1]; -+ palette.entry[new_idx].listNode->idx = new_idx; -+ new_idx--; -+ } -+ while (new_idx && palette.entry[new_idx-1].numPixels < count); -+ palette.entry[new_idx].listNode = pnode; -+ pnode->idx = new_idx; -+ } -+ palette.entry[new_idx].numPixels = count; -+ return paletteNumColors; -+ } -+ prev_pnode = pnode; -+ pnode = pnode->next; -+ } -+ -+ /* Check if palette is full. */ -+ if (paletteNumColors == 256 || paletteNumColors == paletteMaxColors) { -+ paletteNumColors = 0; -+ return 0; -+ } -+ -+ /* Move palette entries with lesser pixel counts. */ -+ for ( idx = paletteNumColors; -+ idx > 0 && palette.entry[idx-1].numPixels < numPixels; -+ idx-- ) { -+ palette.entry[idx] = palette.entry[idx-1]; -+ palette.entry[idx].listNode->idx = idx; -+ } -+ -+ /* Add new palette entry into the freed slot. */ -+ pnode = &palette.list[paletteNumColors]; -+ if (prev_pnode != NULL) { -+ prev_pnode->next = pnode; -+ } else { -+ palette.hash[hash_key] = pnode; -+ } -+ pnode->next = NULL; -+ pnode->idx = idx; -+ pnode->rgb = rgb; -+ palette.entry[idx].listNode = pnode; -+ palette.entry[idx].numPixels = numPixels; -+ -+ return (++paletteNumColors); -+} -+ -+ -+/* -+ * Converting 32-bit color samples into 24-bit colors. -+ * Should be called only when redMax, greenMax and blueMax are 255. -+ * Color components assumed to be byte-aligned. -+ */ -+ -+static void Pack24(ScreenPtr pScreen, unsigned char *buf, -+ rfbPixelFormat *fmt, -+ int count) -+{ -+ VNCSCREENPTR(pScreen); -+ CARD32 *buf32; -+ CARD32 pix; -+ int r_shift, g_shift, b_shift; -+ -+ buf32 = (CARD32 *)buf; -+ -+ if (!pVNC->rfbServerFormat.bigEndian == !fmt->bigEndian) { -+ r_shift = fmt->redShift; -+ g_shift = fmt->greenShift; -+ b_shift = fmt->blueShift; -+ } else { -+ r_shift = 24 - fmt->redShift; -+ g_shift = 24 - fmt->greenShift; -+ b_shift = 24 - fmt->blueShift; -+ } -+ -+ while (count--) { -+ pix = *buf32++; -+ *buf++ = (char)(pix >> r_shift); -+ *buf++ = (char)(pix >> g_shift); -+ *buf++ = (char)(pix >> b_shift); -+ } -+} -+ -+ -+/* -+ * Converting truecolor samples into palette indices. -+ */ -+ -+#define DEFINE_IDX_ENCODE_FUNCTION(bpp) \ -+ \ -+static void \ -+EncodeIndexedRect##bpp(CARD8 *buf, int count) \ -+{ \ -+ COLOR_LIST *pnode; \ -+ CARD##bpp *src; \ -+ CARD##bpp rgb; \ -+ int rep = 0; \ -+ \ -+ src = (CARD##bpp *) buf; \ -+ \ -+ while (count--) { \ -+ rgb = *src++; \ -+ while (count && *src == rgb) { \ -+ rep++, src++, count--; \ -+ } \ -+ pnode = palette.hash[HASH_FUNC##bpp(rgb)]; \ -+ while (pnode != NULL) { \ -+ if ((CARD##bpp)pnode->rgb == rgb) { \ -+ *buf++ = (CARD8)pnode->idx; \ -+ while (rep) { \ -+ *buf++ = (CARD8)pnode->idx; \ -+ rep--; \ -+ } \ -+ break; \ -+ } \ -+ pnode = pnode->next; \ -+ } \ -+ } \ -+} -+ -+DEFINE_IDX_ENCODE_FUNCTION(16) -+DEFINE_IDX_ENCODE_FUNCTION(32) -+ -+#define DEFINE_MONO_ENCODE_FUNCTION(bpp) \ -+ \ -+static void \ -+EncodeMonoRect##bpp(CARD8 *buf, int w, int h) \ -+{ \ -+ CARD##bpp *ptr; \ -+ CARD##bpp bg; \ -+ unsigned int value, mask; \ -+ int aligned_width; \ -+ int x, y, bg_bits; \ -+ \ -+ ptr = (CARD##bpp *) buf; \ -+ bg = (CARD##bpp) monoBackground; \ -+ aligned_width = w - w % 8; \ -+ \ -+ for (y = 0; y < h; y++) { \ -+ for (x = 0; x < aligned_width; x += 8) { \ -+ for (bg_bits = 0; bg_bits < 8; bg_bits++) { \ -+ if (*ptr++ != bg) \ -+ break; \ -+ } \ -+ if (bg_bits == 8) { \ -+ *buf++ = 0; \ -+ continue; \ -+ } \ -+ mask = 0x80 >> bg_bits; \ -+ value = mask; \ -+ for (bg_bits++; bg_bits < 8; bg_bits++) { \ -+ mask >>= 1; \ -+ if (*ptr++ != bg) { \ -+ value |= mask; \ -+ } \ -+ } \ -+ *buf++ = (CARD8)value; \ -+ } \ -+ \ -+ mask = 0x80; \ -+ value = 0; \ -+ if (x >= w) \ -+ continue; \ -+ \ -+ for (; x < w; x++) { \ -+ if (*ptr++ != bg) { \ -+ value |= mask; \ -+ } \ -+ mask >>= 1; \ -+ } \ -+ *buf++ = (CARD8)value; \ -+ } \ -+} -+ -+DEFINE_MONO_ENCODE_FUNCTION(8) -+DEFINE_MONO_ENCODE_FUNCTION(16) -+DEFINE_MONO_ENCODE_FUNCTION(32) -+ -+ -+/* -+ * ``Gradient'' filter for 24-bit color samples. -+ * Should be called only when redMax, greenMax and blueMax are 255. -+ * Color components assumed to be byte-aligned. -+ */ -+ -+static void -+FilterGradient24(ScreenPtr pScreen, unsigned char *buf, rfbPixelFormat *fmt, int w, int h) -+{ -+ VNCSCREENPTR(pScreen); -+ CARD32 *buf32; -+ CARD32 pix32; -+ int *prevRowPtr; -+ int shiftBits[3]; -+ int pixHere[3], pixUpper[3], pixLeft[3], pixUpperLeft[3]; -+ int prediction; -+ int x, y, c; -+ -+ buf32 = (CARD32 *)buf; -+ memset (prevRowBuf, 0, w * 3 * sizeof(int)); -+ -+ if (!pVNC->rfbServerFormat.bigEndian == !fmt->bigEndian) { -+ shiftBits[0] = fmt->redShift; -+ shiftBits[1] = fmt->greenShift; -+ shiftBits[2] = fmt->blueShift; -+ } else { -+ shiftBits[0] = 24 - fmt->redShift; -+ shiftBits[1] = 24 - fmt->greenShift; -+ shiftBits[2] = 24 - fmt->blueShift; -+ } -+ -+ for (y = 0; y < h; y++) { -+ for (c = 0; c < 3; c++) { -+ pixUpper[c] = 0; -+ pixHere[c] = 0; -+ } -+ prevRowPtr = prevRowBuf; -+ for (x = 0; x < w; x++) { -+ pix32 = *buf32++; -+ for (c = 0; c < 3; c++) { -+ pixUpperLeft[c] = pixUpper[c]; -+ pixLeft[c] = pixHere[c]; -+ pixUpper[c] = *prevRowPtr; -+ pixHere[c] = (int)(pix32 >> shiftBits[c] & 0xFF); -+ *prevRowPtr++ = pixHere[c]; -+ -+ prediction = pixLeft[c] + pixUpper[c] - pixUpperLeft[c]; -+ if (prediction < 0) { -+ prediction = 0; -+ } else if (prediction > 0xFF) { -+ prediction = 0xFF; -+ } -+ *buf++ = (char)(pixHere[c] - prediction); -+ } -+ } -+ } -+} -+ -+ -+/* -+ * ``Gradient'' filter for other color depths. -+ */ -+ -+#define DEFINE_GRADIENT_FILTER_FUNCTION(bpp) \ -+ \ -+static void \ -+FilterGradient##bpp(ScreenPtr pScreen, CARD##bpp *buf, \ -+rfbPixelFormat *fmt, int w, int h) \ -+{ \ -+ VNCSCREENPTR(pScreen); \ -+ CARD##bpp pix, diff; \ -+ Bool endianMismatch; \ -+ int *prevRowPtr; \ -+ int maxColor[3], shiftBits[3]; \ -+ int pixHere[3], pixUpper[3], pixLeft[3], pixUpperLeft[3]; \ -+ int prediction; \ -+ int x, y, c; \ -+ \ -+ memset (prevRowBuf, 0, w * 3 * sizeof(int)); \ -+ \ -+ endianMismatch = (!pVNC->rfbServerFormat.bigEndian != !fmt->bigEndian); \ -+ \ -+ maxColor[0] = fmt->redMax; \ -+ maxColor[1] = fmt->greenMax; \ -+ maxColor[2] = fmt->blueMax; \ -+ shiftBits[0] = fmt->redShift; \ -+ shiftBits[1] = fmt->greenShift; \ -+ shiftBits[2] = fmt->blueShift; \ -+ \ -+ for (y = 0; y < h; y++) { \ -+ for (c = 0; c < 3; c++) { \ -+ pixUpper[c] = 0; \ -+ pixHere[c] = 0; \ -+ } \ -+ prevRowPtr = prevRowBuf; \ -+ for (x = 0; x < w; x++) { \ -+ pix = *buf; \ -+ if (endianMismatch) { \ -+ pix = Swap##bpp(pix); \ -+ } \ -+ diff = 0; \ -+ for (c = 0; c < 3; c++) { \ -+ pixUpperLeft[c] = pixUpper[c]; \ -+ pixLeft[c] = pixHere[c]; \ -+ pixUpper[c] = *prevRowPtr; \ -+ pixHere[c] = (int)(pix >> shiftBits[c] & maxColor[c]); \ -+ *prevRowPtr++ = pixHere[c]; \ -+ \ -+ prediction = pixLeft[c] + pixUpper[c] - pixUpperLeft[c]; \ -+ if (prediction < 0) { \ -+ prediction = 0; \ -+ } else if (prediction > maxColor[c]) { \ -+ prediction = maxColor[c]; \ -+ } \ -+ diff |= ((pixHere[c] - prediction) & maxColor[c]) \ -+ << shiftBits[c]; \ -+ } \ -+ if (endianMismatch) { \ -+ diff = Swap##bpp(diff); \ -+ } \ -+ *buf++ = diff; \ -+ } \ -+ } \ -+} -+ -+DEFINE_GRADIENT_FILTER_FUNCTION(16) -+DEFINE_GRADIENT_FILTER_FUNCTION(32) -+ -+ -+/* -+ * Code to guess if given rectangle is suitable for smooth image -+ * compression (by applying "gradient" filter or JPEG coder). -+ */ -+ -+#define JPEG_MIN_RECT_SIZE 4096 -+ -+#define DETECT_SUBROW_WIDTH 7 -+#define DETECT_MIN_WIDTH 8 -+#define DETECT_MIN_HEIGHT 8 -+ -+static int -+DetectSmoothImage (rfbClientPtr cl, rfbPixelFormat *fmt, int w, int h) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ unsigned long avgError; -+ -+ if ( pVNC->rfbServerFormat.bitsPerPixel == 8 || fmt->bitsPerPixel == 8 || -+ w < DETECT_MIN_WIDTH || h < DETECT_MIN_HEIGHT ) { -+ return 0; -+ } -+ -+ if (cl->tightQualityLevel != -1) { -+ if (w * h < JPEG_MIN_RECT_SIZE) { -+ return 0; -+ } -+ } else { -+ if ( rfbTightDisableGradient || -+ w * h < tightConf[cl->tightCompressLevel].gradientMinRectSize ) { -+ return 0; -+ } -+ } -+ -+ if (fmt->bitsPerPixel == 32) { -+ if (usePixelFormat24) { -+ avgError = DetectSmoothImage24(cl, fmt, w, h); -+ if (cl->tightQualityLevel != -1) { -+ return (avgError < tightConf[cl->tightQualityLevel].jpegThreshold24); -+ } -+ return (avgError < tightConf[cl->tightCompressLevel].gradientThreshold24); -+ } else { -+ avgError = DetectSmoothImage32(cl, fmt, w, h); -+ } -+ } else { -+ avgError = DetectSmoothImage16(cl, fmt, w, h); -+ } -+ if (cl->tightQualityLevel != -1) { -+ return (avgError < tightConf[cl->tightQualityLevel].jpegThreshold); -+ } -+ return (avgError < tightConf[cl->tightCompressLevel].gradientThreshold); -+} -+ -+static unsigned long -+DetectSmoothImage24 (rfbClientPtr cl, rfbPixelFormat *fmt, int w, int h) -+{ -+ int off; -+ int x, y, d, dx, c; -+ int diffStat[256]; -+ int pixelCount = 0; -+ int pix, left[3]; -+ unsigned long avgError; -+ -+ /* If client is big-endian, color samples begin from the second -+ byte (offset 1) of a 32-bit pixel value. */ -+ off = (fmt->bigEndian != 0); -+ -+ memset(diffStat, 0, 256*sizeof(int)); -+ -+ y = 0, x = 0; -+ while (y < h && x < w) { -+ for (d = 0; d < h - y && d < w - x - DETECT_SUBROW_WIDTH; d++) { -+ for (c = 0; c < 3; c++) { -+ left[c] = (int)tightBeforeBuf[((y+d)*w+x+d)*4+off+c] & 0xFF; -+ } -+ for (dx = 1; dx <= DETECT_SUBROW_WIDTH; dx++) { -+ for (c = 0; c < 3; c++) { -+ pix = (int)tightBeforeBuf[((y+d)*w+x+d+dx)*4+off+c] & 0xFF; -+ diffStat[abs(pix - left[c])]++; -+ left[c] = pix; -+ } -+ pixelCount++; -+ } -+ } -+ if (w > h) { -+ x += h; -+ y = 0; -+ } else { -+ x = 0; -+ y += w; -+ } -+ } -+ -+ if (diffStat[0] * 33 / pixelCount >= 95) -+ return 0; -+ -+ avgError = 0; -+ for (c = 1; c < 8; c++) { -+ avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c); -+ if (diffStat[c] == 0 || diffStat[c] > diffStat[c-1] * 2) -+ return 0; -+ } -+ for (; c < 256; c++) { -+ avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c); -+ } -+ avgError /= (pixelCount * 3 - diffStat[0]); -+ -+ return avgError; -+} -+ -+#define DEFINE_DETECT_FUNCTION(bpp) \ -+ \ -+static unsigned long \ -+DetectSmoothImage##bpp (rfbClientPtr cl, rfbPixelFormat *fmt, int w, int h) \ -+{ \ -+ VNCSCREENPTR(cl->pScreen); \ -+ Bool endianMismatch; \ -+ CARD##bpp pix; \ -+ int maxColor[3], shiftBits[3]; \ -+ int x, y, d, dx, c; \ -+ int diffStat[256]; \ -+ int pixelCount = 0; \ -+ int sample, sum, left[3]; \ -+ unsigned long avgError; \ -+ \ -+ endianMismatch = (!pVNC->rfbServerFormat.bigEndian != !fmt->bigEndian); \ -+ \ -+ maxColor[0] = fmt->redMax; \ -+ maxColor[1] = fmt->greenMax; \ -+ maxColor[2] = fmt->blueMax; \ -+ shiftBits[0] = fmt->redShift; \ -+ shiftBits[1] = fmt->greenShift; \ -+ shiftBits[2] = fmt->blueShift; \ -+ \ -+ memset(diffStat, 0, 256*sizeof(int)); \ -+ \ -+ y = 0, x = 0; \ -+ while (y < h && x < w) { \ -+ for (d = 0; d < h - y && d < w - x - DETECT_SUBROW_WIDTH; d++) { \ -+ pix = ((CARD##bpp *)tightBeforeBuf)[(y+d)*w+x+d]; \ -+ if (endianMismatch) { \ -+ pix = Swap##bpp(pix); \ -+ } \ -+ for (c = 0; c < 3; c++) { \ -+ left[c] = (int)(pix >> shiftBits[c] & maxColor[c]); \ -+ } \ -+ for (dx = 1; dx <= DETECT_SUBROW_WIDTH; dx++) { \ -+ pix = ((CARD##bpp *)tightBeforeBuf)[(y+d)*w+x+d+dx]; \ -+ if (endianMismatch) { \ -+ pix = Swap##bpp(pix); \ -+ } \ -+ sum = 0; \ -+ for (c = 0; c < 3; c++) { \ -+ sample = (int)(pix >> shiftBits[c] & maxColor[c]); \ -+ sum += abs(sample - left[c]); \ -+ left[c] = sample; \ -+ } \ -+ if (sum > 255) \ -+ sum = 255; \ -+ diffStat[sum]++; \ -+ pixelCount++; \ -+ } \ -+ } \ -+ if (w > h) { \ -+ x += h; \ -+ y = 0; \ -+ } else { \ -+ x = 0; \ -+ y += w; \ -+ } \ -+ } \ -+ \ -+ if ((diffStat[0] + diffStat[1]) * 100 / pixelCount >= 90) \ -+ return 0; \ -+ \ -+ avgError = 0; \ -+ for (c = 1; c < 8; c++) { \ -+ avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c); \ -+ if (diffStat[c] == 0 || diffStat[c] > diffStat[c-1] * 2) \ -+ return 0; \ -+ } \ -+ for (; c < 256; c++) { \ -+ avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c); \ -+ } \ -+ avgError /= (pixelCount - diffStat[0]); \ -+ \ -+ return avgError; \ -+} -+ -+DEFINE_DETECT_FUNCTION(16) -+DEFINE_DETECT_FUNCTION(32) -+ -+ -+/* -+ * JPEG compression stuff. -+ */ -+ -+static struct jpeg_destination_mgr jpegDstManager; -+static Bool jpegError; -+static int jpegDstDataLen; -+ -+/** -+ * Send the given image rect with jpeg compression. -+ * \param buffer the source image buffer -+ * \param w width of source image in pixels -+ * \param h height of source image in pixels -+ * \param quality jpeg enoding quality -+ */ -+static Bool -+SendJpegRect(rfbClientPtr cl, const CARD8 *buffer, int w, int h, -+ int quality) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ struct jpeg_compress_struct cinfo; -+ struct jpeg_error_mgr jerr; -+ CARD8 *srcBuf; -+ JSAMPROW rowPointer[1]; -+ int i; -+ -+ if (pVNC->rfbServerFormat.bitsPerPixel == 8) -+ return SendFullColorRect(cl, w, h); -+ -+ srcBuf = (CARD8 *)malloc(w * 3); -+ if (srcBuf == NULL) { -+ return SendFullColorRect(cl, w, h); -+ } -+ rowPointer[0] = srcBuf; -+ -+ cinfo.err = jpeg_std_error(&jerr); -+ jpeg_create_compress(&cinfo); -+ -+ cinfo.image_width = w; -+ cinfo.image_height = h; -+ cinfo.input_components = 3; -+ cinfo.in_color_space = JCS_RGB; -+ -+ jpeg_set_defaults(&cinfo); -+ jpeg_set_quality(&cinfo, quality, TRUE); -+ -+ JpegSetDstManager (&cinfo); -+ -+ jpeg_start_compress(&cinfo, TRUE); -+ -+ for (i = 0; i < h; i++) { -+ PrepareRowForJpeg(cl->pScreen, srcBuf, buffer, i, w); -+ jpeg_write_scanlines(&cinfo, rowPointer, 1); -+ if (jpegError) -+ break; -+ } -+ -+ if (!jpegError) -+ jpeg_finish_compress(&cinfo); -+ -+ jpeg_destroy_compress(&cinfo); -+ free((char *)srcBuf); -+ -+ if (jpegError) -+ return SendFullColorRect(cl, w, h); -+ -+ if (pVNC->ublen + TIGHT_MIN_TO_COMPRESS + 1 > UPDATE_BUF_SIZE) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ pVNC->updateBuf[pVNC->ublen++] = (char)(rfbTightJpeg << 4); -+ cl->rfbBytesSent[rfbEncodingTight]++; -+ -+ return SendCompressedData(cl, jpegDstDataLen); -+} -+ -+/** -+ * Convert pixel data to format needed for jpeg library. -+ * \dst destination buffer (24bpp) -+ * \buffer source buffer (16 or 32bpp) -+ * \row which image row to prepare/convert -+ * \width width of source buffer, in pixels -+ */ -+static void -+PrepareRowForJpeg(ScreenPtr pScreen, CARD8 *dst, const CARD8 *buffer, -+ int row, int width) -+{ -+ VNCSCREENPTR(pScreen); -+ if (pVNC->rfbServerFormat.bitsPerPixel == 32) { -+ if ( pVNC->rfbServerFormat.redMax == 0xFF && -+ pVNC->rfbServerFormat.greenMax == 0xFF && -+ pVNC->rfbServerFormat.blueMax == 0xFF ) { -+ PrepareRowForJpeg24(pScreen, dst, buffer, row, width); -+ } else { -+ PrepareRowForJpeg32(pScreen, dst, buffer, row, width); -+ } -+ } else { -+ /* 16 bpp assumed. */ -+ PrepareRowForJpeg16(pScreen, dst, buffer, row, width); -+ } -+} -+ -+/** -+ * Src buffer is 32bpp, dst buffer is 24bpp (optimized case). -+ */ -+static void -+PrepareRowForJpeg24(ScreenPtr pScreen, CARD8 *dst, const CARD8 *buffer, -+ int row, int width) -+{ -+ VNCSCREENPTR(pScreen); -+ const CARD32 *src = ((const CARD32 *) buffer) + row * width; -+ while (width--) { -+ CARD32 pix = *src++; -+ *dst++ = (CARD8)(pix >> pVNC->rfbServerFormat.redShift); -+ *dst++ = (CARD8)(pix >> pVNC->rfbServerFormat.greenShift); -+ *dst++ = (CARD8)(pix >> pVNC->rfbServerFormat.blueShift); -+ } -+} -+ -+/** -+ * PrepareRowForJpeg16/32: convert 16bpp or 32bpp pixels to 24bpp -+ */ -+#define DEFINE_JPEG_GET_ROW_FUNCTION(bpp) \ -+ \ -+static void \ -+PrepareRowForJpeg##bpp(ScreenPtr pScreen, CARD8 *dst, const CARD8 *buffer, \ -+ int row, int width) \ -+{ \ -+ VNCSCREENPTR(pScreen); \ -+ CARD##bpp *fbptr; \ -+ CARD##bpp pix; \ -+ int inRed, inGreen, inBlue; \ -+ \ -+ fbptr = ((CARD##bpp *) buffer) + row * width; \ -+ \ -+ while (width--) { \ -+ pix = *fbptr++; \ -+ \ -+ inRed = (int) \ -+ (pix >> pVNC->rfbServerFormat.redShift & pVNC->rfbServerFormat.redMax); \ -+ inGreen = (int) \ -+ (pix >> pVNC->rfbServerFormat.greenShift & pVNC->rfbServerFormat.greenMax); \ -+ inBlue = (int) \ -+ (pix >> pVNC->rfbServerFormat.blueShift & pVNC->rfbServerFormat.blueMax); \ -+ \ -+ *dst++ = (CARD8)((inRed * 255 + pVNC->rfbServerFormat.redMax / 2) / \ -+ pVNC->rfbServerFormat.redMax); \ -+ *dst++ = (CARD8)((inGreen * 255 + pVNC->rfbServerFormat.greenMax / 2) / \ -+ pVNC->rfbServerFormat.greenMax); \ -+ *dst++ = (CARD8)((inBlue * 255 + pVNC->rfbServerFormat.blueMax / 2) / \ -+ pVNC->rfbServerFormat.blueMax); \ -+ } \ -+} -+ -+DEFINE_JPEG_GET_ROW_FUNCTION(16) -+DEFINE_JPEG_GET_ROW_FUNCTION(32) -+ -+/* -+ * Destination manager implementation for JPEG library. -+ */ -+ -+static void -+JpegInitDestination(j_compress_ptr cinfo) -+{ -+ jpegError = FALSE; -+ jpegDstManager.next_output_byte = (JOCTET *)tightAfterBuf; -+ jpegDstManager.free_in_buffer = (size_t)tightAfterBufSize; -+} -+ -+static boolean -+JpegEmptyOutputBuffer(j_compress_ptr cinfo) -+{ -+ jpegError = TRUE; -+ jpegDstManager.next_output_byte = (JOCTET *)tightAfterBuf; -+ jpegDstManager.free_in_buffer = (size_t)tightAfterBufSize; -+ -+ return TRUE; -+} -+ -+static void -+JpegTermDestination(j_compress_ptr cinfo) -+{ -+ jpegDstDataLen = tightAfterBufSize - jpegDstManager.free_in_buffer; -+} -+ -+static void -+JpegSetDstManager(j_compress_ptr cinfo) -+{ -+ jpegDstManager.init_destination = JpegInitDestination; -+ jpegDstManager.empty_output_buffer = JpegEmptyOutputBuffer; -+ jpegDstManager.term_destination = JpegTermDestination; -+ cinfo->dest = &jpegDstManager; -+} -+ -diff -pruN xorg-server-1.12.1.orig/hw/vnc/translate.c xorg-server-1.12.1/hw/vnc/translate.c ---- xorg-server-1.12.1.orig/hw/vnc/translate.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/translate.c 2012-04-18 14:45:21.586820829 -0500 -@@ -0,0 +1,496 @@ -+/* -+ * translate.c - translate between different pixel formats -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * 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. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#include -+#include "rfb.h" -+#if XFREE86VNC -+#include -+#endif -+ -+static void PrintPixelFormat(rfbPixelFormat *pf); -+static Bool rfbSetClientColourMapBGR233(rfbClientPtr cl); -+ -+Bool rfbEconomicTranslate = FALSE; -+ -+/* -+ * Some standard pixel formats. -+ */ -+ -+static const rfbPixelFormat BGR233Format = { -+ 8, 8, 0, 1, 7, 7, 3, 0, 3, 6 -+}; -+ -+ -+/* -+ * Macro to compare pixel formats. -+ */ -+ -+#define PF_EQ(x,y) \ -+ ((x.bitsPerPixel == y.bitsPerPixel) && \ -+ (x.depth == y.depth) && \ -+ ((x.bigEndian == y.bigEndian) || (x.bitsPerPixel == 8)) && \ -+ (x.trueColour == y.trueColour) && \ -+ (!x.trueColour || ((x.redMax == y.redMax) && \ -+ (x.greenMax == y.greenMax) && \ -+ (x.blueMax == y.blueMax) && \ -+ (x.redShift == y.redShift) && \ -+ (x.greenShift == y.greenShift) && \ -+ (x.blueShift == y.blueShift)))) -+ -+#define CONCAT2(a,b) a##b -+#define CONCAT2E(a,b) CONCAT2(a,b) -+#define CONCAT4(a,b,c,d) a##b##c##d -+#define CONCAT4E(a,b,c,d) CONCAT4(a,b,c,d) -+ -+#define OUT 8 -+#include "tableinittctemplate.c" -+#include "tableinitcmtemplate.c" -+#define IN 8 -+#include "tabletranstemplate.c" -+#undef IN -+#define IN 16 -+#include "tabletranstemplate.c" -+#undef IN -+#define IN 32 -+#include "tabletranstemplate.c" -+#undef IN -+#undef OUT -+ -+#define OUT 16 -+#include "tableinittctemplate.c" -+#include "tableinitcmtemplate.c" -+#define IN 8 -+#include "tabletranstemplate.c" -+#undef IN -+#define IN 16 -+#include "tabletranstemplate.c" -+#undef IN -+#define IN 32 -+#include "tabletranstemplate.c" -+#undef IN -+#undef OUT -+ -+#define OUT 32 -+#include "tableinittctemplate.c" -+#include "tableinitcmtemplate.c" -+#define IN 8 -+#include "tabletranstemplate.c" -+#undef IN -+#define IN 16 -+#include "tabletranstemplate.c" -+#undef IN -+#define IN 32 -+#include "tabletranstemplate.c" -+#undef IN -+#undef OUT -+ -+typedef void (*rfbInitTableFnType)(ScreenPtr pScreen, char **table, rfbPixelFormat *in, -+ rfbPixelFormat *out); -+ -+rfbInitTableFnType rfbInitTrueColourSingleTableFns[3] = { -+ rfbInitTrueColourSingleTable8, -+ rfbInitTrueColourSingleTable16, -+ rfbInitTrueColourSingleTable32 -+}; -+ -+rfbInitTableFnType rfbInitColourMapSingleTableFns[3] = { -+ rfbInitColourMapSingleTable8, -+ rfbInitColourMapSingleTable16, -+ rfbInitColourMapSingleTable32 -+}; -+ -+rfbInitTableFnType rfbInitTrueColourRGBTablesFns[3] = { -+ rfbInitTrueColourRGBTables8, -+ rfbInitTrueColourRGBTables16, -+ rfbInitTrueColourRGBTables32 -+}; -+ -+rfbTranslateFnType rfbTranslateWithSingleTableFns[3][3] = { -+ { rfbTranslateWithSingleTable8to8, -+ rfbTranslateWithSingleTable8to16, -+ rfbTranslateWithSingleTable8to32 }, -+ { rfbTranslateWithSingleTable16to8, -+ rfbTranslateWithSingleTable16to16, -+ rfbTranslateWithSingleTable16to32 }, -+ { rfbTranslateWithSingleTable32to8, -+ rfbTranslateWithSingleTable32to16, -+ rfbTranslateWithSingleTable32to32 } -+}; -+ -+rfbTranslateFnType rfbTranslateWithRGBTablesFns[3][3] = { -+ { rfbTranslateWithRGBTables8to8, -+ rfbTranslateWithRGBTables8to16, -+ rfbTranslateWithRGBTables8to32 }, -+ { rfbTranslateWithRGBTables16to8, -+ rfbTranslateWithRGBTables16to16, -+ rfbTranslateWithRGBTables16to32 }, -+ { rfbTranslateWithRGBTables32to8, -+ rfbTranslateWithRGBTables32to16, -+ rfbTranslateWithRGBTables32to32 } -+}; -+ -+ -+ -+/* -+ * rfbTranslateNone is used when no translation is required. -+ */ -+ -+void -+rfbTranslateNone(ScreenPtr pScreen, char *table, rfbPixelFormat *in, rfbPixelFormat *out, -+ unsigned char *optr, int bytesBetweenInputLines, -+ int width, int height, int x, int y) -+{ -+ VNCSCREENPTR(pScreen); -+ DrawablePtr pDraw = (DrawablePtr)pScreen->root; -+ int truewidth = PixmapBytePad(width, in->bitsPerPixel) / 4; -+ -+ if ((x + truewidth > pVNC->width) || truewidth != width) { -+ unsigned char *buffer = malloc(truewidth * height * in->bitsPerPixel / 8); -+ unsigned char *buf = buffer; -+ -+ (*pScreen->GetImage)(pDraw, x, y, truewidth, height, ZPixmap, ~0, (char*)buf); -+ while (height--) { -+ memcpy(optr, buf, width * in->bitsPerPixel / 8); -+ optr += width * in->bitsPerPixel / 8; -+ buf += truewidth * in->bitsPerPixel / 8; -+ } -+ free(buffer); -+ return; -+ } -+ -+ (*pScreen->GetImage)(pDraw, x, y, width, height, ZPixmap, ~0, (char*)optr); -+} -+ -+ -+/* -+ * rfbSetTranslateFunction sets the translation function. -+ */ -+ -+Bool -+rfbSetTranslateFunction(rfbClientPtr cl) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ rfbLog("Pixel format for client %s:\n",cl->host); -+ PrintPixelFormat(&cl->format); -+ -+ /* -+ * Check that bits per pixel values are valid -+ */ -+ -+ if ((pVNC->rfbServerFormat.bitsPerPixel != 8) && -+ (pVNC->rfbServerFormat.bitsPerPixel != 16) && -+ (pVNC->rfbServerFormat.bitsPerPixel != 32)) -+ { -+ rfbLog("%s: server bits per pixel not 8, 16 or 32\n", -+ "rfbSetTranslateFunction"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return FALSE; -+ } -+ -+ if ((cl->format.bitsPerPixel != 8) && -+ (cl->format.bitsPerPixel != 16) && -+ (cl->format.bitsPerPixel != 32)) -+ { -+ rfbLog("%s: client bits per pixel not 8, 16 or 32\n", -+ "rfbSetTranslateFunction"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return FALSE; -+ } -+ -+ if (!pVNC->rfbServerFormat.trueColour && -+ (pVNC->rfbServerFormat.bitsPerPixel != 8) && -+#if XFREE86VNC -+ (GetInstalledmiColormap(cl->pScreen)->class == PseudoColor)) { -+#else -+ (pVNC->rfbInstalledColormap->class == PseudoColor)) { -+#endif -+ rfbLog("rfbSetTranslateFunction: server has colour map " -+ "but %d-bit - can only cope with 8-bit colour maps\n", -+ pVNC->rfbServerFormat.bitsPerPixel); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return FALSE; -+ } -+ -+ if (!cl->format.trueColour && -+ (cl->format.bitsPerPixel != 8) && -+#if XFREE86VNC -+ (GetInstalledmiColormap(cl->pScreen)->class == PseudoColor)) { -+#else -+ (pVNC->rfbInstalledColormap->class == PseudoColor) ) { -+#endif -+ rfbLog("rfbSetTranslateFunction: client has colour map " -+ "but %d-bit - can only cope with 8-bit colour maps\n", -+ cl->format.bitsPerPixel); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return FALSE; -+ } -+ -+ /* -+ * bpp is valid, now work out how to translate -+ */ -+ -+ if (!cl->format.trueColour) { -+ -+ /* ? -> colour map */ -+ -+ if (!pVNC->rfbServerFormat.trueColour) { -+ -+ /* colour map -> colour map */ -+ -+#if XFREE86VNC -+ if (GetInstalledmiColormap(cl->pScreen)->class == DirectColor) { -+#else -+ if (pVNC->rfbInstalledColormap->class == DirectColor) { -+#endif -+ rfbLog("rfbSetTranslateFunction: client is %d-bit DirectColor," -+ " client has colour map\n",cl->format.bitsPerPixel); -+ -+ cl->translateFn = rfbTranslateWithRGBTablesFns -+ [pVNC->rfbServerFormat.bitsPerPixel / 16] -+ [cl->format.bitsPerPixel / 16]; -+ -+ (*rfbInitTrueColourRGBTablesFns [cl->format.bitsPerPixel / 16]) -+ (cl->pScreen, &cl->translateLookupTable, -+ &pVNC->rfbServerFormat, &cl->format); -+ -+ return rfbSetClientColourMap(cl, 0, 0); -+ -+ /* PseudoColor colormap */ -+ -+ } else { -+ rfbLog("rfbSetTranslateFunction: both 8-bit colour map: " -+ "no translation needed\n"); -+ cl->translateFn = rfbTranslateNone; -+ return rfbSetClientColourMap(cl, 0, 0); -+ } -+ } -+ -+ /* -+ * truecolour -> colour map -+ * -+ * Set client's colour map to BGR233, then effectively it's -+ * truecolour as well -+ */ -+ -+ if (!rfbSetClientColourMapBGR233(cl)) -+ return FALSE; -+ -+ cl->format = BGR233Format; -+ } -+ -+ /* ? -> truecolour */ -+ -+ if (!pVNC->rfbServerFormat.trueColour) { -+ -+ /* colour map -> truecolour */ -+ -+ rfbLog("rfbSetTranslateFunction: client is %d-bit trueColour," -+ " server has colour map\n",cl->format.bitsPerPixel); -+ -+ cl->translateFn = rfbTranslateWithSingleTableFns -+ [pVNC->rfbServerFormat.bitsPerPixel / 16] -+ [cl->format.bitsPerPixel / 16]; -+ -+ return rfbSetClientColourMap(cl, 0, 0); -+ } -+ -+ /* truecolour -> truecolour */ -+ -+ if (PF_EQ(cl->format,pVNC->rfbServerFormat)) { -+ -+ /* client & server the same */ -+ -+ rfbLog(" no translation needed\n"); -+ cl->translateFn = rfbTranslateNone; -+ return TRUE; -+ } -+ -+ if ((pVNC->rfbServerFormat.bitsPerPixel < 16) || -+ (!rfbEconomicTranslate && (pVNC->rfbServerFormat.bitsPerPixel == 16))) { -+ -+ /* we can use a single lookup table for <= 16 bpp */ -+ -+ cl->translateFn = rfbTranslateWithSingleTableFns -+ [pVNC->rfbServerFormat.bitsPerPixel / 16] -+ [cl->format.bitsPerPixel / 16]; -+ -+ (*rfbInitTrueColourSingleTableFns -+ [cl->format.bitsPerPixel / 16]) (cl->pScreen, -+ &cl->translateLookupTable, -+ &pVNC->rfbServerFormat, &cl->format); -+ -+ } else { -+ -+ /* otherwise we use three separate tables for red, green and blue */ -+ -+ cl->translateFn = rfbTranslateWithRGBTablesFns -+ [pVNC->rfbServerFormat.bitsPerPixel / 16] -+ [cl->format.bitsPerPixel / 16]; -+ -+ (*rfbInitTrueColourRGBTablesFns -+ [cl->format.bitsPerPixel / 16]) (cl->pScreen, -+ &cl->translateLookupTable, -+ &pVNC->rfbServerFormat, &cl->format); -+ } -+ -+ return TRUE; -+} -+ -+ -+ -+/* -+ * rfbSetClientColourMapBGR233 sets the client's colour map so that it's -+ * just like an 8-bit BGR233 true colour client. -+ */ -+ -+static Bool -+rfbSetClientColourMapBGR233(rfbClientPtr cl) -+{ -+ char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2]; -+ rfbSetColourMapEntriesMsg *scme = (rfbSetColourMapEntriesMsg *)buf; -+ CARD16 *rgb = (CARD16 *)(&buf[sz_rfbSetColourMapEntriesMsg]); -+ int i, len; -+ int r, g, b; -+ -+ if (cl->format.bitsPerPixel != 8) { -+ rfbLog("%s: client not 8 bits per pixel\n", -+ "rfbSetClientColourMapBGR233"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return FALSE; -+ } -+ -+ scme->type = rfbSetColourMapEntries; -+ -+ scme->firstColour = Swap16IfLE(0); -+ scme->nColours = Swap16IfLE(256); -+ -+ len = sz_rfbSetColourMapEntriesMsg; -+ -+ i = 0; -+ -+ for (b = 0; b < 4; b++) { -+ for (g = 0; g < 8; g++) { -+ for (r = 0; r < 8; r++) { -+ rgb[i++] = Swap16IfLE(r * 65535 / 7); -+ rgb[i++] = Swap16IfLE(g * 65535 / 7); -+ rgb[i++] = Swap16IfLE(b * 65535 / 3); -+ } -+ } -+ } -+ -+ len += 256 * 3 * 2; -+ -+ if (WriteExact(cl->sock, buf, len) < 0) { -+ rfbLogPerror("rfbSetClientColourMapBGR233: write"); -+ rfbCloseSock(cl->pScreen, cl->sock); -+ return FALSE; -+ } -+ return TRUE; -+} -+ -+ -+/* -+ * rfbSetClientColourMap is called to set the client's colour map. If the -+ * client is a true colour client, we simply update our own translation table -+ * and mark the whole screen as having been modified. -+ */ -+ -+Bool -+ rfbSetClientColourMap(rfbClientPtr cl, -+ int firstColour, int nColours) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ BoxRec box; -+ -+ if (nColours == 0) { -+#if XFREE86VNC -+ nColours = GetInstalledmiColormap(cl->pScreen)->pVisual->ColormapEntries; -+#else -+ nColours = pVNC->rfbInstalledColormap->pVisual->ColormapEntries; -+#endif -+ } -+ -+ if (pVNC->rfbServerFormat.trueColour || !cl->readyForSetColourMapEntries) { -+ return TRUE; -+ } -+ -+ if (cl->format.trueColour) { -+ (*rfbInitColourMapSingleTableFns -+ [cl->format.bitsPerPixel / 16]) (cl->pScreen, -+ &cl->translateLookupTable, -+ &pVNC->rfbServerFormat, &cl->format); -+ -+ REGION_UNINIT(cl->pScreen,&cl->modifiedRegion); -+ box.x1 = box.y1 = 0; -+ box.x2 = pVNC->width; -+ box.y2 = pVNC->height; -+ REGION_INIT(cl->pScreen,&cl->modifiedRegion,&box,0); -+ -+ return TRUE; -+ } -+ -+ return rfbSendSetColourMapEntries(cl, firstColour, nColours); -+} -+ -+ -+/* -+ * rfbSetClientColourMaps sets the colour map for each RFB client. -+ */ -+ -+void -+ rfbSetClientColourMaps(int firstColour, int nColours) -+{ -+ rfbClientPtr cl, nextCl; -+ -+ for (cl = rfbClientHead; cl; cl = nextCl) { -+ nextCl = cl->next; -+ rfbSetClientColourMap(cl, firstColour, nColours); -+ } -+} -+ -+ -+static void -+PrintPixelFormat(rfbPixelFormat *pf) -+{ -+ if (pf->bitsPerPixel == 1) { -+ rfbLog(" 1 bpp, %s sig bit in each byte is leftmost on the screen.\n", -+ (pf->bigEndian ? "most" : "least")); -+ } else { -+ rfbLog(" %d bpp, depth %d%s\n",pf->bitsPerPixel,pf->depth, -+ ((pf->bitsPerPixel == 8) ? "" -+ : (pf->bigEndian ? ", big endian" : ", little endian"))); -+ if (pf->trueColour) { -+ rfbLog(" true colour: max r %d g %d b %d, shift r %d g %d b %d\n", -+ pf->redMax, pf->greenMax, pf->blueMax, -+ pf->redShift, pf->greenShift, pf->blueShift); -+ } else { -+ rfbLog(" uses a colour map (not true colour).\n"); -+ } -+ } -+} -diff -pruN xorg-server-1.12.1.orig/hw/vnc/vncauth.c xorg-server-1.12.1/hw/vnc/vncauth.c ---- xorg-server-1.12.1.orig/hw/vnc/vncauth.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/vncauth.c 2012-04-18 14:45:21.586820829 -0500 -@@ -0,0 +1,252 @@ -+/* -+ * 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 program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -+ * USA. -+ */ -+ -+/* -+ * vncauth.c - Functions for VNC password management and authentication. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+/* -+ * Make sure we call srandom() only once. -+ */ -+ -+static int s_srandom_called = 0; -+ -+/* -+ * We use a fixed key to store passwords, since we assume that our local -+ * file system is secure but nonetheless don't want to store passwords -+ * as plaintext. -+ */ -+ -+static unsigned char s_fixedkey[8] = {23,82,107,6,35,78,88,7}; -+ -+ -+/* -+ * Encrypt a password and store it in a file. Returns 0 if successful, -+ * 1 if the file could not be written. -+ * -+ * NOTE: This function is preserved only for compatibility with the original -+ * AT&T VNC software. Use vncEncryptAndStorePasswd2() instead. -+ */ -+ -+int -+vncEncryptAndStorePasswd(char *passwd, char *fname) -+{ -+ return (vncEncryptAndStorePasswd2(passwd, NULL, fname) == 0); -+} -+ -+/* -+ * Encrypt one or two passwords and store them in a file. Returns 1 if -+ * successful, 0 if the file could not be written (note that the original -+ * vncEncryptAndStorePasswd() function returns inverse values). The -+ * passwdViewOnly pointer may be NULL. -+ * -+ * NOTE: The file name of "-" denotes stdout. -+ */ -+ -+int -+vncEncryptAndStorePasswd2(char *passwd, char *passwdViewOnly, char *fname) -+{ -+ FILE *fp; -+ int bytesToWrite, bytesWrote; -+ unsigned char encryptedPasswd[16] = { -+ 0,0,0,0,0,0,0,0, -+ 0,0,0,0,0,0,0,0 -+ }; -+ -+ if (strcmp(fname, "-") != 0) { -+ fp = fopen(fname, "w"); -+ if (fp == NULL) { -+ return 0; -+ } -+ chmod(fname, S_IRUSR|S_IWUSR); -+ } else { -+ fp = stdout; -+ } -+ -+ strncpy((char*)encryptedPasswd, passwd, 8); -+ if (passwdViewOnly != NULL) -+ strncpy((char*)encryptedPasswd + 8, passwdViewOnly, 8); -+ -+ /* Do encryption in-place - this way we overwrite our copies of -+ plaintext passwords. */ -+ -+ deskey(s_fixedkey, EN0); -+ des(encryptedPasswd, encryptedPasswd); -+ if (passwdViewOnly != NULL) -+ des(encryptedPasswd + 8, encryptedPasswd + 8); -+ -+ bytesToWrite = (passwdViewOnly == NULL) ? 8 : 16; -+ bytesWrote = fwrite(encryptedPasswd, 1, bytesToWrite, fp); -+ -+ if (fp != stdout) { -+ fclose(fp); -+ } -+ return (bytesWrote == bytesToWrite); -+} -+ -+ -+/* -+ * Decrypt a password from a file. Returns a pointer to a newly allocated -+ * string containing the password or a null pointer if the password could -+ * not be retrieved for some reason. -+ * -+ * NOTE: This function is preserved only for compatibility with the original -+ * AT&T VNC software. Use vncDecryptPasswdFromFile2() instead. -+ */ -+ -+char * -+vncDecryptPasswdFromFile(char *fname) -+{ -+ char *passwd; -+ -+ passwd = malloc(9); -+ -+ if (passwd != NULL) { -+ if (vncDecryptPasswdFromFile2(fname, passwd, NULL) == 0) { -+ free(passwd); -+ passwd = NULL; -+ } -+ } -+ -+ return passwd; -+} -+ -+/* -+ * Decrypt one or two passwords from a file. Returns the number of -+ * passwords read (1, 2, or 0 on error). On success, the passwords are -+ * written into buffers passwdFullControl[] and passwdViewOnly[] if -+ * they are not NULL. If the pointers to buffers are not NULL, then -+ * the buffers should be at least of 9 bytes length. -+ */ -+ -+int -+vncDecryptPasswdFromFile2(char *fname, -+ char *passwdFullControl, char *passwdViewOnly) -+{ -+ FILE *fp; -+ int i, ch; -+ unsigned char passwd[16]; -+ -+ if (strcmp(fname, "-") != 0) { -+ if ((fp = fopen(fname,"r")) == NULL) -+ return 0; /* Could not open the file */ -+ } else { -+ fp = stdin; -+ } -+ -+ for (i = 0; i < 16; i++) { -+ ch = getc(fp); -+ if (ch == EOF) -+ break; -+ passwd[i] = ch; -+ } -+ -+ if (fp != stdin) -+ fclose(fp); -+ -+ if (i < 8) -+ return 0; /* Could not read eight bytes */ -+ -+ deskey(s_fixedkey, DE1); -+ -+ /* Decoding first (full-control) password */ -+ if (passwdFullControl != NULL) { -+ des(passwd, passwd); -+ memcpy(passwdFullControl, passwd, 8); -+ passwdFullControl[8] = '\0'; -+ } -+ -+ /* Decoding second (view-only) password if available */ -+ if (i == 16 && passwdViewOnly != NULL) { -+ des(&passwd[8], &passwd[8]); -+ memcpy(passwdViewOnly, &passwd[8], 8); -+ passwdViewOnly[8] = '\0'; -+ } -+ -+ /* Destroying our copy of clear-text passwords */ -+ memset(passwd, 0, 16); -+ -+ return (i < 16) ? 1 : 2; -+} -+ -+ -+/* -+ * Generate CHALLENGESIZE random bytes for use in challenge-response -+ * authentication. -+ */ -+ -+void -+vncRandomBytes(unsigned char *bytes) -+{ -+ int i; -+ unsigned int seed; -+ -+ if (!s_srandom_called) { -+ seed = (unsigned int)time(0) ^ (unsigned int)getpid(); -+ srandom(seed); -+ s_srandom_called = 1; -+ } -+ -+ for (i = 0; i < CHALLENGESIZE; i++) { -+ bytes[i] = (unsigned char)(random() & 255); -+ } -+} -+ -+ -+/* -+ * Encrypt CHALLENGESIZE bytes in memory using a password. -+ */ -+ -+void -+vncEncryptBytes(unsigned char *bytes, char *passwd) -+{ -+ unsigned char key[8]; -+ int i; -+ -+ /* key is simply password padded with nulls */ -+ -+ for (i = 0; i < 8; i++) { -+ if (i < strlen(passwd)) { -+ key[i] = passwd[i]; -+ } else { -+ key[i] = 0; -+ } -+ } -+ -+ deskey(key, EN0); -+ -+ for (i = 0; i < CHALLENGESIZE; i += 8) { -+ des(bytes+i, bytes+i); -+ } -+} -diff -pruN xorg-server-1.12.1.orig/hw/vnc/vncauth.h xorg-server-1.12.1/hw/vnc/vncauth.h ---- xorg-server-1.12.1.orig/hw/vnc/vncauth.h 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/vncauth.h 2012-04-18 14:45:21.586820829 -0500 -@@ -0,0 +1,33 @@ -+/* -+ * 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. -+ */ -+ -+/* -+ * vncauth.h - describes the functions provided by the vncauth library. -+ */ -+ -+#define MAXPWLEN 8 -+#define CHALLENGESIZE 16 -+ -+extern int vncEncryptAndStorePasswd(char *passwd, char *fname); -+extern char *vncDecryptPasswdFromFile(char *fname); -+extern void vncRandomBytes(unsigned char *bytes); -+extern void vncEncryptBytes(unsigned char *bytes, char *passwd); -+extern int vncEncryptAndStorePasswd2(char *passwd, char *passwdViewOnly, char *fname); -+extern int vncDecryptPasswdFromFile2(char *fname, char *passwdFullControl, char *passwdViewOnly); -+ -diff -pruN xorg-server-1.12.1.orig/hw/vnc/vncext.c xorg-server-1.12.1/hw/vnc/vncext.c ---- xorg-server-1.12.1.orig/hw/vnc/vncext.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/vncext.c 2012-04-18 15:30:57.637615484 -0500 -@@ -0,0 +1,794 @@ -+/* -+ * Copyright (C) 2002 Alan Hourihane. 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. -+ * -+ * Author: Alan Hourihane -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#include "rfb.h" -+#include "extnsionst.h" -+#define _VNC_SERVER -+#include -+#ifdef XFree86LOADER -+#include "xf86Module.h" -+#endif -+ -+#include -+#include -+#include -+#include -+ -+static DevPrivateKeyRec vncCreateScreenResourcesKeyRec; -+#define vncCreateScreenResourcesKey (&vncCreateScreenResourcesKeyRec) -+DevPrivateKeyRec rfbGCKeyRec; -+#define rfbGCKey (&rfbGCKeyRec) -+ -+int VncSelectNotify(ClientPtr client, BOOL onoff); -+void VncExtensionInit(void); -+ -+static int VncErrorBase; /* first vnc error number */ -+static int VncEventBase; /* first vnc event number */ -+ -+#define USE_ORIG_RES_CODE 0 -+ -+#if USE_ORIG_RES_CODE -+unsigned long VncResourceGeneration = 0; -+ -+static RESTYPE VncNotifyList; -+ -+static XID faked; -+ -+typedef struct _VncNotifyListRec { -+ struct _VncNotifyListRec *next; -+ ClientPtr client; -+} VncNotifyListRec, *VncNotifyListPtr; -+#endif -+ -+ -+/** -+ * Each X client that uses libVnc to talk to this extension will -+ * get recorded by one of these records. -+ */ -+typedef struct _VncClientRec { -+ ClientPtr client; -+ struct _VncClientRec *next; -+ XID fakeID; -+ RESTYPE res; -+} VncClientRec, *VncClientRecPtr; -+ -+static VncClientRecPtr ClientsList = NULL; -+ -+ -+/** -+ * Remove client record from list -+ */ -+static void -+VncRemoveClientRecord(ClientPtr client) -+{ -+ /* XXX need 'deleteresource' flag? */ -+ VncClientRecPtr p = ClientsList, prev = NULL; -+ rfbLog("%s client %p\n", __func__, (void *) client); -+ while (p) { -+ if (p->client == client) { -+ /* remove this one */ -+ if (prev) -+ prev->next = p->next; -+ else -+ ClientsList = p->next; -+ free(p); -+ return; -+ } -+ prev = p; -+ p = p->next; -+ } -+} -+ -+ -+/** -+ * This callback will be called by X's resource manager to delete the -+ * given resource. We create one resource for each client. When X -+ * deletes the resource, we know the client is going away. -+ */ -+static int -+VncDestroyClientResourceCallback(pointer pn, XID id) -+{ -+ VncClientRecPtr rec = (VncClientRecPtr) pn; -+ VncRemoveClientRecord(rec->client); -+ return Success; -+} -+ -+ -+/** -+ * Add a client record to the list of clients (unless already in list). -+ * We'll create a new, unique resource for this client. This is used -+ * to detect when an X client goes away. -+ */ -+static void -+VncSaveClientRecord(ClientPtr client) -+{ -+ VncClientRecPtr rec = ClientsList; -+ -+ rfbLog("%s saving client %p\n", __func__, (void *) client); -+ -+ /* look if already in list */ -+ while (rec) { -+ if (rec->client == client) { -+ return; /* already in list */ -+ } -+ rec = rec->next; -+ } -+ -+ /* allocate new client record */ -+ rec = (VncClientRecPtr) malloc(sizeof(VncClientRec)); -+ if (rec) { -+ rec->client = client; -+ rec->fakeID = FakeClientID(client->index); -+ rec->res = CreateNewResourceType(VncDestroyClientResourceCallback,"DestroyClientResourceCallback"); -+ if (!AddResource(rec->fakeID, rec->res, rec)) { -+ free(rec); -+ } -+ -+ /* insert at head of list */ -+ rec->next = ClientsList; -+ ClientsList = rec; -+ } -+} -+ -+ -+ -+static int -+ProcVncQueryVersion(ClientPtr client) -+{ -+ xVncQueryVersionReply rep; -+ -+ REQUEST_SIZE_MATCH(xVncQueryVersionReq); -+ rep.type = X_Reply; -+ rep.sequenceNumber = client->sequence; -+ rep.length = 0; -+ rep.majorVersion = VNC_MAJOR_VERSION; -+ rep.minorVersion = VNC_MINOR_VERSION; -+ if(client->swapped) -+ { -+ swaps(&rep.sequenceNumber); -+ swaps(&rep.majorVersion); -+ swaps(&rep.minorVersion); -+ } -+ (void)WriteToClient(client, SIZEOF(xVncQueryVersionReply), -+ (char *)&rep); -+ return (client->noClientException); -+} /* ProcVncQueryVersion */ -+ -+static int -+ProcVncConnection(ClientPtr client) -+{ -+ REQUEST(xVncConnectionReq); -+ xVncConnectionReply rep; -+ -+ rfbUserAllow( stuff->sock, stuff->accept ); -+ -+ REQUEST_SIZE_MATCH(xVncConnectionReq); -+ rep.type = X_Reply; -+ rep.sequenceNumber = client->sequence; -+ rep.length = 0; -+ rep.sock = 0; -+ rep.accept = 0; -+ if(client->swapped) -+ { -+ swaps(&rep.sequenceNumber); -+ swaps(&rep.sock); -+ swaps(&rep.accept); -+ } -+ (void)WriteToClient(client, SIZEOF(xVncConnectionReply), -+ (char *)&rep); -+ return (client->noClientException); -+} /* ProcVncConnection */ -+ -+static int -+ProcVncSelectNotify(ClientPtr client) -+{ -+ REQUEST(xVncSelectNotifyReq); -+ xVncSelectNotifyReply rep; -+ -+ VncSelectNotify(client, stuff->onoff); -+ -+ REQUEST_SIZE_MATCH(xVncSelectNotifyReq); -+ rep.type = X_Reply; -+ rep.sequenceNumber = client->sequence; -+ rep.length = 0; -+ if(client->swapped) -+ { -+ swaps(&rep.sequenceNumber); -+ } -+ (void)WriteToClient(client, SIZEOF(xVncSelectNotifyReply), -+ (char *)&rep); -+ return (client->noClientException); -+ -+} -+ -+static int -+ProcVncListConnections(ClientPtr client) -+{ -+ xVncListConnectionsReply rep; -+ rfbClientPtr cl; -+ int count = 0; -+ struct in_addr ipaddress; -+ xVncConnectionListInfo Info; -+ -+ /* count connections */ -+ for (cl = rfbClientHead; cl; cl = cl->next) -+#ifdef CHROMIUM -+ /* -+ * Fix this, as it should be generic, but we're only using it -+ * for Chromium at the moment, so we only list the connections -+ * that have a valid chromium encoding. We should be able to list -+ * any type requested. FIXME! XXXX -+ * See furthur down this function too!!! -+ */ -+ if (cl->enableChromiumEncoding) -+#endif -+ count++; -+ -+ REQUEST_SIZE_MATCH(xVncListConnectionsReq); -+ rep.type = X_Reply; -+ rep.sequenceNumber = client->sequence; -+ rep.count = count; -+ rep.length = count * sizeof(xVncConnectionListInfo) >> 2; -+ if(client->swapped) -+ { -+ swaps(&rep.sequenceNumber); -+ swapl(&rep.count); -+ } -+ (void)WriteToClient(client, SIZEOF(xVncListConnectionsReply), -+ (char *)&rep); -+ -+ for (cl = rfbClientHead; cl; cl = cl->next) { -+#ifdef CHROMIUM -+ /* -+ * Fix this, as it should be generic, but we're only using it -+ * for Chromium at the moment, so we only list the connections -+ * that have a valid chromium encoding. We should be able to list -+ * any type requested. FIXME! XXXX -+ */ -+ if (!cl->enableChromiumEncoding) -+ continue; -+#endif -+ inet_aton(cl->host, &ipaddress); -+ memcpy(&Info, &ipaddress, sizeof(struct in_addr)); -+ WriteToClient(client, SIZEOF(xVncConnectionListInfo), (char*)&Info); -+ } -+ -+ return (client->noClientException); -+} /* ProcVncListConnections */ -+ -+#ifdef CHROMIUM -+static int -+ProcVncChromiumStart(ClientPtr client) -+{ -+ REQUEST(xVncChromiumStartReq); -+ xVncChromiumStartReply rep; -+ -+ rfbSendChromiumStart(stuff->ipaddress, stuff->crServerPort, stuff->mothershipPort); -+ -+ REQUEST_SIZE_MATCH(xVncChromiumStartReq); -+ rep.type = X_Reply; -+ rep.sequenceNumber = client->sequence; -+ rep.length = 0; -+ if(client->swapped) -+ { -+ swaps(&rep.sequenceNumber); -+ } -+ (void)WriteToClient(client, SIZEOF(xVncChromiumStartReply), -+ (char *)&rep); -+ return (client->noClientException); -+} /* ProcVncChromiumStart */ -+ -+static int -+ProcVncChromiumMonitor(ClientPtr client) -+{ -+ REQUEST(xVncChromiumMonitorReq); -+ xVncChromiumMonitorReply rep; -+ -+ rfbChromiumMonitorWindowID(stuff->cr_windowid, stuff->windowid); -+ -+ REQUEST_SIZE_MATCH(xVncChromiumMonitorReq); -+ rep.type = X_Reply; -+ rep.sequenceNumber = client->sequence; -+ rep.length = 0; -+ if(client->swapped) -+ { -+ swaps(&rep.sequenceNumber); -+ } -+ (void)WriteToClient(client, SIZEOF(xVncChromiumMonitorReply), -+ (char *)&rep); -+ return (client->noClientException); -+} /* ProcVncChromiumMonitor */ -+#endif /* CHROMIUM */ -+ -+static int -+ProcVncDispatch(ClientPtr client) -+{ -+ REQUEST(xReq); -+ -+ switch (stuff->data) -+ { -+ case X_VncQueryVersion: -+ return ProcVncQueryVersion(client); -+ case X_VncSelectNotify: -+ return ProcVncSelectNotify(client); -+ case X_VncConnection: -+ return ProcVncConnection(client); -+ case X_VncListConnections: -+ return ProcVncListConnections(client); -+#ifdef CHROMIUM -+ case X_VncChromiumStart: -+ return ProcVncChromiumStart(client); -+ case X_VncChromiumMonitor: -+ return ProcVncChromiumMonitor(client); -+#endif -+ default: -+ return BadRequest; -+ } -+} /* ProcVncDispatch */ -+ -+static int -+SProcVncQueryVersion(ClientPtr client) -+{ -+ REQUEST(xVncQueryVersionReq); -+ -+ swaps(&stuff->length); -+ REQUEST_SIZE_MATCH(xVncQueryVersionReq); -+ swaps(&stuff->majorVersion); -+ swaps(&stuff->minorVersion); -+ return ProcVncQueryVersion(client); -+} /* SProcVncQueryVersion */ -+ -+static int -+SProcVncSelectNotify(ClientPtr client) -+{ -+ REQUEST(xVncSelectNotifyReq); -+ -+ swaps(&stuff->length); -+ REQUEST_SIZE_MATCH(xVncSelectNotifyReq); -+ return ProcVncSelectNotify(client); -+} /* SProcVncSelectNotify */ -+ -+static int -+SProcVncListConnections(ClientPtr client) -+{ -+ REQUEST(xVncListConnectionsReq); -+ -+ swaps(&stuff->length); -+ REQUEST_SIZE_MATCH(xVncListConnectionsReq); -+ return ProcVncListConnections(client); -+} /* SProcVncListConnections */ -+ -+#ifdef CHROMIUM -+static int -+SProcVncChromiumStart(ClientPtr client) -+{ -+ REQUEST(xVncChromiumStartReq); -+ -+ swapl(&stuff->ipaddress); -+ swapl(&stuff->crServerPort); -+ swapl(&stuff->mothershipPort); -+ swaps(&stuff->length); -+ REQUEST_SIZE_MATCH(xVncChromiumStartReq); -+ return ProcVncChromiumStart(client); -+} /* SProcVncChromiumStart */ -+ -+static int -+SProcVncChromiumMonitor(ClientPtr client) -+{ -+ REQUEST(xVncChromiumMonitorReq); -+ -+ swaps(&stuff->length); -+ swapl(&stuff->windowid); -+ swapl(&stuff->cr_windowid); -+ REQUEST_SIZE_MATCH(xVncChromiumMonitorReq); -+ return ProcVncChromiumMonitor(client); -+} /* SProcVncChromiumMonitor */ -+#endif /* CHROMIUM */ -+ -+static int -+SProcVncConnection(ClientPtr client) -+{ -+ REQUEST(xVncConnectionReq); -+ -+ swaps(&stuff->length); -+ REQUEST_SIZE_MATCH(xVncConnectionReq); -+ swaps(&stuff->sock); -+ swaps(&stuff->accept); -+ return ProcVncConnection(client); -+} /* SProcVncConnection */ -+ -+static int -+SProcVncDispatch(ClientPtr client) -+{ -+ REQUEST(xReq); -+ -+ switch (stuff->data) -+ { -+ case X_VncQueryVersion: -+ return SProcVncQueryVersion(client); -+ case X_VncSelectNotify: -+ return SProcVncSelectNotify(client); -+ case X_VncConnection: -+ return SProcVncConnection(client); -+ case X_VncListConnections: -+ return SProcVncListConnections(client); -+#ifdef CHROMIUM -+ case X_VncChromiumStart: -+ return SProcVncChromiumStart(client); -+ case X_VncChromiumMonitor: -+ return SProcVncChromiumMonitor(client); -+#endif -+ default: -+ return BadRequest; -+ } -+} /* SProcVncDispatch */ -+ -+static void -+SwapVncConnectedEvent(xVncConnectedEvent *from, xVncConnectedEvent *to) -+{ -+ to->type = from->type; -+ to->detail = from->detail; -+ cpswaps(from->sequenceNumber, to->sequenceNumber); -+ cpswapl(from->connected, to->connected); -+} -+ -+#ifdef CHROMIUM -+static void -+SwapVncChromiumConnectedEvent(xVncConnectedEvent *from, xVncConnectedEvent *to) -+{ -+ to->type = from->type; -+ to->detail = from->detail; -+ cpswaps(from->sequenceNumber, to->sequenceNumber); -+ cpswapl(from->connected, to->connected); -+} -+#endif -+ -+static void -+SwapVncDisconnectedEvent(xVncConnectedEvent *from, xVncConnectedEvent *to) -+{ -+ to->type = from->type; -+ to->detail = from->detail; -+ cpswaps(from->sequenceNumber, to->sequenceNumber); -+ cpswapl(from->connected, to->connected); -+} -+ -+int -+GenerateVncConnectedEvent(int sock) -+{ -+#if USE_ORIG_RES_CODE -+ VncNotifyListPtr pn; -+ -+ pn = (VncNotifyListPtr)LookupIDByType(faked, VncNotifyList); -+#else -+ VncClientRecPtr pn = ClientsList; -+#endif -+ -+ while (pn) -+ { -+ if (pn->client) -+ { -+ xVncConnectedEvent conn; -+ SOCKLEN_T peer_len; -+ struct sockaddr_in peer; -+ -+ conn.type = VncEventBase + XVncConnected; -+ conn.sequenceNumber = pn->client->sequence; -+ conn.connected = sock; -+ -+ peer_len = sizeof(peer); -+ if (getpeername(sock, (struct sockaddr *) &peer, &peer_len) == -1) -+ conn.ipaddress = 0; -+ else -+ conn.ipaddress = (CARD32)peer.sin_addr.s_addr; -+ -+ (void) TryClientEvents(pn->client, NULL, (xEventPtr)&conn, 1, NoEventMask, -+ NoEventMask, NullGrab); -+ } -+ pn = pn->next; -+ } -+ -+ return 1; -+} -+ -+ -+ -+#ifdef CHROMIUM -+int -+GenerateVncChromiumConnectedEvent(int sock) -+{ -+#if USE_ORIG_RES_CODE -+ VncNotifyListPtr pn; -+ pn = (VncNotifyListPtr)LookupIDByType(faked, VncNotifyList); -+#else -+ VncClientRecPtr pn = ClientsList; -+#endif -+ rfbLog("Enter GenerateVncChromiumConnectedEvent\n"); -+ while (pn) -+ { -+ if (pn->client) -+ { -+ xVncConnectedEvent conn; -+ SOCKLEN_T peer_len; -+ struct sockaddr_in peer; -+ -+ rfbLog("Sending XVncChromiumConnected to client %p\n", -+ (void *) pn->client); -+ -+ conn.type = VncEventBase + XVncChromiumConnected; -+ conn.sequenceNumber = pn->client->sequence; -+ conn.connected = sock; -+ -+ peer_len = sizeof(peer); -+ if (getpeername(sock, (struct sockaddr *)&peer, &peer_len) == -1) -+ conn.ipaddress = 0; -+ else -+ conn.ipaddress = (CARD32)peer.sin_addr.s_addr; -+ -+ (void) TryClientEvents(pn->client, NULL, (xEventPtr)&conn, 1, NoEventMask, -+ NoEventMask, NullGrab); -+ } -+ pn = pn->next; -+ } -+ return 1; -+} -+#endif /* CHROMIUM */ -+ -+ -+int -+GenerateVncDisconnectedEvent(int sock) -+{ -+#if USE_ORIG_RES_CODE -+ VncNotifyListPtr pn; -+ -+ pn = (VncNotifyListPtr)LookupIDByType(faked, VncNotifyList); -+#else -+ VncClientRecPtr pn = ClientsList; -+#endif -+ rfbLog("GenerateVncDisconnectedEvent\n"); -+ while (pn) -+ { -+ if (pn->client) -+ { -+ xVncDisconnectedEvent conn; -+ conn.type = VncEventBase + XVncDisconnected; -+ conn.sequenceNumber = pn->client->sequence; -+ conn.connected = sock; -+ (void) TryClientEvents(pn->client, NULL, (xEventPtr)&conn, 1, NoEventMask, -+ NoEventMask, NullGrab); -+ } -+ pn = pn->next; -+ } -+ -+ return 1; -+} -+ -+static void -+VncResetProc(ExtensionEntry *extEntry) -+{ -+} /* VncResetProc */ -+ -+ -+ -+/** -+ * When the app calls libVnc's XVncSelectNotify() we wind up here. -+ * Either add or remove 'client' from the VncNotifyList depending on 'onoff'. -+ */ -+int -+VncSelectNotify(ClientPtr client, BOOL onoff) -+{ -+#if USE_ORIG_RES_CODE -+ VncNotifyListPtr head, newRec, tmp, freeRec = NULL; -+ -+ rfbLog("%s client %p onoff=%d\n", __func__, (void *) client, (int) onoff); -+ if (!faked) -+ faked = FakeClientID(client->index); -+#else -+ /* ignore onoff param */ -+ VncSaveClientRecord(client); -+#endif -+ -+#if USE_ORIG_RES_CODE -+ /* Get the first VncNotifyListPtr */ -+ head = (VncNotifyListPtr) LookupIDByType(faked, VncNotifyList); -+ -+ /* search list for this client */ -+ tmp = head; -+ while (tmp) { -+ if (tmp->client == client) { -+ /* found client! */ -+ if (!onoff) -+ tmp->client = NULL; -+ return Success; -+ } -+ if (!tmp->client) -+ freeRec = tmp; /* save ptr to free record */ -+ tmp = tmp->next; -+ } -+ -+ /* if we get here, we didn't find client in the list */ -+ -+ if (!onoff) { -+ /* if turning off non-existing client, just return */ -+ return Success; -+ } -+ -+ /* OK, add new client to list now */ -+ -+ if (freeRec) { -+ /* re-using a free spot */ -+ freeRec->client = client; -+ return Success; -+ } -+ -+ /* need to allocate new node */ -+ if (!(newRec = (VncNotifyListPtr)xalloc(sizeof(VncNotifyListRec)))) -+ return BadAlloc; -+ /* insert at head, just as AddResource() does!!! */ -+ newRec->next = head; -+ newRec->client = client; -+ if (!AddResource(faked, VncNotifyList, newRec)) { -+ free(newRec); -+ return BadAlloc; -+ } -+#endif -+ return Success; -+} -+ -+ -+#if USE_ORIG_RES_CODE -+static int -+VncDestroyNotifyList(pointer pn, XID id) -+{ -+ VncNotifyListPtr cpn = (VncNotifyListPtr) pn; -+ rfbLog("%s client %p\n", __func__, (void *) cpn->client); -+ cpn->client = NULL; -+ return Success; -+} -+#endif -+ -+static Bool -+CreateResourceTypes(void) -+{ -+#if USE_ORIG_RES_CODE -+ if (VncResourceGeneration == serverGeneration) -+ return TRUE; -+ -+ VncResourceGeneration = serverGeneration; -+ -+ if (!(VncNotifyList = CreateNewResourceType(VncDestroyNotifyList,"DestroyNotifyList"))) { -+ ErrorF("CreateResourceTypes: failed to allocate vnc notify list resource.\n"); -+ return FALSE; -+ } -+#endif -+ return TRUE; -+} -+ -+ -+ -+static unsigned long vncExtGeneration = 0; -+#if XFREE86VNC -+extern Bool VNCInit(ScreenPtr pScreen, unsigned char *FBStart); -+ -+/* copied from miscrinit.c */ -+typedef struct -+{ -+ pointer pbits; /* pointer to framebuffer */ -+ int width; /* delta to add to a framebuffer addr to move one row down */ -+} miScreenInitParmsRec, *miScreenInitParmsPtr; -+ -+ -+static Bool -+vncCreateScreenResources(ScreenPtr pScreen) -+{ -+ int ret = TRUE; -+ CreateScreenResourcesProcPtr CreateScreenResources = -+ (CreateScreenResourcesProcPtr) -+ dixLookupPrivate(&pScreen->devPrivates, vncCreateScreenResourcesKey); -+ miScreenInitParmsPtr pScrInitParms; -+ -+ pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate; -+ -+ if ( pScreen->CreateScreenResources != vncCreateScreenResources ) { -+ /* Can't find hook we are hung on */ -+ xf86DrvMsg(pScreen->myNum, X_WARNING /* X_ERROR */, -+ "vncCreateScreenResources %p called when not in " -+ "pScreen->CreateScreenResources %p n", -+ (void *) vncCreateScreenResources, -+ (void *) pScreen->CreateScreenResources ); -+ } -+ -+ /* Now do our stuff */ -+ VNCInit(pScreen, pScrInitParms->pbits); -+ -+ /* Unhook this function ... */ -+ pScreen->CreateScreenResources = CreateScreenResources; -+ dixSetPrivate(&pScreen->devPrivates, vncCreateScreenResourcesKey, NULL); -+ -+ /* ... and call the previous CreateScreenResources fuction, if any */ -+ if (pScreen->CreateScreenResources) { -+ ret = (*pScreen->CreateScreenResources)(pScreen); -+ } -+ -+#ifdef DEBUG -+ ErrorF("vncCreateScreenResources() returns %d\n", ret); -+#endif -+ return ret; -+} -+#endif -+ -+ -+ -+void -+VncExtensionInit(void) -+{ -+ ExtensionEntry *extEntry; -+#if XFREE86VNC -+ int i; -+#endif -+ if (vncExtGeneration != serverGeneration) { -+ -+ vncExtGeneration = serverGeneration; -+ -+ // doesn't seem to be valid any more - mhopf 21.12.2010 -+ // no allocation needed for screen privates -+ if (!dixRegisterPrivateKey(vncCreateScreenResourcesKey, PRIVATE_SCREEN, 0)) -+ return; -+ -+ if (!dixRegisterPrivateKey(rfbGCKey, PRIVATE_GC, sizeof(rfbGCRec))) -+ return; -+ -+#if XFREE86VNC -+ for (i = 0 ; i < screenInfo.numScreens; i++) -+ { -+ dixSetPrivate(&screenInfo.screens[i]->devPrivates, -+ vncCreateScreenResourcesKey, -+ xf86Screens[i]->pScreen->CreateScreenResources); -+ xf86Screens[i]->pScreen->CreateScreenResources = vncCreateScreenResources; -+ } -+#endif -+ -+ gethostname(rfbThisHost, 255); -+ } -+ -+ if (!CreateResourceTypes()) -+ return; -+ -+ extEntry = AddExtension(VNC_EXTENSION_NAME, -+ XVncNumberEvents, XVncNumberErrors, -+ ProcVncDispatch, SProcVncDispatch, -+ VncResetProc, StandardMinorOpcode); -+ -+ VncErrorBase = extEntry->errorBase; -+ VncEventBase = extEntry->eventBase; -+ -+ EventSwapVector[VncEventBase + XVncConnected] = -+ (EventSwapPtr)SwapVncConnectedEvent; -+ EventSwapVector[VncEventBase + XVncDisconnected] = -+ (EventSwapPtr)SwapVncDisconnectedEvent; -+#ifdef CHROMIUM -+ EventSwapVector[VncEventBase + XVncChromiumConnected] = -+ (EventSwapPtr)SwapVncChromiumConnectedEvent; -+#endif -+} /* VncExtensionInit */ -diff -pruN xorg-server-1.12.1.orig/hw/vnc/xistubs.c xorg-server-1.12.1/hw/vnc/xistubs.c ---- xorg-server-1.12.1.orig/hw/vnc/xistubs.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/xistubs.c 2012-04-18 14:45:21.587820816 -0500 -@@ -0,0 +1,312 @@ -+/* $Xorg: stubs.c,v 1.4 2001/02/09 02:04:35 xorgcvs Exp $ */ -+ -+/************************************************************ -+ -+Copyright 1989, 1998 The Open Group -+ -+Permission to use, copy, modify, distribute, and sell this software and its -+documentation for any purpose is hereby granted without fee, provided that -+the above copyright notice appear in all copies and that both that -+copyright notice and this permission notice appear in supporting -+documentation. -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+Except as contained in this notice, the name of The Open Group shall not be -+used in advertising or otherwise to promote the sale, use or other dealings -+in this Software without prior written authorization from The Open Group. -+ -+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California. -+ -+ All Rights Reserved -+ -+Permission to use, copy, modify, and distribute this software and its -+documentation for any purpose and without fee is hereby granted, -+provided that the above copyright notice appear in all copies and that -+both that copyright notice and this permission notice appear in -+supporting documentation, and that the name of Hewlett-Packard not be -+used in advertising or publicity pertaining to distribution of the -+software without specific, written prior permission. -+ -+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -+HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -+SOFTWARE. -+ -+********************************************************/ -+/* $XFree86: xc/programs/Xserver/Xi/stubs.c,v 3.3 2001/01/17 22:13:26 dawes Exp $ */ -+ -+/* -+ * stubs.c -- stub routines for the X server side of the XINPUT -+ * extension. This file is mainly to be used only as documentation. -+ * There is not much code here, and you can't get a working XINPUT -+ * server just using this. -+ * The Xvfb server uses this file so it will compile with the same -+ * object files as the real X server for a platform that has XINPUT. -+ * Xnest could do the same thing. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#define NEED_EVENTS -+#include -+#include -+#include -+#include -+#include "inputstr.h" -+#include "XIstubs.h" -+#include "../dmxvnc.h" -+ -+/*********************************************************************** -+ * -+ * Caller: ProcXChangeKeyboardDevice -+ * -+ * This procedure does the implementation-dependent portion of the work -+ * needed to change the keyboard device. -+ * -+ * The X keyboard device has a FocusRec. If the device that has been -+ * made into the new X keyboard did not have a FocusRec, -+ * ProcXChangeKeyboardDevice will allocate one for it. -+ * -+ * If you do not want clients to be able to focus the old X keyboard -+ * device, call DeleteFocusClassDeviceStruct to free the FocusRec. -+ * -+ * If you support input devices with keys that you do not want to be -+ * used as the X keyboard, you need to check for them here and return -+ * a BadDevice error. -+ * -+ * The default implementation is to do nothing (assume you do want -+ * clients to be able to focus the old X keyboard). The commented-out -+ * sample code shows what you might do if you don't want the default. -+ * -+ */ -+ -+int -+ChangeKeyboardDevice (DeviceIntPtr old_dev, -+ DeviceIntPtr new_dev) -+ { -+ /*********************************************************************** -+ DeleteFocusClassDeviceStruct(old_dev); * defined in xchgptr.c * -+ **********************************************************************/ -+ return BadMatch; -+ } -+ -+ -+/*********************************************************************** -+ * -+ * Caller: ProcXChangePointerDevice -+ * -+ * This procedure does the implementation-dependent portion of the work -+ * needed to change the pointer device. -+ * -+ * The X pointer device does not have a FocusRec. If the device that -+ * has been made into the new X pointer had a FocusRec, -+ * ProcXChangePointerDevice will free it. -+ * -+ * If you want clients to be able to focus the old pointer device that -+ * has now become accessible through the input extension, you need to -+ * add a FocusRec to it here. -+ * -+ * The XChangePointerDevice protocol request also allows the client -+ * to choose which axes of the new pointer device are used to move -+ * the X cursor in the X- and Y- directions. If the axes are different -+ * than the default ones, you need to keep track of that here. -+ * -+ * If you support input devices with valuators that you do not want to be -+ * used as the X pointer, you need to check for them here and return a -+ * BadDevice error. -+ * -+ * The default implementation is to do nothing (assume you don't want -+ * clients to be able to focus the old X pointer). The commented-out -+ * sample code shows what you might do if you don't want the default. -+ * -+ */ -+ -+int -+ChangePointerDevice ( -+ DeviceIntPtr old_dev, -+ DeviceIntPtr new_dev, -+ unsigned char x, -+ unsigned char y) -+ { -+ /*********************************************************************** -+ InitFocusClassDeviceStruct(old_dev); * allow focusing old ptr* -+ -+ x_axis = x; * keep track of new x-axis* -+ y_axis = y; * keep track of new y-axis* -+ if (x_axis != 0 || y_axis != 1) -+ axes_changed = TRUE; * remember axes have changed* -+ else -+ axes_changed = FALSE; -+ *************************************************************************/ -+ return BadMatch; -+ } -+#if 0 -+/*********************************************************************** -+ * -+ * Caller: ProcXCloseDevice -+ * -+ * Take care of implementation-dependent details of closing a device. -+ * Some implementations may actually close the device, others may just -+ * remove this clients interest in that device. -+ * -+ * The default implementation is to do nothing (assume all input devices -+ * are initialized during X server initialization and kept open). -+ * -+ */ -+ -+static void -+CloseInputDevice (DeviceIntPtr d, -+ ClientPtr client) -+ { -+ } -+#endif -+/*********************************************************************** -+ * -+ * Caller: ProcXListInputDevices -+ * -+ * This is the implementation-dependent routine to initialize an input -+ * device to the point that information about it can be listed. -+ * Some implementations open all input devices when the server is first -+ * initialized, and never close them. Other implementations open only -+ * the X pointer and keyboard devices during server initialization, -+ * and only open other input devices when some client makes an -+ * XOpenDevice request. If some other process has the device open, the -+ * server may not be able to get information about the device to list it. -+ * -+ * This procedure should be used by implementations that do not initialize -+ * all input devices at server startup. It should do device-dependent -+ * initialization for any devices not previously initialized, and call -+ * AddInputDevice for each of those devices so that a DeviceIntRec will be -+ * created for them. -+ * -+ * The default implementation is to do nothing (assume all input devices -+ * are initialized during X server initialization and kept open). -+ * The commented-out sample code shows what you might do if you don't want -+ * the default. -+ * -+ */ -+#if 0 -+static void -+AddOtherInputDevices (void) -+ { -+ /********************************************************************** -+ for each uninitialized device, do something like: -+ -+ DeviceIntPtr dev; -+ DeviceProc deviceProc; -+ pointer private; -+ -+ dev = (DeviceIntPtr) AddInputDevice(deviceProc, TRUE); -+ dev->public.devicePrivate = private; -+ RegisterOtherDevice(dev); -+ dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success); -+ ************************************************************************/ -+ -+ } -+#endif -+/*********************************************************************** -+ * -+ * Caller: ProcXOpenDevice -+ * -+ * This is the implementation-dependent routine to open an input device. -+ * Some implementations open all input devices when the server is first -+ * initialized, and never close them. Other implementations open only -+ * the X pointer and keyboard devices during server initialization, -+ * and only open other input devices when some client makes an -+ * XOpenDevice request. This entry point is for the latter type of -+ * implementation. -+ * -+ * If the physical device is not already open, do it here. In this case, -+ * you need to keep track of the fact that one or more clients has the -+ * device open, and physically close it when the last client that has -+ * it open does an XCloseDevice. -+ * -+ * The default implementation is to do nothing (assume all input devices -+ * are opened during X server initialization and kept open). -+ * -+ */ -+#if 0 -+static void -+OpenInputDevice (DeviceIntPtr dev, -+ ClientPtr client, -+ int *status) -+ { -+ } -+#endif -+/**************************************************************************** -+ * -+ * Caller: ProcXSetDeviceMode -+ * -+ * Change the mode of an extension device. -+ * This function is used to change the mode of a device from reporting -+ * relative motion to reporting absolute positional information, and -+ * vice versa. -+ * The default implementation below is that no such devices are supported. -+ * -+ */ -+ -+int -+SetDeviceMode (register ClientPtr client, -+ DeviceIntPtr dev, -+ int mode) -+ { -+ return BadMatch; -+ } -+ -+/**************************************************************************** -+ * -+ * Caller: ProcXSetDeviceValuators -+ * -+ * Set the value of valuators on an extension input device. -+ * This function is used to set the initial value of valuators on -+ * those input devices that are capable of reporting either relative -+ * motion or an absolute position, and allow an initial position to be set. -+ * The default implementation below is that no such devices are supported. -+ * -+ */ -+ -+int -+SetDeviceValuators (register ClientPtr client, -+ DeviceIntPtr dev, -+ int *valuators, -+ int first_valuator, -+ int num_valuators) -+ { -+ return BadMatch; -+ } -+ -+/**************************************************************************** -+ * -+ * Caller: ProcXChangeDeviceControl -+ * -+ * Change the specified device controls on an extension input device. -+ * -+ */ -+ -+int -+ChangeDeviceControl (register ClientPtr client, -+ DeviceIntPtr dev, -+ xDeviceCtl *control) -+ { -+ switch (control->control) -+ { -+ case DEVICE_RESOLUTION: -+ return (BadMatch); -+ default: -+ return (BadMatch); -+ } -+ } -diff -pruN xorg-server-1.12.1.orig/hw/vnc/zlib.c xorg-server-1.12.1/hw/vnc/zlib.c ---- xorg-server-1.12.1.orig/hw/vnc/zlib.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/vnc/zlib.c 2012-04-18 14:45:21.587820816 -0500 -@@ -0,0 +1,308 @@ -+/* -+ * zlib.c -+ * -+ * Routines to implement zlib based encoding (deflate). -+ * -+ * Modified for XFree86 4.x by Alan Hourihane -+ */ -+ -+/* -+ * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. -+ * 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. -+ * -+ * For the latest source code, please check: -+ * -+ * http://www.developVNC.org/ -+ * -+ * or send email to feedback@developvnc.org. -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+ -+#include -+#include "rfb.h" -+ -+/* -+ * zlibBeforeBuf contains pixel data in the client's format. -+ * zlibAfterBuf contains the zlib (deflated) encoding version. -+ * If the zlib compressed/encoded version is -+ * larger than the raw data or if it exceeds zlibAfterBufSize then -+ * raw encoding is used instead. -+ */ -+ -+static int zlibBeforeBufSize = 0; -+static unsigned char *zlibBeforeBuf = NULL; -+ -+static int zlibAfterBufSize = 0; -+static unsigned char *zlibAfterBuf = NULL; -+static int zlibAfterBufLen; -+ -+/* -+ * rfbSendOneRectEncodingZlib - send a given rectangle using one Zlib -+ * rectangle encoding. -+ */ -+ -+static Bool -+rfbSendOneRectEncodingZlib(rfbClientPtr cl, -+ int x, int y, int w, int h) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ rfbFramebufferUpdateRectHeader rect; -+ rfbZlibHeader hdr; -+ int deflateResult; -+ int previousOut; -+ int i; -+ int maxRawSize; -+ int maxCompSize; -+ -+ maxRawSize = (pVNC->width * pVNC->height -+ * (cl->format.bitsPerPixel / 8)); -+ -+ if (zlibBeforeBufSize < maxRawSize) { -+ zlibBeforeBufSize = maxRawSize; -+ if (zlibBeforeBuf == NULL) -+ zlibBeforeBuf = (unsigned char *)malloc(zlibBeforeBufSize); -+ else -+ zlibBeforeBuf = (unsigned char *)realloc(zlibBeforeBuf, zlibBeforeBufSize); -+ } -+ -+ /* zlib compression is not useful for very small data sets. -+ * So, we just send these raw without any compression. -+ */ -+ if (( w * h * (pVNC->bitsPerPixel / 8)) < -+ VNC_ENCODE_ZLIB_MIN_COMP_SIZE ) { -+ -+ int result; -+ -+ /* The translation function (used also by the in raw encoding) -+ * requires 4/2/1 byte alignment in the output buffer (which is -+ * pVNC->updateBuf for the raw encoding) based on the bitsPerPixel of -+ * the viewer/client. This prevents SIGBUS errors on some -+ * architectures like SPARC, PARISC... -+ */ -+ if (( cl->format.bitsPerPixel > 8 ) && -+ ( pVNC->ublen % ( cl->format.bitsPerPixel / 8 )) != 0 ) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ result = rfbSendRectEncodingRaw(cl, x, y, w, h); -+ -+ return result; -+ -+ } -+ -+ /* -+ * zlib requires output buffer to be slightly larger than the input -+ * buffer, in the worst case. -+ */ -+ maxCompSize = maxRawSize + (( maxRawSize + 99 ) / 100 ) + 12; -+ -+ if (zlibAfterBufSize < maxCompSize) { -+ zlibAfterBufSize = maxCompSize; -+ if (zlibAfterBuf == NULL) -+ zlibAfterBuf = (unsigned char *)malloc(zlibAfterBufSize); -+ else -+ zlibAfterBuf = (unsigned char *)realloc(zlibAfterBuf, zlibAfterBufSize); -+ } -+ -+ /* -+ * Convert pixel data to client format. -+ */ -+ (*cl->translateFn)(cl->pScreen, cl->translateLookupTable, -+ &pVNC->rfbServerFormat, -+ &cl->format, zlibBeforeBuf, -+ pVNC->paddedWidthInBytes, w, h, x, y); -+ -+ cl->compStream.next_in = ( Bytef * )zlibBeforeBuf; -+ cl->compStream.avail_in = w * h * (cl->format.bitsPerPixel / 8); -+ cl->compStream.next_out = ( Bytef * )zlibAfterBuf; -+ cl->compStream.avail_out = maxCompSize; -+ cl->compStream.data_type = Z_BINARY; -+ -+ /* Initialize the deflation state. */ -+ if ( cl->compStreamInited == FALSE ) { -+ -+ cl->compStream.total_in = 0; -+ cl->compStream.total_out = 0; -+ cl->compStream.zalloc = Z_NULL; -+ cl->compStream.zfree = Z_NULL; -+ cl->compStream.opaque = Z_NULL; -+ -+ deflateInit2( &(cl->compStream), -+ cl->zlibCompressLevel, -+ Z_DEFLATED, -+ MAX_WBITS, -+ MAX_MEM_LEVEL, -+ Z_DEFAULT_STRATEGY ); -+ /* deflateInit( &(cl->compStream), Z_BEST_COMPRESSION ); */ -+ /* deflateInit( &(cl->compStream), Z_BEST_SPEED ); */ -+ cl->compStreamInited = TRUE; -+ -+ } -+ -+ previousOut = cl->compStream.total_out; -+ -+ /* Perform the compression here. */ -+ deflateResult = deflate( &(cl->compStream), Z_SYNC_FLUSH ); -+ -+ /* Find the total size of the resulting compressed data. */ -+ zlibAfterBufLen = cl->compStream.total_out - previousOut; -+ -+ if ( deflateResult != Z_OK ) { -+ rfbLog("zlib deflation error: %s\n", cl->compStream.msg); -+ return FALSE; -+ } -+ -+ /* Note that it is not possible to switch zlib parameters based on -+ * the results of the compression pass. The reason is -+ * that we rely on the compressor and decompressor states being -+ * in sync. Compressing and then discarding the results would -+ * cause lose of synchronization. -+ */ -+ -+ /* Update statics */ -+ cl->rfbRectanglesSent[rfbEncodingZlib]++; -+ cl->rfbBytesSent[rfbEncodingZlib] += (sz_rfbFramebufferUpdateRectHeader -+ + sz_rfbZlibHeader + zlibAfterBufLen); -+ -+ if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader -+ > UPDATE_BUF_SIZE) -+ { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ -+ rect.r.x = Swap16IfLE(x); -+ rect.r.y = Swap16IfLE(y); -+ rect.r.w = Swap16IfLE(w); -+ rect.r.h = Swap16IfLE(h); -+ rect.encoding = Swap32IfLE(rfbEncodingZlib); -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect, -+ sz_rfbFramebufferUpdateRectHeader); -+ pVNC->ublen += sz_rfbFramebufferUpdateRectHeader; -+ -+ hdr.nBytes = Swap32IfLE(zlibAfterBufLen); -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&hdr, sz_rfbZlibHeader); -+ pVNC->ublen += sz_rfbZlibHeader; -+ -+ for (i = 0; i < zlibAfterBufLen;) { -+ -+ int bytesToCopy = UPDATE_BUF_SIZE - pVNC->ublen; -+ -+ if (i + bytesToCopy > zlibAfterBufLen) { -+ bytesToCopy = zlibAfterBufLen - i; -+ } -+ -+ memcpy(&pVNC->updateBuf[pVNC->ublen], &zlibAfterBuf[i], bytesToCopy); -+ -+ pVNC->ublen += bytesToCopy; -+ i += bytesToCopy; -+ -+ if (pVNC->ublen == UPDATE_BUF_SIZE) { -+ if (!rfbSendUpdateBuf(cl)) -+ return FALSE; -+ } -+ } -+ -+ return TRUE; -+ -+} -+ -+ -+/* -+ * rfbSendRectEncodingZlib - send a given rectangle using one or more -+ * Zlib encoding rectangles. -+ */ -+ -+Bool -+rfbSendRectEncodingZlib(rfbClientPtr cl, -+ int x, int y, int w, int h) -+{ -+ VNCSCREENPTR(cl->pScreen); -+ int maxLines; -+ int linesRemaining; -+ rfbRectangle partialRect; -+ -+ partialRect.x = x; -+ partialRect.y = y; -+ partialRect.w = w; -+ partialRect.h = h; -+ -+ /* Determine maximum pixel/scan lines allowed per rectangle. */ -+ maxLines = ( ZLIB_MAX_SIZE(w) / w ); -+ -+ /* Initialize number of scan lines left to do. */ -+ linesRemaining = h; -+ -+ /* Loop until all work is done. */ -+ while ( linesRemaining > 0 ) { -+ -+ int linesToComp; -+ -+ if ( maxLines < linesRemaining ) -+ linesToComp = maxLines; -+ else -+ linesToComp = linesRemaining; -+ -+ partialRect.h = linesToComp; -+ -+ /* Encode (compress) and send the next rectangle. */ -+ if ( ! rfbSendOneRectEncodingZlib( cl, -+ partialRect.x, -+ partialRect.y, -+ partialRect.w, -+ partialRect.h )) { -+ -+ return FALSE; -+ } -+ -+ /* Technically, flushing the buffer here is not extrememly -+ * efficient. However, this improves the overall throughput -+ * of the system over very slow networks. By flushing -+ * the buffer with every maximum size zlib rectangle, we -+ * improve the pipelining usage of the server CPU, network, -+ * and viewer CPU components. Insuring that these components -+ * are working in parallel actually improves the performance -+ * seen by the user. -+ * Since, zlib is most useful for slow networks, this flush -+ * is appropriate for the desired behavior of the zlib encoding. -+ */ -+ if (( pVNC->ublen > 0 ) && -+ ( linesToComp == maxLines )) { -+ if (!rfbSendUpdateBuf(cl)) { -+ -+ return FALSE; -+ } -+ } -+ -+ /* Update remaining and incremental rectangle location. */ -+ linesRemaining -= linesToComp; -+ partialRect.y += linesToComp; -+ -+ } -+ -+ return TRUE; -+ -+} -+ -+ -diff --git a/hw/xfree86/dixmods/Makefile.am b/hw/xfree86/dixmods/Makefile.am -index f161db6..1e075f8 100644 ---- a/hw/xfree86/dixmods/Makefile.am -+++ b/hw/xfree86/dixmods/Makefile.am -@@ -4,19 +4,29 @@ if GLX - GLXMODS = libglx.la - endif - -+if XCLIPLIST -+XCLIPLISTMOD = libxcliplist.la -+endif -+ - module_LTLIBRARIES = libfb.la \ - libwfb.la \ - libshadow.la - - extsmoduledir = $(moduledir)/extensions --extsmodule_LTLIBRARIES = $(GLXMODS) -+extsmodule_LTLIBRARIES = $(GLXMODS) \ -+ $(XCLIPLISTMOD) - - AM_CFLAGS = @XORG_CFLAGS@ @DIX_CFLAGS@ - INCLUDES = @XORG_INCS@ \ -+ -I$(top_srcdir)/xcliplist \ - -I$(top_srcdir)/hw/xfree86/loader \ - -I$(top_srcdir)/miext/shadow \ - -I$(top_srcdir)/glx - -+libxcliplist_la_LDFLAGS = -avoid-version -+libxcliplist_la_LIBADD = $(top_builddir)/xcliplist/libxcliplist.la -+libxcliplist_la_SOURCES = $(top_srcdir)/xcliplist/cliplistmod.c -+ - libfb_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) - libfb_la_LIBADD = $(top_builddir)/fb/libfb.la - libfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c --- -diff -pruN xorg-server-1.12.1.orig/hw/xfree86/Makefile.am xorg-server-1.12.1/hw/xfree86/Makefile.am ---- xorg-server-1.12.1.orig/hw/xfree86/Makefile.am 2012-03-30 22:04:18.000000000 -0500 -+++ xorg-server-1.12.1/hw/xfree86/Makefile.am 2012-04-18 14:45:21.587820816 -0500 -@@ -35,6 +35,11 @@ DIST_SUBDIRS = common ddc i2c x86emu int - loader dixmods dri dri2 exa modes \ - utils doc man - -+if VNC -+SUBDIRS += vnc -+DIST_SUBDIRS += vnc -+endif -+ - bin_PROGRAMS = Xorg - nodist_Xorg_SOURCES = sdksyms.c - -diff -pruN xorg-server-1.12.1.orig/hw/xfree86/vnc/.gitignore xorg-server-1.12.1/hw/xfree86/vnc/.gitignore ---- xorg-server-1.12.1.orig/hw/xfree86/vnc/.gitignore 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/xfree86/vnc/.gitignore 2012-04-18 14:45:21.588820803 -0500 -@@ -0,0 +1,36 @@ -+auth.c -+cmap.c -+corre.c -+cursor.c -+cutpaste.c -+d3des.c -+d3des.h -+dispcur.c -+draw.c -+hextile.c -+httpd.c -+kbdptr.c -+keyboard.h -+loginauth.c -+rdp.c -+rfb.h -+rfbkeyb.c -+rfbmouse.c -+rfbproto.h -+rfbserver.c -+rre.c -+sockets.c -+sprite.c -+sprite.h -+spritest.h -+stats.c -+tableinitcmtemplate.c -+tableinittctemplate.c -+tabletranstemplate.c -+tight.c -+translate.c -+vncauth.c -+vncauth.h -+vncext.c -+xistubs.c -+zlib.c -diff -pruN xorg-server-1.12.1.orig/hw/xfree86/vnc/Makefile.am xorg-server-1.12.1/hw/xfree86/vnc/Makefile.am ---- xorg-server-1.12.1.orig/hw/xfree86/vnc/Makefile.am 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/xfree86/vnc/Makefile.am 2012-04-18 14:45:21.588820803 -0500 -@@ -0,0 +1,51 @@ -+AM_CFLAGS = $(DIX_CFLAGS) -+ -+libvnc_la_LTLIBRARIES = libvnc.la -+libvnc_la_CFLAGS = -I$(top_srcdir)/hw/xfree86/common \ -+ -I$(top_srcdir)/hw/xfree86/os-support \ -+ -I$(top_srcdir)/hw/xfree86/os-support/bus \ -+ -I$(top_srcdir)/mi \ -+ -I$(top_srcdir)/render \ -+ -I$(top_srcdir)/GL/glx \ -+ -I$(top_srcdir)/GL/include \ -+ -I$(top_builddir)/GL/include \ -+ -I@MESA_SOURCE@/include \ -+ -DHAVE_XORG_CONFIG_H \ -+ -DHAVE_DIX_CONFIG_H \ -+ -DXFree86LOADER \ -+ -DXFREE86VNC=1 \ -+ -DCHROMIUM=1 \ -+ $(AM_CFLAGS) -+ -+libvnc_la_LIBADD = -ljpeg -lcrypt -+libvnc_la_LDFLAGS = -module -avoid-version -+libvnc_ladir = $(moduledir)/extensions -+libvnc_la_SOURCES = \ -+ auth.c \ -+ cmap.c \ -+ corre.c \ -+ cursor.c \ -+ cutpaste.c \ -+ d3des.c \ -+ dispcur.c \ -+ draw.c \ -+ hextile.c \ -+ httpd.c \ -+ kbdptr.c \ -+ loginauth.c \ -+ rdp.c \ -+ rfbkeyb.c \ -+ rfbmouse.c \ -+ rfbserver.c \ -+ rre.c \ -+ sockets.c \ -+ sprite.c \ -+ stats.c \ -+ tight.c \ -+ translate.c \ -+ vncInit.c \ -+ vncauth.c \ -+ vncext.c \ -+ zlib.c -+ -+#sdk_HEADERS = vncint.h -diff -pruN xorg-server-1.12.1.orig/hw/xfree86/vnc/README xorg-server-1.12.1/hw/xfree86/vnc/README ---- xorg-server-1.12.1.orig/hw/xfree86/vnc/README 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/xfree86/vnc/README 2012-04-18 14:45:21.588820803 -0500 -@@ -0,0 +1 @@ -+This directory contains the sources for building the vnc.so server extension module. -diff -pruN xorg-server-1.12.1.orig/hw/xfree86/vnc/vncInit.c xorg-server-1.12.1/hw/xfree86/vnc/vncInit.c ---- xorg-server-1.12.1.orig/hw/xfree86/vnc/vncInit.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/xfree86/vnc/vncInit.c 2012-04-18 14:45:21.588820803 -0500 -@@ -0,0 +1,626 @@ -+/* -+ * Copyright (C) 2002 Alan Hourihane. 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. -+ * -+ * Author: Alan Hourihane -+ */ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "../ramdac/xf86CursorPriv.h" -+#include "rfb.h" -+#include "vncint.h" -+ -+#include "xf86.h" -+#include "xf86_OSproc.h" -+#include "xorgVersion.h" -+ -+int inetdSock = -1; -+Atom VNC_LAST_CLIENT_ID = 0; -+Atom VNC_CONNECT = 0; -+char *desktopName = "x11"; -+char rfbThisHost[256]; -+ -+struct _DevPrivateKeyRec VNCScreenKeyRec; -+DevPrivateKey VNCScreenKey = &VNCScreenKeyRec; -+ -+extern void VncExtensionInit(void); -+ -+extern void vncInitMouse(void); -+extern void vncInitKeyb(void); -+Bool VNCInit(ScreenPtr pScreen, unsigned char *FBStart); -+ -+#ifndef XFree86LOADER -+static unsigned long VNCGeneration = 0; -+#endif -+#if 0 -+static const OptionInfoRec *VNCAvailableOptions(void *unused); -+#endif -+ -+static void rfbWakeupHandler (pointer pScreen,unsigned long err,pointer pReadmask); -+static Bool vncCursorRealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr); -+static Bool vncCursorUnrealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr); -+static void vncCursorSetCursor(DeviceIntPtr, ScreenPtr, CursorPtr, int, int); -+static void vncCursorMoveCursor(DeviceIntPtr, ScreenPtr, int, int); -+static Bool vncDisplayCursor(DeviceIntPtr, ScreenPtr, CursorPtr); -+static Bool vncDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr); -+static void vncDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr); -+ -+static miPointerSpriteFuncRec vncCursorSpriteFuncs = { -+ vncCursorRealizeCursor, -+ vncCursorUnrealizeCursor, -+ vncCursorSetCursor, -+ vncCursorMoveCursor, -+ vncDeviceCursorInitialize, -+ vncDeviceCursorCleanup -+ -+}; -+ -+/* -+ * VNC Config options -+ */ -+ -+typedef enum { -+ OPTION_USEVNC, -+ OPTION_RFBPORT, -+ OPTION_HTTPPORT, -+ OPTION_ALWAYS_SHARED, -+ OPTION_NEVER_SHARED, -+ OPTION_DONT_DISCONNECT, -+ OPTION_HTTPDIR, -+ OPTION_PASSWD_FILE, -+ OPTION_USER_ACCEPT, -+ OPTION_LOCALHOST, -+ OPTION_INTERFACE, -+ OPTION_VIEWONLY, -+ OPTION_LOGIN_AUTH, -+} VNCOpts; -+ -+static const OptionInfoRec VNCOptions[] = { -+ {OPTION_USEVNC, "usevnc", OPTV_BOOLEAN, {0}, FALSE }, -+ {OPTION_RFBPORT, "rfbport", OPTV_INTEGER, {0}, FALSE }, -+ {OPTION_HTTPPORT, "httpport", OPTV_INTEGER, {0}, FALSE }, -+ {OPTION_ALWAYS_SHARED, "alwaysshared", OPTV_BOOLEAN, {0}, FALSE }, -+ {OPTION_NEVER_SHARED, "nevershared", OPTV_BOOLEAN, {0}, FALSE }, -+ {OPTION_DONT_DISCONNECT, "dontdisconnect", OPTV_BOOLEAN, {0}, FALSE }, -+ {OPTION_HTTPDIR, "httpdir", OPTV_STRING, {0}, FALSE }, -+ {OPTION_PASSWD_FILE, "rfbauth", OPTV_STRING, {0}, FALSE }, -+ {OPTION_USER_ACCEPT, "useraccept", OPTV_BOOLEAN, {0}, FALSE }, -+ {OPTION_LOCALHOST, "localhost", OPTV_BOOLEAN, {0}, FALSE }, -+ {OPTION_INTERFACE, "interface", OPTV_STRING, {0}, FALSE }, -+ {OPTION_VIEWONLY, "viewonly", OPTV_BOOLEAN, {0}, FALSE }, -+ {OPTION_LOGIN_AUTH, "loginauth", OPTV_BOOLEAN, {0}, FALSE }, -+ { -1, NULL, OPTV_NONE, {0}, FALSE } -+}; -+ -+/*ARGSUSED*/ -+#if 0 -+static const OptionInfoRec * -+VNCAvailableOptions(void *unused) -+{ -+ return (VNCOptions); -+} -+#endif -+/* -+ * rfbLog prints a time-stamped message to the log file (stderr). -+ */ -+ -+void rfbLog(char *format, ...) -+{ -+ va_list ap; -+ char buf[256]; -+ time_t clock; -+ -+ time(&clock); -+ strftime(buf, 255, "%d/%m/%Y %H:%M:%S ", localtime(&clock)); -+ xf86DrvMsgVerb(-1, X_INFO, 1, "%s\n", buf); -+ -+ va_start(ap, format); -+ xf86VDrvMsgVerb(-1, X_NONE, 1, format, ap); -+ va_end(ap); -+} -+ -+void rfbLogPerror(char *str) -+{ -+ rfbLog(""); -+ perror(str); -+} -+ -+/* -+ * Called by vncCreateScreenResources() -+ */ -+Bool -+VNCInit(ScreenPtr pScreen, unsigned char *FBStart) -+{ -+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; -+ VisualPtr visual; -+ vncScreenPtr pScreenPriv; -+ OptionInfoPtr options; -+ char *interface_str = NULL; -+ miPointerScreenPtr PointPriv; -+ xf86CursorScreenPtr xf86CursorPriv; -+#ifdef RENDER -+ PictureScreenPtr ps; -+#endif -+ -+ if (!FBStart) -+ return FALSE; -+ -+#ifndef XFree86LOADER -+ if (VNCGeneration != serverGeneration) { -+ VncExtensionInit(); -+ VNCGeneration = serverGeneration; -+ } -+#endif -+ -+ if (!(pScreenPriv = malloc(sizeof(vncScreenRec)))) -+ return FALSE; -+ if (!dixRegisterPrivateKey(VNCScreenKey, PRIVATE_SCREEN, 0)) -+ return FALSE; -+ dixSetPrivate(&pScreen->devPrivates, VNCScreenKey, pScreenPriv); -+ -+ options = xnfalloc(sizeof(VNCOptions)); -+ (void)memcpy(options, VNCOptions, sizeof(VNCOptions)); -+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); -+ -+ if (xf86ReturnOptValBool(options, OPTION_USEVNC, FALSE)) { -+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VNC enabled\n"); -+ } else { -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VNC disabled\n"); -+ free(options); -+ return FALSE; -+ } -+ -+ pScreenPriv->rfbAuthTries = 0; -+ pScreenPriv->rfbAuthTooManyTries = FALSE; -+ pScreenPriv->timer = NULL; -+ pScreenPriv->udpPort = 0; -+ pScreenPriv->rfbListenSock = -1; -+ pScreenPriv->udpSock = -1; -+ pScreenPriv->udpSockConnected = FALSE; -+ pScreenPriv->httpListenSock = -1; -+ pScreenPriv->httpSock = -1; -+ pScreenPriv->maxFd = 0; -+ pScreenPriv->rfbAuthPasswdFile = NULL; -+ pScreenPriv->httpDir = NULL; -+ pScreenPriv->rfbInstalledColormap = NULL; -+ pScreenPriv->interface.s_addr = htonl (INADDR_ANY); -+ -+ pScreenPriv->rfbPort = 0; -+ xf86GetOptValInteger(options, OPTION_RFBPORT, &pScreenPriv->rfbPort); -+ pScreenPriv->httpPort = 0; -+ xf86GetOptValInteger(options, OPTION_HTTPPORT, &pScreenPriv->httpPort); -+ pScreenPriv->rfbAuthPasswdFile = -+ xf86GetOptValString(options, OPTION_PASSWD_FILE); -+ pScreenPriv->httpDir = -+ xf86GetOptValString(options, OPTION_HTTPDIR); -+ pScreenPriv->rfbAlwaysShared = FALSE; -+ xf86GetOptValBool(options, OPTION_ALWAYS_SHARED, -+ &pScreenPriv->rfbAlwaysShared); -+ pScreenPriv->rfbNeverShared = FALSE; -+ xf86GetOptValBool(options, OPTION_NEVER_SHARED, -+ &pScreenPriv->rfbNeverShared); -+ pScreenPriv->rfbUserAccept = FALSE; -+ xf86GetOptValBool(options, OPTION_USER_ACCEPT, -+ &pScreenPriv->rfbUserAccept); -+ pScreenPriv->rfbViewOnly = FALSE; -+ xf86GetOptValBool(options, OPTION_VIEWONLY, -+ &pScreenPriv->rfbViewOnly); -+ pScreenPriv->rfbDontDisconnect = FALSE; -+ xf86GetOptValBool(options, OPTION_DONT_DISCONNECT, -+ &pScreenPriv->rfbDontDisconnect); -+ pScreenPriv->loginAuthEnabled = FALSE; -+ xf86GetOptValBool(options, OPTION_LOGIN_AUTH, -+ &pScreenPriv->loginAuthEnabled); -+ -+ if (xf86ReturnOptValBool(options, OPTION_LOCALHOST, FALSE)) -+ pScreenPriv->interface.s_addr = htonl (INADDR_LOOPBACK); -+ -+ interface_str = xf86GetOptValString(options, OPTION_INTERFACE); -+ -+ if (interface_str && pScreenPriv->interface.s_addr == htonl(INADDR_ANY)) { -+ Bool failed = FALSE; -+ struct in_addr got; -+ unsigned long octet; -+ char *p = interface_str, *end; -+ int q; -+ -+ for (q = 0; q < 4; q++) { -+ octet = strtoul (p, &end, 10); -+ -+ if (p == end || octet > 255) -+ failed = TRUE; -+ -+ if ((q < 3 && *end != '.') || -+ (q == 3 && *end != '\0')) -+ failed = TRUE; -+ -+ got.s_addr = (got.s_addr << 8) | octet; -+ p = end + 1; -+ } -+ -+ if (!failed) -+ pScreenPriv->interface.s_addr = htonl (got.s_addr); -+ else -+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VNC interface option malformed, not using.\n"); -+ } -+ -+ free(options); -+ -+ if (!VNC_LAST_CLIENT_ID) -+ VNC_LAST_CLIENT_ID = MakeAtom("VNC_LAST_CLIENT_ID", -+ strlen("VNC_LAST_CLIENT_ID"), TRUE); -+ if (!VNC_CONNECT) -+ VNC_CONNECT = MakeAtom("VNC_CONNECT", strlen("VNC_CONNECT"), TRUE); -+ -+ rfbInitSockets(pScreen); -+ if (inetdSock == -1) -+ httpInitSockets(pScreen); -+ -+#ifdef CORBA -+ initialiseCORBA(argc, argv, desktopName); -+#endif -+ -+ pScreenPriv->width = pScrn->virtualX; -+ pScreenPriv->height = pScrn->virtualY; -+ pScreenPriv->depth = pScrn->depth; -+ pScreenPriv->paddedWidthInBytes = PixmapBytePad(pScrn->displayWidth, pScrn->depth); -+ pScreenPriv->bitsPerPixel = rfbBitsPerPixel(pScrn->depth); -+ pScreenPriv->pfbMemory = FBStart; -+ pScreenPriv->oldpfbMemory = FBStart; -+ -+ pScreenPriv->cursorIsDrawn = TRUE; -+ pScreenPriv->dontSendFramebufferUpdate = FALSE; -+ -+ pScreenPriv->CloseScreen = pScreen->CloseScreen; -+ pScreenPriv->CreateGC = pScreen->CreateGC; -+ pScreenPriv->CopyWindow = pScreen->CopyWindow; -+ pScreenPriv->ClearToBackground = pScreen->ClearToBackground; -+ pScreenPriv->WakeupHandler = pScreen->WakeupHandler; -+ pScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess; -+ pScreenPriv->InstallColormap = pScreen->InstallColormap; -+ pScreenPriv->UninstallColormap = pScreen->UninstallColormap; -+ pScreenPriv->ListInstalledColormaps = pScreen->ListInstalledColormaps; -+ pScreenPriv->StoreColors = pScreen->StoreColors; -+ pScreenPriv->DisplayCursor = pScreen->DisplayCursor; -+#ifdef CHROMIUM -+ pScreenPriv->RealizeWindow = pScreen->RealizeWindow; -+ pScreenPriv->UnrealizeWindow = pScreen->UnrealizeWindow; -+ pScreenPriv->DestroyWindow = pScreen->DestroyWindow; -+ pScreenPriv->PositionWindow = pScreen->PositionWindow; -+ pScreenPriv->ResizeWindow = pScreen->ResizeWindow; -+ pScreenPriv->ClipNotify = pScreen->ClipNotify; -+#endif -+#ifdef RENDER -+ ps = GetPictureScreenIfSet(pScreen); -+ if (ps) -+ pScreenPriv->Composite = ps->Composite; -+#endif -+ pScreen->CloseScreen = rfbCloseScreen; -+ pScreen->CreateGC = rfbCreateGC; -+ pScreen->CopyWindow = rfbCopyWindow; -+ pScreen->ClearToBackground = rfbClearToBackground; -+ pScreen->WakeupHandler = rfbWakeupHandler; -+ pScrn->EnableDisableFBAccess = rfbEnableDisableFBAccess; -+ pScreen->InstallColormap = rfbInstallColormap; -+ pScreen->UninstallColormap = rfbUninstallColormap; -+ pScreen->ListInstalledColormaps = rfbListInstalledColormaps; -+ pScreen->StoreColors = rfbStoreColors; -+ pScreen->DisplayCursor = vncDisplayCursor; /* it's defined in here */ -+ -+#ifdef CHROMIUM -+ pScreen->RealizeWindow = rfbRealizeWindow; -+ pScreen->UnrealizeWindow = rfbUnrealizeWindow; -+ pScreen->DestroyWindow = rfbDestroyWindow; -+ pScreen->PositionWindow = rfbPositionWindow; -+ pScreen->ResizeWindow = rfbResizeWindow; -+ pScreen->ClipNotify = rfbClipNotify; -+#endif -+#ifdef RENDER -+ if (ps) -+ ps->Composite = rfbComposite; -+#endif -+ -+ for (visual = pScreen->visuals; visual->vid != pScreen->rootVisual; visual++) -+ ; -+ -+ if (!visual) { -+ ErrorF("rfbScreenInit: couldn't find root visual\n"); -+ return FALSE; -+ } -+ -+ pScreenPriv->rfbServerFormat.bitsPerPixel = pScrn->bitsPerPixel; -+ pScreenPriv->rfbServerFormat.depth = pScrn->depth; -+ pScreenPriv->rfbServerFormat.bigEndian = !(*(char *)&rfbEndianTest); -+ pScreenPriv->rfbServerFormat.trueColour = (visual->class == TrueColor); -+ if (pScreenPriv->rfbServerFormat.trueColour) { -+ pScreenPriv->rfbServerFormat.redMax = visual->redMask >> visual->offsetRed; -+ pScreenPriv->rfbServerFormat.greenMax = visual->greenMask >> visual->offsetGreen; -+ pScreenPriv->rfbServerFormat.blueMax = visual->blueMask >> visual->offsetBlue; -+ pScreenPriv->rfbServerFormat.redShift = visual->offsetRed; -+ pScreenPriv->rfbServerFormat.greenShift = visual->offsetGreen; -+ pScreenPriv->rfbServerFormat.blueShift = visual->offsetBlue; -+ } else { -+ pScreenPriv->rfbServerFormat.redMax -+ = pScreenPriv->rfbServerFormat.greenMax -+ = pScreenPriv->rfbServerFormat.blueMax = 0; -+ pScreenPriv->rfbServerFormat.redShift -+ = pScreenPriv->rfbServerFormat.greenShift -+ = pScreenPriv->rfbServerFormat.blueShift = 0; -+ } -+ -+ PointPriv = dixLookupPrivate(&(pScreen)->devPrivates, miPointerScreenKey); -+ -+ pScreenPriv->spriteFuncs = PointPriv->spriteFuncs; -+ PointPriv->spriteFuncs = &vncCursorSpriteFuncs; -+ -+ if (dixPrivateKeyRegistered(xf86CursorScreenKey)) { -+ xf86CursorPriv = dixLookupPrivate(&(pScreen)->devPrivates, xf86CursorScreenKey); -+ -+ if (xf86CursorPriv) { -+ pScreenPriv->UseHWCursor = xf86CursorPriv->CursorInfoPtr->UseHWCursor; -+ xf86CursorPriv->CursorInfoPtr->UseHWCursor = vncUseHWCursor; -+#ifdef ARGB_CURSOR -+ pScreenPriv->UseHWCursorARGB = xf86CursorPriv->CursorInfoPtr->UseHWCursorARGB; -+ xf86CursorPriv->CursorInfoPtr->UseHWCursorARGB = vncUseHWCursorARGB; -+#endif -+ pScreenPriv->SWCursor = &xf86CursorPriv->SWCursor; -+ } -+ } else { -+ pScreenPriv->UseHWCursor = NULL; -+ } -+ -+ return TRUE; -+} -+ -+/****** miPointerSpriteFunctions *******/ -+ -+static Bool -+vncCursorRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs) -+{ -+ vncScreenPtr pScreenPriv = VNCPTR(pScreen); -+ -+ return (*pScreenPriv->spriteFuncs->RealizeCursor)(pDev, pScreen, pCurs); -+} -+ -+static Bool -+vncCursorUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs) -+{ -+ vncScreenPtr pScreenPriv = VNCPTR(pScreen); -+ -+ return (*pScreenPriv->spriteFuncs->UnrealizeCursor)(pDev, pScreen, pCurs); -+} -+ -+static void -+vncCursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs, int x, int y) -+{ -+ vncScreenPtr pScreenPriv = VNCPTR(pScreen); -+ -+ pScreenPriv->pCurs = pCurs; -+ -+ /* Without this call, cursor changes only appear in the viewer when -+ * some other drawing has occured. Added by BrianP. -+ */ -+ rfbScheduleUpdate(pScreen); -+ -+#if 0 -+ if (pCurs == NullCursor) { /* means we're supposed to remove the cursor */ -+ if (pScreenPriv->cursorIsDrawn) -+ pScreenPriv->cursorIsDrawn = FALSE; -+ return; -+ } -+ -+ pScreenPriv->cursorIsDrawn = TRUE; -+#endif -+ -+ (*pScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, pCurs, x, y); -+} -+ -+static void -+vncCursorMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) -+{ -+ vncScreenPtr pScreenPriv = VNCPTR(pScreen); -+ rfbClientPtr cl; -+ -+ for (cl = rfbClientHead; cl ; cl = cl->next) { -+ if (cl->enableCursorPosUpdates) -+ cl->cursorWasMoved = TRUE; -+ } -+ -+ (*pScreenPriv->spriteFuncs->MoveCursor)(pDev, pScreen, x, y); -+} -+ -+Bool -+vncUseHWCursor(ScreenPtr pScreen, CursorPtr pCursor) -+{ -+ vncScreenPtr pScreenPriv = VNCPTR(pScreen); -+ rfbClientPtr cl; -+ -+ if (!*pScreenPriv->UseHWCursor) { -+ /* If the driver doesn't have a UseHWCursor function we're -+ * basically saying we can have the HWCursor on all the time -+ */ -+ pScreenPriv->SWCursor = (Bool *)FALSE; -+ return TRUE; -+ } -+ -+ pScreenPriv->SWCursor = (Bool *)FALSE; -+ -+ /* If someone's connected, we revert to software cursor */ -+ for (cl = rfbClientHead; cl ; cl = cl->next) { -+ if (!cl->enableCursorShapeUpdates) -+ pScreenPriv->SWCursor = (Bool *)TRUE; -+ } -+ -+ if (pScreenPriv->SWCursor == (Bool *)TRUE) -+ return FALSE; -+ -+ return (*pScreenPriv->UseHWCursor)(pScreen, pCursor); -+} -+ -+#ifdef ARGB_CURSOR -+#include "cursorstr.h" -+ -+Bool -+vncUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCursor) -+{ -+ vncScreenPtr pScreenPriv = VNCPTR(pScreen); -+ rfbClientPtr cl; -+ -+ if (!*pScreenPriv->UseHWCursorARGB) { -+ pScreenPriv->SWCursor = (Bool *)TRUE; -+ return FALSE; -+ } -+ -+ pScreenPriv->SWCursor = (Bool *)FALSE; -+ -+ /* If someone's connected, we revert to software cursor */ -+ for (cl = rfbClientHead; cl ; cl = cl->next) { -+ if (!cl->enableCursorShapeUpdates) -+ pScreenPriv->SWCursor = (Bool *)TRUE; -+ } -+ -+ if (pScreenPriv->SWCursor == (Bool *)TRUE) -+ return FALSE; -+ -+ return (*pScreenPriv->UseHWCursorARGB)(pScreen, pCursor); -+} -+#endif -+ -+static Bool -+vncDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) -+{ -+ vncScreenPtr pScreenPriv = VNCPTR(pScreen); -+ rfbClientPtr cl; -+ Bool ret; -+ -+ pScreen->DisplayCursor = pScreenPriv->DisplayCursor; -+ -+ for (cl = rfbClientHead; cl ; cl = cl->next) { -+ if (cl->enableCursorShapeUpdates) -+ cl->cursorWasChanged = TRUE; -+ } -+ -+ ret = (*pScreen->DisplayCursor)(pDev, pScreen, pCursor); -+ -+ pScreen->DisplayCursor = vncDisplayCursor; -+ -+ return ret; -+} -+ -+static Bool vncDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr) -+{ -+ vncScreenPtr pScreenPriv = VNCPTR(pScr); -+ -+ return (*pScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScr); -+} -+ -+static void vncDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr) -+{ -+ vncScreenPtr pScreenPriv = VNCPTR(pScr); -+ -+ (*pScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScr); -+} -+ -+static void -+rfbWakeupHandler ( -+ /*int i,*/ -+ pointer pScreen, -+ /*pointer blockData,*/ -+ unsigned long err, -+ pointer pReadmask -+){ -+ /*ScreenPtr pScreen = screenInfo.screens[i];*/ -+ vncScreenPtr pScreenPriv = VNCPTR(pScreen); -+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; -+ int sigstate = xf86BlockSIGIO(); -+ -+ rfbRootPropertyChange(pScreen); /* Check clipboard */ -+ -+ if (pScrn->vtSema) { -+ rfbCheckFds(pScreen); -+ httpCheckFds(pScreen); -+#ifdef CORBA -+ corbaCheckFds(); -+#endif -+ } else { -+ rfbCheckFds(pScreen); -+ } -+ -+ xf86UnblockSIGIO(sigstate); -+ -+ pScreen->WakeupHandler = pScreenPriv->WakeupHandler; -+ /*(*pScreen->WakeupHandler) (i, blockData, err, pReadmask);*/ -+ (*pScreen->WakeupHandler) (pScreen, err, pReadmask); -+ pScreen->WakeupHandler = rfbWakeupHandler; -+} -+ -+#ifdef XFree86LOADER -+static MODULESETUPPROTO(vncSetup); -+ -+static XF86ModuleVersionInfo vncVersRec = -+{ -+ "vnc", -+ "xf4vnc Project, see http://xf4vnc.sf.net (based on modular X.org)", -+ MODINFOSTRING1, -+ MODINFOSTRING2, -+ XORG_VERSION_CURRENT, -+ 1, 1, 0, -+ ABI_CLASS_EXTENSION, -+#if 1 -+ ABI_EXTENSION_VERSION, -+#else -+ /* Hack to allow module to work with more servers (vs. 0.3 above) */ -+ SET_ABI_VERSION(0, 2), -+#endif -+ MOD_CLASS_EXTENSION, -+ {0,0,0,0} -+}; -+ -+_X_EXPORT XF86ModuleData vncModuleData = { -+ &vncVersRec, /* vers */ -+ vncSetup, /* ModuleSetupProc */ -+ NULL /* ModuleTearDownProc */ -+}; -+ -+ExtensionModule vncExtensionModule = { -+ VncExtensionInit, /* initFunc */ -+ "VNC", /* name */ -+ NULL, /* disablePtr */ -+ NULL, /* setupFunc */ -+ NULL /* initDependencies */ -+}; -+ -+ -+/*ARGSUSED*/ -+static pointer -+vncSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor) -+{ -+ LoadExtension(&vncExtensionModule, FALSE); -+ /* add mouse/kbd input drivers */ -+ vncInitMouse(); -+ vncInitKeyb(); -+ xf86Msg(X_INFO, "Ignore errors regarding the loading of the rfbmouse & rfbkeyb drivers\n"); -+ -+ return (pointer)TRUE; -+} -+#endif -+ -diff -pruN xorg-server-1.12.1.orig/hw/xfree86/vnc/vncint.h xorg-server-1.12.1/hw/xfree86/vnc/vncint.h ---- xorg-server-1.12.1.orig/hw/xfree86/vnc/vncint.h 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/hw/xfree86/vnc/vncint.h 2012-04-18 14:45:21.588820803 -0500 -@@ -0,0 +1,148 @@ -+/* -+ * Copyright (C) 2002 Alan Hourihane. 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. -+ * -+ * Author: Alan Hourihane -+ */ -+ -+#ifndef _VNC_H_ -+#define _VNC_H_ -+ -+#include <../ramdac/xf86Cursor.h> -+ -+#define VNCPTR(pScreen)\ -+ (vncScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates, VNCScreenKey)) -+ -+typedef struct { -+ int rfbPort; -+ int rdpPort; -+ int udpPort; -+ int rfbListenSock; -+ int rdpListenSock; -+ int udpSock; -+ int httpPort; -+ int httpListenSock; -+ int httpSock; -+ char * httpDir; -+ char buf[HTTP_BUF_SIZE]; -+ Bool udpSockConnected; -+ char * rfbAuthPasswdFile; -+ size_t buf_filled; -+ int maxFd; -+ fd_set allFds; -+ unsigned char * oldpfbMemory; -+ Bool rfbAlwaysShared; -+ Bool rfbNeverShared; -+ Bool rfbDontDisconnect; -+ Bool rfbUserAccept; -+ Bool rfbViewOnly; -+ unsigned char * pfbMemory; -+ int paddedWidthInBytes; -+ ColormapPtr rfbInstalledColormap; -+ ColormapPtr savedColormap; -+ rfbPixelFormat rfbServerFormat; -+ Bool rfbAuthTooManyTries; -+ int rfbAuthTries; -+ Bool loginAuthEnabled; -+ struct in_addr interface; -+ OsTimerPtr timer; -+ unsigned char updateBuf[UPDATE_BUF_SIZE]; -+ int ublen; -+ int width; -+ int height; -+ int depth; -+ int bitsPerPixel; -+ -+ /* The following two members are used to minimise the amount of unnecessary -+ drawing caused by cursor movement. Whenever any drawing affects the -+ part of the screen where the cursor is, the cursor is removed first and -+ then the drawing is done (this is what the sprite routines test for). -+ Afterwards, however, we do not replace the cursor, even when the cursor -+ is logically being moved across the screen. We only draw the cursor -+ again just as we are about to send the client a framebuffer update. -+ -+ We need to be careful when removing and drawing the cursor because of -+ their relationship with the normal drawing routines. The drawing -+ routines can invoke the cursor routines, but also the cursor routines -+ themselves end up invoking drawing routines. -+ -+ Removing the cursor (rfbSpriteRemoveCursor) is eventually achieved by -+ doing a CopyArea from a pixmap to the screen, where the pixmap contains -+ the saved contents of the screen under the cursor. Before doing this, -+ however, we set cursorIsDrawn to FALSE. Then, when CopyArea is called, -+ it sees that cursorIsDrawn is FALSE and so doesn't feel the need to -+ (recursively!) remove the cursor before doing it. -+ -+ Putting up the cursor (rfbSpriteRestoreCursor) involves a call to -+ PushPixels. While this is happening, cursorIsDrawn must be FALSE so -+ that PushPixels doesn't think it has to remove the cursor first. -+ Obviously cursorIsDrawn is set to TRUE afterwards. -+ -+ Another problem we face is that drawing routines sometimes cause a -+ framebuffer update to be sent to the RFB client. When the RFB client is -+ already waiting for a framebuffer update and some drawing to the -+ framebuffer then happens, the drawing routine sees that the client is -+ ready, so it calls rfbSendFramebufferUpdate. If the cursor is not drawn -+ at this stage, it must be put up, and so rfbSpriteRestoreCursor is -+ called. However, if the original drawing routine was actually called -+ from within rfbSpriteRestoreCursor or rfbSpriteRemoveCursor we don't -+ want this to happen. So both the cursor routines set -+ dontSendFramebufferUpdate to TRUE, and all the drawing routines check -+ this before calling rfbSendFramebufferUpdate. */ -+ -+ Bool cursorIsDrawn; /* TRUE if the cursor is currently drawn */ -+ Bool dontSendFramebufferUpdate; /* TRUE while removing or drawing the -+ cursor */ -+ -+ /* wrapped screen functions */ -+ -+ CloseScreenProcPtr CloseScreen; -+ CreateGCProcPtr CreateGC; -+ CopyWindowProcPtr CopyWindow; -+ ClearToBackgroundProcPtr ClearToBackground; -+ ScreenWakeupHandlerProcPtr WakeupHandler; -+ InstallColormapProcPtr InstallColormap; -+ UninstallColormapProcPtr UninstallColormap; -+ ListInstalledColormapsProcPtr ListInstalledColormaps; -+ StoreColorsProcPtr StoreColors; -+ xf86EnableDisableFBAccessProc *EnableDisableFBAccess; -+ miPointerSpriteFuncPtr spriteFuncs; -+ DisplayCursorProcPtr DisplayCursor; -+ CursorPtr pCurs; -+ Bool (*UseHWCursor)(ScreenPtr, CursorPtr); -+ Bool (*UseHWCursorARGB)(ScreenPtr, CursorPtr); -+ Bool *SWCursor; -+#ifdef CHROMIUM -+ RealizeWindowProcPtr RealizeWindow; -+ UnrealizeWindowProcPtr UnrealizeWindow; -+ DestroyWindowProcPtr DestroyWindow; -+ ResizeWindowProcPtr ResizeWindow; -+ PositionWindowProcPtr PositionWindow; -+ ClipNotifyProcPtr ClipNotify; -+#endif -+#ifdef RENDER -+ CompositeProcPtr Composite; -+#endif -+ -+} vncScreenRec, *vncScreenPtr; -+ -+extern Bool vncUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs); -+extern Bool vncUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs); -+extern void rfbEnableDisableFBAccess (int index, Bool enable); -+ -+#endif /* _VNC_H_ */ -+ -diff -pruN xorg-server-1.12.1.orig/Makefile.am xorg-server-1.12.1/Makefile.am ---- xorg-server-1.12.1.orig/Makefile.am 2011-09-22 20:39:52.000000000 -0500 -+++ xorg-server-1.12.1/Makefile.am 2012-04-18 14:45:21.589820790 -0500 -@@ -17,6 +17,10 @@ if RECORD - RECORD_DIR=record - endif - -+if XCLIPLIST -+XCLIPLIST_DIR=xcliplist -+endif -+ - SUBDIRS = \ - doc \ - man \ -@@ -37,6 +41,7 @@ SUBDIRS = \ - damageext \ - $(COMPOSITE_DIR) \ - $(GLX_DIR) \ -+ $(XCLIPLIST_DIR) \ - exa \ - config \ - hw \ -diff -pruN xorg-server-1.12.1.orig/mi/miinitext.c xorg-server-1.12.1/mi/miinitext.c ---- xorg-server-1.12.1.orig/mi/miinitext.c 2012-03-29 21:57:27.000000000 -0500 -+++ xorg-server-1.12.1/mi/miinitext.c 2012-04-18 14:45:21.589820790 -0500 -@@ -105,6 +105,18 @@ #ifdef HAVE_XGL_CONFIG_H - #include - #endif - -+#ifdef VNCSERVER -+#undef COMPOSITE -+#undef DAMAGE -+#undef DBE -+#undef RANDR -+#undef XF86MISC -+#undef XFreeXDGA -+#undef XF86DRI -+#undef XF86VIDMODE -+#undef XFIXES -+#endif -+ - #include "misc.h" - #include "extension.h" - #include "extinit.h" -diff -pruN xorg-server-1.12.1.orig/xcliplist/cliplist.c xorg-server-1.12.1/xcliplist/cliplist.c ---- xorg-server-1.12.1.orig/xcliplist/cliplist.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/xcliplist/cliplist.c 2012-04-18 14:45:21.589820790 -0500 -@@ -0,0 +1,128 @@ -+/* -+ * Server-side code for the Xcliplist extension -+ */ -+ -+#if HAVE_DIX_CONFIG_H -+#include "dix-config.h" -+#endif -+ -+#include -+#include -+ -+#include "dixstruct.h" -+#include "extnsionst.h" -+#include "windowstr.h" -+ -+#define _XCLIPLIST_SERVER_ -+#include -+ -+ -+static int XClipListErrorBase; -+static unsigned char XClipListReqCode = 0; -+ -+static void -+XClipListResetProc(ExtensionEntry* extEntry) -+{ -+ (void)extEntry; -+} -+ -+static int -+ProcXClipListQueryVersion(ClientPtr client) -+{ -+ xXClipListQueryVersionReply rep; -+ -+ REQUEST_SIZE_MATCH(xXClipListQueryVersionReq); -+ rep.type = X_Reply; -+ rep.length = 0; -+ rep.sequenceNumber = client->sequence; -+ rep.majorVersion = XCLIPLIST_MAJOR_VERSION; -+ rep.minorVersion = XCLIPLIST_MINOR_VERSION; -+ rep.patchVersion = XCLIPLIST_PATCH_VERSION; -+ -+ WriteToClient(client, sizeof(xXClipListQueryVersionReply), (char *)&rep); -+ return (client->noClientException); -+} -+ -+static int -+ProcXGetClipList(ClientPtr client) -+{ -+ xXGetClipListReply rep; -+ WindowPtr pWin; -+ int i; -+ BoxPtr pClipRects = NULL; -+ short xorig, yorig; -+ REQUEST(xXGetClipListReq); -+ REQUEST_SIZE_MATCH(xXGetClipListReq); -+ -+ rep.type = X_Reply; -+ rep.length = 0; -+ rep.sequenceNumber = client->sequence; -+ -+ if(!(pWin = (WindowPtr)LOOKUP_DRAWABLE(stuff->windowid, client) )) -+ { -+ client->errorValue = stuff->windowid; -+ return (BadWindow); -+ } -+ -+ rep.num_entries = REGION_NUM_RECTS(&pWin->clipList); -+ -+ WriteToClient(client, sizeof(xXGetClipListReply), (char *)&rep); -+ -+ pClipRects = REGION_RECTS(&pWin->clipList); -+ -+ xorig = pWin->drawable.x; -+ yorig = pWin->drawable.y; -+ -+ for (i = 0; i < rep.num_entries; i++) { -+ BoxRec box; -+ /* translate clip rect from screen coords to window coords */ -+ box.x1 = pClipRects[i].x1 - xorig; -+ box.y1 = pClipRects[i].y1 - yorig; -+ box.x2 = pClipRects[i].x2 - xorig; -+ box.y2 = pClipRects[i].y2 - yorig; -+ /*memcpy(&box, &pClipRects[i], sizeof(BoxRec));*/ -+ WriteToClient(client, sizeof(BoxRec), (char *)&box); -+ } -+ -+ return (client->noClientException); -+} -+ -+static int -+ProcXClipListDispatch (ClientPtr client) -+{ -+ REQUEST(xReq); -+ -+ switch (stuff->data) { -+ case X_XClipListQueryVersion: -+ return ProcXClipListQueryVersion(client); -+ case X_XGetClipList: -+ return ProcXGetClipList(client); -+ default: -+ return BadRequest; -+ } -+} -+ -+static int -+SProcXClipListDispatch (ClientPtr client) -+{ -+ REQUEST(xReq); -+ (void)stuff; -+ return XClipListErrorBase + XClipListClientNotLocal; -+} -+ -+void -+XClipListExtensionInit(void) -+{ -+ ExtensionEntry* extEntry; -+ -+ if ((extEntry = AddExtension(XCLIPLISTNAME, -+ XClipListNumberEvents, -+ XClipListNumberErrors, -+ ProcXClipListDispatch, -+ SProcXClipListDispatch, -+ XClipListResetProc, -+ StandardMinorOpcode))) { -+ XClipListReqCode = (unsigned char)extEntry->base; -+ XClipListErrorBase = extEntry->errorBase; -+ } -+} -diff -pruN xorg-server-1.12.1.orig/xcliplist/cliplistmod.c xorg-server-1.12.1/xcliplist/cliplistmod.c ---- xorg-server-1.12.1.orig/xcliplist/cliplistmod.c 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/xcliplist/cliplistmod.c 2012-04-18 14:45:21.589820790 -0500 -@@ -0,0 +1,49 @@ -+#ifdef HAVE_XORG_CONFIG_H -+#include -+#endif -+ -+#include "../hw/xfree86/common/xf86Module.h" -+ -+extern Bool noTestExtensions; -+ -+static MODULESETUPPROTO(xcliplistSetup); -+ -+extern void XClipListExtensionInit(INITARGS); -+ -+ExtensionModule xcliplistExt = { -+ XClipListExtensionInit, -+ "XClipList", -+ &noTestExtensions, -+ NULL, -+ NULL -+}; -+ -+static XF86ModuleVersionInfo VersRec = { -+ "XClipList", -+ MODULEVENDORSTRING, -+ MODINFOSTRING1, -+ MODINFOSTRING2, -+ XORG_VERSION_CURRENT, /* XXX fix? */ -+ 1, 13, 0, -+ ABI_CLASS_EXTENSION, -+#if 0 -+ ABI_EXTENSION_VERSION, -+#else -+ /* Hack to allow module to work with more servers (vs. 0.3 above) */ -+ SET_ABI_VERSION(0, 2), -+#endif -+ MOD_CLASS_EXTENSION, -+ {0,0,0,0} -+}; -+ -+XF86ModuleData xcliplistModuleData = { &VersRec, xcliplistSetup, NULL }; -+ -+static pointer -+xcliplistSetup(pointer module, pointer opts, int *errmaj, int *errmin) -+{ -+ LoadExtension(&xcliplistExt, FALSE); -+ -+ /* Need a non-NULL return value to indicate success */ -+ return (pointer)1; -+} -+ -diff -pruN xorg-server-1.12.1.orig/xcliplist/Makefile.am xorg-server-1.12.1/xcliplist/Makefile.am ---- xorg-server-1.12.1.orig/xcliplist/Makefile.am 1969-12-31 18:00:00.000000000 -0600 -+++ xorg-server-1.12.1/xcliplist/Makefile.am 2012-04-18 14:45:21.589820790 -0500 -@@ -0,0 +1,16 @@ -+#noinst_LTLIBRARIES = libxcliplist.la -+libxcliplist_la_LTLIBRARIES = libxcliplist.la -+ -+#AM_CFLAGS = $(DIX_CFLAGS) @SERVER_DEFINES@ @LOADER_DEFINES@ -+AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) -+ -+libxcliplist_la_LDFLAGS = -module -avoid-version -+libxcliplist_ladir = $(moduledir)/extensions -+ -+libxcliplist_la_SOURCES = \ -+ cliplist.c \ -+ cliplistmod.c -+ -+if XORG -+sdk_HEADERS = -+endif diff --git a/n_VNC-Don-t-let-VNC-access-the-framebuffer-directly-an.patch b/n_VNC-Don-t-let-VNC-access-the-framebuffer-directly-an.patch deleted file mode 100644 index 7bebc89..0000000 --- a/n_VNC-Don-t-let-VNC-access-the-framebuffer-directly-an.patch +++ /dev/null @@ -1,352 +0,0 @@ -From: Michal Srb -Date: Tue, 6 Sep 2011 13:08:25 +0200 -Subject: [PATCH 4/6] VNC: Don't let VNC access the framebuffer directly any more. -Patch-Mainline: Currently no upstream project. -Git-commit: 3e0de1d95b3ffd3988016b2d3f40f577393ad046 -Signed-off: Egbert Eich -References: bnc #653915 - -It seems that accessing the framebuffer directly is not a good idea anymore. -This patch will let the tight encoding read the screen data using GetImage. It -may be little slower, but not dramatically - it already does few GetImage calls -on every repaint now. - -Signed-off-by: Egbert Eich ---- - hw/vnc/tight.c | 69 ++++++++++++++++++++++++++++++--------------- - hw/vnc/vncext.c | 19 ++---------- - hw/xfree86/vnc/vncInit.c | 11 ++----- - hw/xfree86/vnc/vncint.h | 2 - - 4 files changed, 53 insertions(+), 48 deletions(-) - -diff --git a/hw/vnc/tight.c b/hw/vnc/tight.c -index 5c54736..f27c73e 100644 ---- a/hw/vnc/tight.c -+++ b/hw/vnc/tight.c -@@ -109,15 +109,17 @@ static unsigned char *tightAfterBuf = NULL; - - static int *prevRowBuf = NULL; - -+static unsigned char* fakeFrameBuffer = NULL; -+ - - /* Prototypes for static functions. */ - --static void FindBestSolidArea (ScreenPtr pScreen, int x, int y, int w, int h, -+static void FindBestSolidArea (rfbClientPtr cl, int x, int y, int w, int h, - CARD32 colorValue, int *w_ptr, int *h_ptr); --static void ExtendSolidArea (ScreenPtr pScreen, int x, int y, int w, int h, -+static void ExtendSolidArea (rfbClientPtr cl, int x, int y, int w, int h, - CARD32 colorValue, - int *x_ptr, int *y_ptr, int *w_ptr, int *h_ptr); --static Bool CheckSolidTile (ScreenPtr pScreen, int x, int y, int w, int h, -+static Bool CheckSolidTile (rfbClientPtr cl, int x, int y, int w, int h, - CARD32 *colorPtr, Bool needSameColor); - static Bool CheckSolidTile8 (ScreenPtr pScreen, int x, int y, int w, int h, - CARD32 *colorPtr, Bool needSameColor); -@@ -126,6 +128,7 @@ static Bool CheckSolidTile16 (ScreenPtr pScreen, int x, int y, int w, int h, - static Bool CheckSolidTile32 (ScreenPtr pScreen, int x, int y, int w, int h, - CARD32 *colorPtr, Bool needSameColor); - -+static Bool SendRectEncodingTight(rfbClientPtr cl, int x, int y, int w, int h); - static Bool SendRectSimple (rfbClientPtr cl, int x, int y, int w, int h); - static Bool SendSubrect (rfbClientPtr cl, int x, int y, int w, int h); - static Bool SendTightHeader (rfbClientPtr cl, int x, int y, int w, int h); -@@ -211,6 +214,25 @@ rfbSendRectEncodingTight(rfbClientPtr cl, - int x, int y, int w, int h) - { - VNCSCREENPTR(cl->pScreen); -+ -+ /* Copy the rectangle to the fake buffer for CheckSolidTile functions. */ -+ -+ if(!fakeFrameBuffer) fakeFrameBuffer = malloc(pVNC->width * pVNC->height * cl->format.bitsPerPixel / 8); -+ (*cl->translateFn)(cl->pScreen, cl->translateLookupTable, -+ &pVNC->rfbServerFormat, -+ &cl->format, fakeFrameBuffer + (y * pVNC->width * cl->format.bitsPerPixel / 8), -+ pVNC->paddedWidthInBytes, pVNC->width, h, 0, y); -+ -+ /* Call the inner part */ -+ -+ return SendRectEncodingTight(cl, x, y, w, h); -+} -+ -+static Bool -+SendRectEncodingTight(rfbClientPtr cl, -+ int x, int y, int w, int h) -+{ -+ VNCSCREENPTR(cl->pScreen); - int nMaxRows; - CARD32 colorValue; - int dx, dy, dw, dh; -@@ -247,7 +269,7 @@ rfbSendRectEncodingTight(rfbClientPtr cl, - nMaxWidth = (w > maxRectWidth) ? maxRectWidth : w; - nMaxRows = maxRectSize / nMaxWidth; - } -- -+ - /* Try to find large solid-color areas and send them separately. */ - - for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) { -@@ -269,11 +291,11 @@ rfbSendRectEncodingTight(rfbClientPtr cl, - dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w) ? - MAX_SPLIT_TILE_SIZE : (x + w - dx); - -- if (CheckSolidTile(cl->pScreen, dx, dy, dw, dh, &colorValue, FALSE)) { -+ if (CheckSolidTile(cl, dx, dy, dw, dh, &colorValue, FALSE)) { - - /* Get dimensions of solid-color area. */ - -- FindBestSolidArea(cl->pScreen, dx, dy, w - (dx - x), h - (dy - y), -+ FindBestSolidArea(cl, dx, dy, w - (dx - x), h - (dy - y), - colorValue, &w_best, &h_best); - - /* Make sure a solid rectangle is large enough -@@ -286,7 +308,7 @@ rfbSendRectEncodingTight(rfbClientPtr cl, - /* Try to extend solid rectangle to maximum size. */ - - x_best = dx; y_best = dy; -- ExtendSolidArea(cl->pScreen, x, y, w, h, colorValue, -+ ExtendSolidArea(cl, x, y, w, h, colorValue, - &x_best, &y_best, &w_best, &h_best); - - /* Send rectangles at top and left to solid-color area. */ -@@ -295,7 +317,7 @@ rfbSendRectEncodingTight(rfbClientPtr cl, - !SendRectSimple(cl, x, y, w, y_best-y) ) - return FALSE; - if ( x_best != x && -- !rfbSendRectEncodingTight(cl, x, y_best, -+ !SendRectEncodingTight(cl, x, y_best, - x_best-x, h_best) ) - return FALSE; - -@@ -316,11 +338,11 @@ rfbSendRectEncodingTight(rfbClientPtr cl, - /* Send remaining rectangles (at right and bottom). */ - - if ( x_best + w_best != x + w && -- !rfbSendRectEncodingTight(cl, x_best+w_best, y_best, -+ !SendRectEncodingTight(cl, x_best+w_best, y_best, - w-(x_best-x)-w_best, h_best) ) - return FALSE; - if ( y_best + h_best != y + h && -- !rfbSendRectEncodingTight(cl, x, y_best+h_best, -+ !SendRectEncodingTight(cl, x, y_best+h_best, - w, h-(y_best-y)-h_best) ) - return FALSE; - -@@ -339,7 +361,7 @@ rfbSendRectEncodingTight(rfbClientPtr cl, - } - - static void --FindBestSolidArea(ScreenPtr pScreen, -+FindBestSolidArea(rfbClientPtr cl, - int x, int y, int w, int h, - CARD32 colorValue, - int *w_ptr, int *h_ptr) -@@ -357,13 +379,13 @@ FindBestSolidArea(ScreenPtr pScreen, - dw = (w_prev > MAX_SPLIT_TILE_SIZE) ? - MAX_SPLIT_TILE_SIZE : w_prev; - -- if (!CheckSolidTile(pScreen, x, dy, dw, dh, &colorValue, TRUE)) -+ if (!CheckSolidTile(cl, x, dy, dw, dh, &colorValue, TRUE)) - break; - - for (dx = x + dw; dx < x + w_prev;) { - dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w_prev) ? - MAX_SPLIT_TILE_SIZE : (x + w_prev - dx); -- if (!CheckSolidTile(pScreen, dx, dy, dw, dh, &colorValue, TRUE)) -+ if (!CheckSolidTile(cl, dx, dy, dw, dh, &colorValue, TRUE)) - break; - dx += dw; - } -@@ -380,7 +402,7 @@ FindBestSolidArea(ScreenPtr pScreen, - } - - static void --ExtendSolidArea(ScreenPtr pScreen, int x, int y, int w, int h, -+ExtendSolidArea(rfbClientPtr cl, int x, int y, int w, int h, - CARD32 colorValue, - int *x_ptr, int *y_ptr, int *w_ptr, int *h_ptr) - { -@@ -388,7 +410,7 @@ ExtendSolidArea(ScreenPtr pScreen, int x, int y, int w, int h, - - /* Try to extend the area upwards. */ - for ( cy = *y_ptr - 1; -- cy >= y && CheckSolidTile(pScreen, *x_ptr, cy, *w_ptr, 1, &colorValue, TRUE); -+ cy >= y && CheckSolidTile(cl, *x_ptr, cy, *w_ptr, 1, &colorValue, TRUE); - cy-- ); - *h_ptr += *y_ptr - (cy + 1); - *y_ptr = cy + 1; -@@ -396,13 +418,13 @@ ExtendSolidArea(ScreenPtr pScreen, int x, int y, int w, int h, - /* ... downwards. */ - for ( cy = *y_ptr + *h_ptr; - cy < y + h && -- CheckSolidTile(pScreen, *x_ptr, cy, *w_ptr, 1, &colorValue, TRUE); -+ CheckSolidTile(cl, *x_ptr, cy, *w_ptr, 1, &colorValue, TRUE); - cy++ ); - *h_ptr += cy - (*y_ptr + *h_ptr); - - /* ... to the left. */ - for ( cx = *x_ptr - 1; -- cx >= x && CheckSolidTile(pScreen, cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE); -+ cx >= x && CheckSolidTile(cl, cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE); - cx-- ); - *w_ptr += *x_ptr - (cx + 1); - *x_ptr = cx + 1; -@@ -410,7 +432,7 @@ ExtendSolidArea(ScreenPtr pScreen, int x, int y, int w, int h, - /* ... to the right. */ - for ( cx = *x_ptr + *w_ptr; - cx < x + w && -- CheckSolidTile(pScreen, cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE); -+ CheckSolidTile(cl, cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE); - cx++ ); - *w_ptr += cx - (*x_ptr + *w_ptr); - } -@@ -423,11 +445,12 @@ ExtendSolidArea(ScreenPtr pScreen, int x, int y, int w, int h, - */ - - static Bool --CheckSolidTile(ScreenPtr pScreen, int x, int y, int w, int h, CARD32 *colorPtr, -+CheckSolidTile(rfbClientPtr cl, int x, int y, int w, int h, CARD32 *colorPtr, - Bool needSameColor) - { -- VNCSCREENPTR(pScreen); -- switch(pVNC->rfbServerFormat.bitsPerPixel) { -+ ScreenPtr pScreen = cl->pScreen; -+ -+ switch(cl->format.bitsPerPixel) { - case 32: - return CheckSolidTile32(pScreen, x, y, w, h, colorPtr, needSameColor); - case 16: -@@ -449,7 +472,7 @@ static Bool \ - int dx, dy; \ - \ - fbptr = (CARD##bpp *) \ -- &pVNC->pfbMemory[y * pVNC->paddedWidthInBytes + x * (bpp/8)]; \ -+ &fakeFrameBuffer[(y * pVNC->width + x) * (bpp/8)]; \ - \ - colorValue = *fbptr; \ - if (needSameColor && (CARD32)colorValue != *colorPtr) \ -@@ -460,7 +483,7 @@ static Bool \ - if (colorValue != fbptr[dx]) \ - return FALSE; \ - } \ -- fbptr = (CARD##bpp *)((CARD8 *)fbptr + pVNC->paddedWidthInBytes); \ -+ fbptr = (CARD##bpp *)((CARD8 *)fbptr + pVNC->width * (bpp/8)); \ - } \ - \ - *colorPtr = (CARD32)colorValue; \ -diff --git a/hw/vnc/vncext.c b/hw/vnc/vncext.c -index ea913b7..534f3f5 100644 ---- a/hw/vnc/vncext.c -+++ b/hw/vnc/vncext.c -@@ -702,15 +702,7 @@ CreateResourceTypes(void) - - static unsigned long vncExtGeneration = 0; - #if XFREE86VNC --extern Bool VNCInit(ScreenPtr pScreen, unsigned char *FBStart); -- --/* copied from miscrinit.c */ --typedef struct --{ -- pointer pbits; /* pointer to framebuffer */ -- int width; /* delta to add to a framebuffer addr to move one row down */ --} miScreenInitParmsRec, *miScreenInitParmsPtr; -- -+extern Bool VNCInit(ScreenPtr pScreen); - - static Bool - vncCreateScreenResources(ScreenPtr pScreen) -@@ -719,9 +711,6 @@ vncCreateScreenResources(ScreenPtr pScreen) - CreateScreenResourcesProcPtr CreateScreenResources = - (CreateScreenResourcesProcPtr) - dixLookupPrivate(&pScreen->devPrivates, vncCreateScreenResourcesKey); -- miScreenInitParmsPtr pScrInitParms; -- -- pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate; - - if ( pScreen->CreateScreenResources != vncCreateScreenResources ) { - /* Can't find hook we are hung on */ -@@ -732,9 +721,6 @@ vncCreateScreenResources(ScreenPtr pScreen) - (void *) pScreen->CreateScreenResources ); - } - -- /* Now do our stuff */ -- VNCInit(pScreen, pScrInitParms->pbits); -- - /* Unhook this function ... */ - pScreen->CreateScreenResources = CreateScreenResources; - dixSetPrivate(&pScreen->devPrivates, vncCreateScreenResourcesKey, NULL); -@@ -744,6 +730,9 @@ vncCreateScreenResources(ScreenPtr pScreen) - ret = (*pScreen->CreateScreenResources)(pScreen); - } - -+ /* Now do our stuff */ -+ VNCInit(pScreen); -+ - #ifdef DEBUG - ErrorF("vncCreateScreenResources() returns %d\n", ret); - #endif -diff --git a/hw/xfree86/vnc/vncInit.c b/hw/xfree86/vnc/vncInit.c -index 4a124fb..8b2fa5f 100644 ---- a/hw/xfree86/vnc/vncInit.c -+++ b/hw/xfree86/vnc/vncInit.c -@@ -49,7 +49,7 @@ extern void VncExtensionInit(void); - - extern void vncInitMouse(void); - extern void vncInitKeyb(void); --Bool VNCInit(ScreenPtr pScreen, unsigned char *FBStart); -+Bool VNCInit(ScreenPtr pScreen); - - #ifndef XFree86LOADER - static unsigned long VNCGeneration = 0; -@@ -151,7 +151,7 @@ void rfbLogPerror(char *str) - * Called by vncCreateScreenResources() - */ - Bool --VNCInit(ScreenPtr pScreen, unsigned char *FBStart) -+VNCInit(ScreenPtr pScreen) - { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - VisualPtr visual; -@@ -164,9 +164,6 @@ VNCInit(ScreenPtr pScreen, unsigned char *FBStart) - PictureScreenPtr ps; - #endif - -- if (!FBStart) -- return FALSE; -- - #ifndef XFree86LOADER - if (VNCGeneration != serverGeneration) { - VncExtensionInit(); -@@ -287,9 +284,7 @@ VNCInit(ScreenPtr pScreen, unsigned char *FBStart) - pScreenPriv->depth = pScrn->depth; - pScreenPriv->paddedWidthInBytes = PixmapBytePad(pScrn->displayWidth, pScrn->depth); - pScreenPriv->bitsPerPixel = rfbBitsPerPixel(pScrn->depth); -- pScreenPriv->pfbMemory = FBStart; -- pScreenPriv->oldpfbMemory = FBStart; -- -+ - pScreenPriv->cursorIsDrawn = TRUE; - pScreenPriv->dontSendFramebufferUpdate = FALSE; - -diff --git a/hw/xfree86/vnc/vncint.h b/hw/xfree86/vnc/vncint.h -index 18a3630..9e4a36f 100644 ---- a/hw/xfree86/vnc/vncint.h -+++ b/hw/xfree86/vnc/vncint.h -@@ -44,13 +44,11 @@ typedef struct { - size_t buf_filled; - int maxFd; - fd_set allFds; -- unsigned char * oldpfbMemory; - Bool rfbAlwaysShared; - Bool rfbNeverShared; - Bool rfbDontDisconnect; - Bool rfbUserAccept; - Bool rfbViewOnly; -- unsigned char * pfbMemory; - int paddedWidthInBytes; - ColormapPtr rfbInstalledColormap; - ColormapPtr savedColormap; --- -1.7.3.4 - diff --git a/n_VNC-Enable-use-of-all-keyboard-layouts-independent-o.patch b/n_VNC-Enable-use-of-all-keyboard-layouts-independent-o.patch deleted file mode 100644 index f04aef8..0000000 --- a/n_VNC-Enable-use-of-all-keyboard-layouts-independent-o.patch +++ /dev/null @@ -1,467 +0,0 @@ -From: Matthias Hopf -Date: Tue, 6 Sep 2011 08:35:57 +0200 -Subject: [PATCH 5/6] VNC: Enable use of all keyboard layouts, independent of remotely set layout -Patch-Mainline: Currently no upstream project. -Git-commit: 6885b927a6065e6379cfaa3ebbf6c51445a015d9 -Signed-off: Egbert Eich -References: bnc #400520, #605015, #660797 - -Changes: - -- Use virtual core keyboard for events and key state lookup: - Make layout changes work again - see discussion on - https://defect.opensolaris.org/bz/show_bug.cgi?id=8687 -- keycode lookup: - Don't use any static keyboard layout any more. -- ISO-Level3-Shift handling: - Enable the use of keyboard layouts that use AltGr for 3rd and 4th level. -- Make keyboard handling more XKB aware: - Previous code was e.g. not multi-group aware. -- Nuke use of legacy keymap as far as possible: - Creating legacy keymap takes time, and it has to be freed again afterwards. -- Free index lookup: - Make XKB aware. -- Ignore calls for NoSymbol: - This destroys otherwise valid entries. -- Fix analysis for shift/level3 event faking: - Previous broken version lead to e.g. Shift+PgUp not being recognized. -- Add tons of debug output (disabled). - -Signed-off-by: Egbert Eich - -Rebased to 1.12.1 by Mike Gorse ---- -diff -pruN xorg-server-1.12.1.orig/hw/vnc/kbdptr.c xorg-server-1.12.1/hw/vnc/kbdptr.c ---- xorg-server-1.12.1.orig/hw/vnc/kbdptr.c 2012-04-18 14:14:07.436250934 -0500 -+++ xorg-server-1.12.1/hw/vnc/kbdptr.c 2012-04-18 14:15:27.656248047 -0500 -@@ -34,6 +34,8 @@ - #include "X11/Xproto.h" - #include "inputstr.h" - #include "inpututils.h" -+#include "xkbsrv.h" -+#include "xkbstr.h" - #define XK_CYRILLIC - #include - #include -@@ -46,6 +48,7 @@ - #include "dmxinput.h" - #endif - -+#if 0 - #if !XFREE86VNC - - #define MIN_KEY_CODE 8 -@@ -196,21 +199,20 @@ static KeySym map[MAX_KEY_CODE * GLYPHS_ - #define N_PREDEFINED_KEYS (sizeof(map) / (sizeof(KeySym) * GLYPHS_PER_KEY)) - - #endif -+#endif - - #define KEY_IS_PRESSED(keycode) \ -- (kbdDevice->key->down[(keycode) >> 3] & (1 << ((keycode) & 7))) -+ (inputInfo.keyboard->key->down[(keycode) >> 3] & (1 << ((keycode) & 7))) - - static void vncXConvertCase(KeySym sym, KeySym *lower, KeySym *upper); - --static DeviceIntPtr ptrDevice = NULL, kbdDevice = NULL; -+static DeviceIntPtr ptrDevice = NULL; - - - void - vncSetKeyboardDevice(DeviceIntPtr kbd) - { -- if (kbdDevice && kbd) -- return; /* set once */ -- kbdDevice = kbd; -+ // obsoleted by inputInfo - } - - -@@ -263,6 +265,29 @@ EnqueueKey(DeviceIntPtr kbdDev, int type - QueueKeyboardEvents(kbdDev, type, detail, NULL); - } - -+/* In-server and highly changed version of XkbKeycodeToKeysym */ -+static KeySym -+_XkbKeycodeToKeysym(XkbDescPtr xkb, KeyCode kc, int group, int level) -+{ -+ KeySym ks; -+ -+ if ((kcmin_key_code)||(kc>xkb->max_key_code)) -+ return NoSymbol; -+ /* Treat single group elements as present in all groups */ -+ if (XkbKeyNumGroups (xkb,kc) == 1) -+ group = 0; -+ if ((group<0)||(level<0)||(group>=XkbKeyNumGroups(xkb,kc))) -+ return NoSymbol; -+ if (level < XkbKeyGroupWidth(xkb, kc, group)) -+ ks = XkbKeySymEntry(xkb, kc, level, group); -+ else -+ ks = NoSymbol; -+ /* Treat 'K' as 'K K', */ -+ if (ks == NoSymbol && (level & 1) && level-1 < XkbKeyGroupWidth(xkb, kc, group)) -+ ks = XkbKeySymEntry(xkb, kc, level-1, group); -+ return ks; -+} -+ - /* - * Called when the rfbserver receives a rfbKeyEvent event from a client. - * Put an X keyboard event into the event queue. -@@ -271,21 +296,35 @@ void - KbdAddEvent(Bool down, KeySym keySym, rfbClientPtr cl) - { - const int type = down ? KeyPress : KeyRelease; -- KeySymsPtr keySyms; -- XkbStateRec *xkb; -- int i; -+ XkbSrvInfoPtr xkbInfo; -+ int i, group, level; - int keyCode = 0; -- int freeIndex = -1; - Bool fakeShiftPress = FALSE; - Bool fakeShiftLRelease = FALSE; - Bool fakeShiftRRelease = FALSE; - Bool shiftMustBeReleased = FALSE; - Bool shiftMustBePressed = FALSE; -+ Bool fakeLevel3Press = FALSE; -+ Bool fakeLevel3Release = FALSE; -+ Bool level3MustBeReleased = FALSE; -+ Bool level3MustBePressed = FALSE; -+ -+ /* Incomplete maps may create NoSymbol - which lets us -+ * select and/or overwrite otherwise valid entries. -+ * E.g Level3+a in serbian layout creates NoSymbol on os11.4 -+ * 2011-05-24 mhopf@suse.de */ -+ if (keySym == NoSymbol) { -+ ErrorF("KbdAddEvent: ignoring illegal NoSymbol\n"); -+ return; -+ } - -- if (!kbdDevice) -- return; -- -- keySyms = XkbGetCoreMap(kbdDevice); -+ xkbInfo = inputInfo.keyboard->key->xkbInfo; -+ group = xkbInfo->state.group; -+ level = (KEY_IS_PRESSED(ISO_LEVEL3_KEY_CODE) ? 2 : 0) | -+ (XkbStateFieldFromRec(&xkbInfo->state) & ShiftMask ? 1 : 0); -+#ifdef DEBUG -+ ErrorF ("VNCkbd:\t%s Sym %04x\n", down ? "+":"-", (int)keySym); -+#endif - - #ifdef CORBA - if (cl) { -@@ -303,6 +342,12 @@ KbdAddEvent(Bool down, KeySym keySym, rf - * - * Alan. - */ -+ /* Never use predefined keys. -+ * This is inherently incapable of dealing with changing -+ * keyboard layouts. Not being able to work with non-local xmodmaps -+ * is a nuisance at worst, and probably even preferred. -+ * 2011-04-15 mhopf@suse.de */ -+#ifdef NOTANYMORE - #if !XFREE86VNC - /* First check if it's one of our predefined keys. If so then we can make - some attempt at allowing an xmodmap inside a VNC desktop behave -@@ -329,107 +374,227 @@ KbdAddEvent(Bool down, KeySym keySym, rf - } - } - #endif -+#endif - - if (!keyCode) { - - /* not one of our predefined keys - see if it's in the current keyboard - mapping (i.e. we've already allocated an extra keycode for it) */ - -- if (keySyms->mapWidth < 2) { -- ErrorF("KbdAddEvent: Sanity check failed - Keyboard mapping has " -- "less than 2 keysyms per keycode (KeySym 0x%x)\n", (int)keySym); -- return; -- } -+ for (keyCode = MIN_KEY_CODE; keyCode < MIN_KEY_CODE + NO_OF_KEYS; keyCode++) { -+ /* Check all keycodes, but only continue on those where -+ * backconversion results in keySym. -+ * 2011-05-20 mhopf@suse.de */ -+ -+#ifdef DEBUG -+ int j; -+ ErrorF (" keyCode %3d map# %4d++ level %d of %d: keySyms", -+ keyCode, (i / keySyms->mapWidth) * keySyms->mapWidth, -+ i % keySyms->mapWidth, keySyms->mapWidth); -+ for (j = 0; j < keySyms->mapWidth; j++) -+ ErrorF (" %02x", (int)keySyms->map[(i / keySyms->mapWidth) * keySyms->mapWidth + j]); -+ ErrorF ("\n"); -+ ErrorF (" group %d of %d width %d: keySyms", -+ group, XkbKeyNumGroups(xkbInfo->desc, keyCode), -+ XkbKeyGroupWidth(xkbInfo->desc, keyCode, group)); -+ if (XkbKeyNumGroups(xkbInfo->desc, keyCode) > group) -+ for (j = 0; j < XkbKeyGroupWidth(xkbInfo->desc, keyCode, group); j++) -+ ErrorF (" %02x", (int) XkbKeySymEntry(xkbInfo->desc, keyCode, j, group)); -+ ErrorF ("\n"); -+#endif - -- for (i = 0; i < NO_OF_KEYS * keySyms->mapWidth; i++) { -- if (keySym == keySyms->map[i]) { -- keyCode = MIN_KEY_CODE + i / keySyms->mapWidth; -- -- if (keySyms->map[(i / keySyms->mapWidth) -- * keySyms->mapWidth + 1] != NoSymbol) { -- -- /* this keycode has more than one symbol associated with -- it, so shift state is important */ -- -- if ((i % keySyms->mapWidth) == 0) -- shiftMustBeReleased = TRUE; -- else -- shiftMustBePressed = TRUE; -- } -+ /* Check whether keySym is reachable in current group -+ * by any shift/Level3_shift state (preferrable w/o change). -+ * This doesn't do real modifyer analysis, only Shift and Level3_Shift. -+ * 2011-05-23 mhopf@suse.de */ -+ if (_XkbKeycodeToKeysym(xkbInfo->desc, keyCode, group, level) == keySym) -+ break; -+ if (_XkbKeycodeToKeysym(xkbInfo->desc, keyCode, group, level ^ 2) == keySym) { -+ if (level & 2) -+ level3MustBeReleased = TRUE; -+ else -+ level3MustBePressed = TRUE; - break; - } -- if ((freeIndex == -1) && (keySyms->map[i] == NoSymbol) -- && (i % keySyms->mapWidth) == 0) -- { -- freeIndex = i; -+ if (_XkbKeycodeToKeysym(xkbInfo->desc, keyCode, group, level ^ 1) == keySym) { -+ if (level & 1) -+ shiftMustBeReleased = TRUE; -+ else -+ shiftMustBePressed = TRUE; -+ break; -+ } -+ if (_XkbKeycodeToKeysym(xkbInfo->desc, keyCode, group, level ^ 3) == keySym) { -+ if (level & 2) -+ level3MustBeReleased = TRUE; -+ else -+ level3MustBePressed = TRUE; -+ if (level & 1) -+ shiftMustBeReleased = TRUE; -+ else -+ shiftMustBePressed = TRUE; -+ break; - } - } -+ if (keyCode == MIN_KEY_CODE + NO_OF_KEYS) -+ keyCode = 0; - } - - if (!keyCode) { - KeySym lower, upper; -+ KeySymsPtr keySyms = XkbGetCoreMap(inputInfo.keyboard); - - /* we don't have an existing keycode - make one up on the fly and add - it to the keyboard mapping. Thanks to Vlad Harchev for pointing - out problems with non-ascii capitalisation. */ - -- if (freeIndex == -1) { -+ /* Find free index for current group. */ -+ for (keyCode = MIN_KEY_CODE; keyCode < MIN_KEY_CODE + NO_OF_KEYS; keyCode++) { -+ /* A keyCode is free if no groups are assigned at all */ -+ if (XkbKeyNumGroups(xkbInfo->desc, keyCode) == 0) -+ break; -+#ifdef NOTANYMORE -+ /* We can use exact map positions for group 1+2, but only partially -+ * filling out xkb legacy maps may suddenly change the # of groups. -+ * Reason for that is unknown yet. Might be related to (fixed) NoSymbol issue. -+ * 2011-05-24 mhopf@suse.de */ -+ /* For primary groups: A keyCode is free if current group is empty */ -+ if (XkbKeyGroupWidth(xkbInfo->desc, keyCode, group) < 1 && group < 2) -+ break; -+ /* Never touch groups that have a single level only (weird group?!?) */ -+ if (XkbKeyGroupWidth(xkbInfo->desc, keyCode, group) < 2) -+ continue; -+ /* For primary groups: A keyCode is free if only NoSymbol is assigned -+ * to available levels (only validating levels 0-3) */ -+ if (group < 2 && -+ XkbKeySymEntry(xkbInfo->desc, keyCode, 0, group) == NoSymbol && -+ XkbKeySymEntry(xkbInfo->desc, keyCode, 1, group) == NoSymbol && -+ (XkbKeyGroupWidth(xkbInfo->desc, keyCode, group) < 3 || -+ (XkbKeySymEntry(xkbInfo->desc, keyCode, 2, group) == NoSymbol && -+ (XkbKeyGroupWidth(xkbInfo->desc, keyCode, group) < 4 || -+ XkbKeySymEntry(xkbInfo->desc, keyCode, 3, group) == NoSymbol)))) -+ break; -+#endif -+ } -+ -+ if (keyCode == MIN_KEY_CODE + NO_OF_KEYS) { - ErrorF("KbdAddEvent: ignoring KeySym 0x%x - no free KeyCodes\n", - (int)keySym); -+ free (keySyms->map); -+ free (keySyms); - return; - } - -- keyCode = MIN_KEY_CODE + freeIndex / keySyms->mapWidth; -- - vncXConvertCase(keySym, &lower, &upper); - -- if (lower == upper) { -- keySyms->map[freeIndex] = keySym; -- -- } else { -- keySyms->map[freeIndex] = lower; -- keySyms->map[freeIndex+1] = upper; -- -+ /* Adding keys is not using xkb mechanisms yet, but relying on support -+ * for changing keys in the legacy map. Should be changed, eventually. -+ * 2011-05-19 mhopf@suse.de */ -+#ifdef NOTANYMORE -+ if (group < 2) { -+ /* Only set mapping for active group. Will only work with dual layouts. -+ * 2011-05-23 mhopf@suse.de */ -+ int active_group_offset = group ? 2 : 0; -+ -+ if (lower == upper) { -+ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + active_group_offset] = keySym; -+ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + active_group_offset + 1] = NoSymbol; -+ } else { -+ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + active_group_offset] = lower; -+ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + active_group_offset + 1] = upper; -+ } -+ } -+#endif -+ /* Generic layouts needs to set the full map width. -+ * Weird enough, mapWidth seems too big... -+ * 2011-05-23 mhopf@suse.de */ -+ for (i = 0; i < (keySyms->mapWidth & ~1); i += 2) { -+ if (lower == upper) { -+ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + i] = keySym; -+ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + i + 1] = NoSymbol; -+ } else { -+ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + i] = lower; -+ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + i + 1] = upper; -+ } -+ } -+ if (lower != upper) { - if (keySym == lower) - shiftMustBeReleased = TRUE; - else - shiftMustBePressed = TRUE; - } -+ level3MustBeReleased = TRUE; - -- XkbApplyMappingChange(kbdDevice, keySyms, keyCode, 1, NULL, serverClient); -+ XkbApplyMappingChange(inputInfo.keyboard, keySyms, keyCode, 1, NULL, serverClient); - - ErrorF("KbdAddEvent: unknown KeySym 0x%x - allocating KeyCode %d\n", - (int)keySym, keyCode); -+ free (keySyms->map); -+ free (keySyms); - } - -- xkb = &kbdDevice->key->xkbInfo->state; -+#ifdef DEBUG -+ ErrorF ("\t%s Sym %04x Code%3d\tState x%02x %s%s%s\tSh %s%s\tL3 %s%s\n", -+ down ? "+":"-", (int)keySym, keyCode, XkbStateFieldFromRec(&xkbInfo->state), -+ KEY_IS_PRESSED(SHIFT_L_KEY_CODE) ? "Sl":"", -+ KEY_IS_PRESSED(SHIFT_R_KEY_CODE) ? "Sr":"", -+ KEY_IS_PRESSED(ISO_LEVEL3_KEY_CODE) ? "L3":"", -+ shiftMustBePressed ? "+":"", shiftMustBeReleased ? "-":"", -+ level3MustBePressed ? "+":"", level3MustBeReleased ? "-":""); -+#endif -+#ifdef NOTANYMORE -+ int back = _XkbKeycodeToKeysym (xkbInfo->desc, keyCode, group, -+ ((level3MustBePressed || (!level3MustBeReleased && (level & 2))) ? 2 : 0) | -+ ((shiftMustBePressed || (!shiftMustBeReleased && (level & 1))) ? 1 : 0)); -+ ErrorF ("\tvalidate code %d %-2s%-2s -> sym %04x %s\n\n", keyCode, -+ (shiftMustBePressed || (!shiftMustBeReleased && (level & 1))) ? "Sh" : "", -+ (level3MustBePressed || (!level3MustBeReleased && (level & 2))) ? "L3" : "", -+ back, (back == keySym ? "ok" : "FAILED")); -+#endif -+ - if (down) { -- if (shiftMustBePressed && !(XkbStateFieldFromRec(xkb) & ShiftMask)) { -+ /* TODO: would require to check which keycodes are actually -+ * bound to ISO_Level3_Shift and/or Shift_L. -+ * 2011-04-18 mhopf@suse.de */ -+ if (level3MustBePressed && !(level & 2)) { -+ fakeLevel3Press = TRUE; -+ EnqueueKey(inputInfo.keyboard, KeyPress, ISO_LEVEL3_KEY_CODE); -+ } -+ if (level3MustBeReleased && (level & 2)) { -+ fakeLevel3Release = TRUE; -+ EnqueueKey(inputInfo.keyboard, KeyRelease, ISO_LEVEL3_KEY_CODE); -+ } -+ if (shiftMustBePressed && !(level & 1)) { - fakeShiftPress = TRUE; -- EnqueueKey(kbdDevice, KeyPress, SHIFT_L_KEY_CODE); -+ EnqueueKey(inputInfo.keyboard, KeyPress, SHIFT_L_KEY_CODE); - } -- if (shiftMustBeReleased && (XkbStateFieldFromRec(xkb) & ShiftMask)) { -+ if (shiftMustBeReleased && (level & 1)) { - if (KEY_IS_PRESSED(SHIFT_L_KEY_CODE)) { - fakeShiftLRelease = TRUE; -- EnqueueKey(kbdDevice, KeyRelease, SHIFT_L_KEY_CODE); -+ EnqueueKey(inputInfo.keyboard, KeyRelease, SHIFT_L_KEY_CODE); - } - if (KEY_IS_PRESSED(SHIFT_R_KEY_CODE)) { - fakeShiftRRelease = TRUE; -- EnqueueKey(kbdDevice, KeyRelease, SHIFT_R_KEY_CODE); -+ EnqueueKey(inputInfo.keyboard, KeyRelease, SHIFT_R_KEY_CODE); - } - } - } - -- EnqueueKey(kbdDevice, type, keyCode); -+ EnqueueKey(inputInfo.keyboard, type, keyCode); - - if (fakeShiftPress) { -- EnqueueKey(kbdDevice, KeyRelease, SHIFT_L_KEY_CODE); -+ EnqueueKey(inputInfo.keyboard, KeyRelease, SHIFT_L_KEY_CODE); - } - if (fakeShiftLRelease) { -- EnqueueKey(kbdDevice, KeyPress, SHIFT_L_KEY_CODE); -+ EnqueueKey(inputInfo.keyboard, KeyPress, SHIFT_L_KEY_CODE); - } - if (fakeShiftRRelease) { -- EnqueueKey(kbdDevice, KeyPress, SHIFT_R_KEY_CODE); -+ EnqueueKey(inputInfo.keyboard, KeyPress, SHIFT_R_KEY_CODE); -+ } -+ if (fakeLevel3Press) { -+ EnqueueKey(inputInfo.keyboard, KeyRelease, ISO_LEVEL3_KEY_CODE); -+ } -+ if (fakeLevel3Release) { -+ EnqueueKey(inputInfo.keyboard, KeyPress, ISO_LEVEL3_KEY_CODE); - } - } - -@@ -480,15 +645,15 @@ KbdReleaseAllKeys(void) - { - int i, j; - -- if (!kbdDevice) -+ if (!inputInfo.keyboard) - return; - - for (i = 0; i < DOWN_LENGTH; i++) { -- if (kbdDevice->key->down[i] != 0) { -+ if (inputInfo.keyboard->key->down[i] != 0) { - for (j = 0; j < 8; j++) { -- if (kbdDevice->key->down[i] & (1 << j)) { -+ if (inputInfo.keyboard->key->down[i] & (1 << j)) { - int detail = (i << 3) | j; -- EnqueueKey(kbdDevice, KeyRelease, detail); -+ EnqueueKey(inputInfo.keyboard, KeyRelease, detail); - } - } - } -diff -pruN xorg-server-1.12.1.orig/hw/vnc/keyboard.h xorg-server-1.12.1/hw/vnc/keyboard.h ---- xorg-server-1.12.1.orig/hw/vnc/keyboard.h 2012-04-18 14:14:07.437250922 -0500 -+++ xorg-server-1.12.1/hw/vnc/keyboard.h 2012-04-18 14:15:27.657248035 -0500 -@@ -32,3 +32,4 @@ - #define META_R_KEY_CODE (MIN_KEY_CODE + 108) - #define ALT_L_KEY_CODE (MIN_KEY_CODE + 56) - #define ALT_R_KEY_CODE (MIN_KEY_CODE + 105) -+#define ISO_LEVEL3_KEY_CODE ALT_R_KEY_CODE diff --git a/n_VNC-Fix-crash-due-to-unset-input-device-names.patch b/n_VNC-Fix-crash-due-to-unset-input-device-names.patch deleted file mode 100644 index 7c527a1..0000000 --- a/n_VNC-Fix-crash-due-to-unset-input-device-names.patch +++ /dev/null @@ -1,125 +0,0 @@ -From: Egbert Eich -Date: Tue, 6 Sep 2011 14:58:28 +0200 -Subject: [PATCH 6/6] VNC: Fix crash due to unset input device names. -Patch-Mainline: Currently no upstream project. -Git-commit: b756a7efff37021ca503fe1e63084daae4082e9d -Signed-off: Egbert Eich -References: bnc #716074 - - Signed-off-by: Egbert Eich - ---- - hw/vnc/init.c | 2 +- - hw/vnc/rfb.h | 2 +- - hw/vnc/rfbkeyb.c | 7 +++++-- - hw/vnc/rfbmouse.c | 9 +++++++-- - 4 files changed, 14 insertions(+), 6 deletions(-) - -diff --git a/hw/vnc/init.c b/hw/vnc/init.c -index 0977fee..6f83aa8 100644 ---- a/hw/vnc/init.c -+++ b/hw/vnc/init.c -@@ -816,7 +816,7 @@ rfbMouseProc(DeviceIntPtr pDevice, int onoff) - switch (onoff) - { - case DEVICE_INIT: -- PtrDeviceInit(); -+ PtrDeviceInit(pDevice, "vncMouse"); - map[1] = 1; - map[2] = 2; - map[3] = 3; -diff --git a/hw/vnc/rfb.h b/hw/vnc/rfb.h -index 70b1a45..aa9abab 100644 ---- a/hw/vnc/rfb.h -+++ b/hw/vnc/rfb.h -@@ -578,7 +578,7 @@ extern void rfbGotXCutText(char *str, int len); - extern Bool compatibleKbd; - extern unsigned char ptrAcceleration; - --extern void PtrDeviceInit(void); -+extern void PtrDeviceInit(DeviceIntPtr pDevice, char *name); - extern void PtrDeviceOn(DeviceIntPtr pDev); - extern void PtrDeviceOff(void); - extern void PtrDeviceControl(DeviceIntPtr dev, PtrCtrl *ctrl); -diff --git a/hw/vnc/rfbkeyb.c b/hw/vnc/rfbkeyb.c -index 4da29c2..6d97999 100644 ---- a/hw/vnc/rfbkeyb.c -+++ b/hw/vnc/rfbkeyb.c -@@ -36,6 +36,7 @@ - #endif - #include - #include /* Needed for InitValuator/Proximity stuff */ -+#include - #include - - #ifdef XFree86LOADER -@@ -49,7 +50,6 @@ - - - extern void rfbSendBell(void); --extern DeviceIntPtr kbdDevice; - extern void vncInitKeyb(void); - - #include -@@ -212,11 +212,15 @@ static KeySym map[MAX_KEY_CODE * GLYPHS_PER_KEY] = { - }; - - #define N_PREDEFINED_KEYS (sizeof(map) / (sizeof(KeySym) * GLYPHS_PER_KEY)) -+#define RFB_KEYB "rfbKeyb" - - void - KbdDeviceInit(DeviceIntPtr pDevice, KeySymsPtr pKeySyms, CARD8 *pModMap) - { - int i; -+ Atom atom = MakeAtom(RFB_KEYB, strlen(RFB_KEYB), TRUE); -+ -+ AssignTypeAndName(pDevice, atom, RFB_KEYB); - - for (i = 0; i < MAP_LENGTH; i++) - pModMap[i] = NoSymbol; -@@ -359,7 +363,6 @@ xf86rfbKeybInit(struct _InputDriverRec *drv, - pInfo->control_proc = NULL; - pInfo->switch_mode = NULL; - pInfo->fd = -1; -- pInfo->dev = NULL; - - /* Collect the options, and process the common options. */ - xf86CollectInputOptions(pInfo, (const char**)drv->default_options); -diff --git a/hw/vnc/rfbmouse.c b/hw/vnc/rfbmouse.c -index 4657128..86e8f2f 100644 ---- a/hw/vnc/rfbmouse.c -+++ b/hw/vnc/rfbmouse.c -@@ -37,6 +37,7 @@ - #endif - #include - #include /* Needed for InitValuator/Proximity stuff */ -+#include - #include - - #ifdef XFree86LOADER -@@ -63,8 +64,12 @@ PtrDeviceOn(DeviceIntPtr pDev) - } - - void --PtrDeviceInit(void) -+PtrDeviceInit(DeviceIntPtr pDevice, char *name) - { -+ Atom atom = MakeAtom(name, strlen(name), TRUE); -+ -+ AssignTypeAndName(pDevice, atom, name); -+ - } - - void -@@ -119,7 +124,7 @@ xf86rfbMouseControlProc(DeviceIntPtr dev, int onoff) - { - case DEVICE_INIT: - vncSetPointerDevice(dev); -- PtrDeviceInit(); -+ // PtrDeviceInit(dev, "rfbPointer"); - map[1] = 1; - map[2] = 2; - map[3] = 3; --- -1.7.3.4 - diff --git a/n_VNC-Fix-crash-when-no-depth-translation-is-required.patch b/n_VNC-Fix-crash-when-no-depth-translation-is-required.patch deleted file mode 100644 index c269672..0000000 --- a/n_VNC-Fix-crash-when-no-depth-translation-is-required.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: Michael Schroeder -Date: Tue, 6 Sep 2011 07:58:33 +0200 -Subject: [PATCH 3/6] VNC: Fix crash when no depth translation is required. -Patch-Mainline: Currently no upstream project. -Git-commit: 74d5e3115cd955b7ee1acc64c6b8b42198ed894b -Signed-off: Egbert Eich -References: bnc #389386 - - Signed-off-by: Egbert Eich - ---- - hw/vnc/translate.c | 11 ++++++----- - 1 files changed, 6 insertions(+), 5 deletions(-) - -diff --git a/hw/vnc/translate.c b/hw/vnc/translate.c -index 5cc57a3..78030ed 100644 ---- a/hw/vnc/translate.c -+++ b/hw/vnc/translate.c -@@ -168,17 +168,18 @@ rfbTranslateNone(ScreenPtr pScreen, char *table, rfbPixelFormat *in, rfbPixelFor - { - VNCSCREENPTR(pScreen); - DrawablePtr pDraw = (DrawablePtr)pScreen->root; -- int truewidth = PixmapBytePad(width, in->bitsPerPixel) / 4; -+ int truewidth = PixmapBytePad(width, in->bitsPerPixel); - -- if ((x + truewidth > pVNC->width) || truewidth != width) { -- unsigned char *buffer = malloc(truewidth * height * in->bitsPerPixel / 8); -+ if ((x + width > pVNC->width) || truewidth != width * in->bitsPerPixel / 8) { -+ unsigned char *buffer = malloc(truewidth * height); - unsigned char *buf = buffer; - -- (*pScreen->GetImage)(pDraw, x, y, truewidth, height, ZPixmap, ~0, (char*)buf); -+ (*pScreen->GetImage)(pDraw, x, y, width, height, ZPixmap, ~0, (char*)buf); -+ - while (height--) { - memcpy(optr, buf, width * in->bitsPerPixel / 8); - optr += width * in->bitsPerPixel / 8; -- buf += truewidth * in->bitsPerPixel / 8; -+ buf += truewidth; - } - free(buffer); - return; --- -1.7.3.4 - diff --git a/n_VNC-Readd-timeout-when-vnc-viewer-connection-breaks.patch b/n_VNC-Readd-timeout-when-vnc-viewer-connection-breaks.patch deleted file mode 100644 index ce2d2b1..0000000 --- a/n_VNC-Readd-timeout-when-vnc-viewer-connection-breaks.patch +++ /dev/null @@ -1,74 +0,0 @@ -From: Egbert Eich -Date: Tue, 6 Sep 2011 07:02:11 +0200 -Subject: [PATCH 2/6] VNC: Readd timeout when vnc viewer connection breaks. -Patch-Mainline: Currently no upstream project. -Git-commit: 759b49ed1c4ea03e45433c92c2fb8c44a60db34a -Signed-off: Egbert Eich -References: bnc #441935, bnc #403901 - -This prevents Xvnc busy loop forever waiting for a viewer that no longer -response due to network or other issues. - -Signed-off-by: Egbert Eich ---- - hw/vnc/sockets.c | 19 +++++-------------- - 1 files changed, 5 insertions(+), 14 deletions(-) - -diff --git a/hw/vnc/sockets.c b/hw/vnc/sockets.c -index 39eb88a..ae43ed0 100644 ---- a/hw/vnc/sockets.c -+++ b/hw/vnc/sockets.c -@@ -442,9 +442,7 @@ WriteExact(int sock, char *buf, int len) - int n; - fd_set fds; - struct timeval tv; --#if 0 - int totalTimeWaited = 0; --#endif - - while (len > 0) { - n = write(sock, buf, len); -@@ -464,7 +462,6 @@ WriteExact(int sock, char *buf, int len) - return n; - } - --#if 0 - /* Retry every 5 seconds until we exceed rfbMaxClientWait. We - need to do this because select doesn't necessarily return - immediately when the other end has gone away */ -@@ -473,19 +470,14 @@ WriteExact(int sock, char *buf, int len) - FD_SET(sock, &fds); - tv.tv_sec = 5; - tv.tv_usec = 0; --#else -- /* We're in the WakeupHandler now, so don't wait */ - -- FD_ZERO(&fds); -- FD_SET(sock, &fds); -- tv.tv_sec = 0; -- tv.tv_usec = 0; --#endif - n = select(sock+1, NULL, &fds, NULL, &tv); --#if 0 -+ - if (n < 0) { -- rfbLogPerror("WriteExact: select"); -- return n; -+ if (errno != EINTR) { -+ rfbLogPerror("WriteExact: select"); -+ return n; -+ } - } - if (n == 0) { - totalTimeWaited += 5000; -@@ -496,7 +488,6 @@ WriteExact(int sock, char *buf, int len) - } else { - totalTimeWaited = 0; - } --#endif - } - } - return 1; --- -1.7.3.4 - diff --git a/xorg-x11-server.changes b/xorg-x11-server.changes index f5af13e..827bad2 100644 --- a/xorg-x11-server.changes +++ b/xorg-x11-server.changes @@ -1,3 +1,18 @@ +------------------------------------------------------------------- +Fri Aug 9 13:25:41 UTC 2013 - tobias.johannes.klausmann@mni.thm.de + +- Remove the unused Xvnc packages +- Remove the now unused vnc macro +- Remove the Xvnc patches: + + Patch17: n_VNC-Add-support-for-VNC.patch + + Patch18: n_VNC-Readd-timeout-when-vnc-viewer-connection-breaks.patch + + Patch19: n_VNC-Fix-crash-when-no-depth-translation-is-required.patch + + Patch20: n_VNC-Don-t-let-VNC-access-the-framebuffer-directly-an.patch + + Patch21: n_VNC-Enable-use-of-all-keyboard-layouts-independent-o.patch + + Patch22: n_VNC-Fix-crash-due-to-unset-input-device-names.patch + + Patch23: n_Xvnc-pthread.diff + + Patch24: n_VNC-Add-proto.diff + ------------------------------------------------------------------- Thu Aug 8 19:51:35 UTC 2013 - eich@suse.com diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index 23fe874..326e259 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -19,7 +19,7 @@ Name: xorg-x11-server %define dirsuffix 1.14.2 -%define vnc 0 + Summary: X License: GPL-2.0+ and MIT Group: System/X11/Servers/XF86_4 @@ -91,10 +91,7 @@ BuildRequires: pkgconfig(xv) %if 0%{?suse_version} >= 1130 BuildRequires: pkgconfig(libudev) >= 143 %endif -%if %vnc -BuildRequires: libjpeg-devel -BuildRequires: pkgconfig(vncproto) -%endif + Version: 7.6_%{dirsuffix} Release: 0 Url: http://xorg.freedesktop.org/ @@ -116,24 +113,7 @@ Obsoletes: xorg-x11-Xvfb Obsoletes: xorg-x11-server-glx # Xvfb requires keyboard files as well (bnc#797124) Requires: xkeyboard-config -%if %vnc -# PATCH-MISSING-TAG -- See http://wiki.opensuse.org/openSUSE:Packaging_Patches_guidelines -Patch17: n_VNC-Add-support-for-VNC.patch -# PATCH-MISSING-TAG -- See http://wiki.opensuse.org/openSUSE:Packaging_Patches_guidelines -Patch18: n_VNC-Readd-timeout-when-vnc-viewer-connection-breaks.patch -# PATCH-MISSING-TAG -- See http://wiki.opensuse.org/openSUSE:Packaging_Patches_guidelines -Patch19: n_VNC-Fix-crash-when-no-depth-translation-is-required.patch -# PATCH-MISSING-TAG -- See http://wiki.opensuse.org/openSUSE:Packaging_Patches_guidelines -Patch20: n_VNC-Don-t-let-VNC-access-the-framebuffer-directly-an.patch -# PATCH-MISSING-TAG -- See http://wiki.opensuse.org/openSUSE:Packaging_Patches_guidelines -Patch21: n_VNC-Enable-use-of-all-keyboard-layouts-independent-o.patch -# PATCH-MISSING-TAG -- See http://wiki.opensuse.org/openSUSE:Packaging_Patches_guidelines -Patch22: n_VNC-Fix-crash-due-to-unset-input-device-names.patch -# PATCH-MISSING-TAG -- See http://wiki.opensuse.org/openSUSE:Packaging_Patches_guidelines -Patch23: n_Xvnc-pthread.diff -# PATCH-MISSING-TAG -- See http://wiki.opensuse.org/openSUSE:Packaging_Patches_guidelines -Patch24: n_VNC-Add-proto.diff -%endif + # PATCH-MISSING-TAG -- See http://wiki.opensuse.org/openSUSE:Packaging_Patches_guidelines Patch45: N_bug-197858_dpms.diff # PATCH-MISSING-TAG -- See http://wiki.opensuse.org/openSUSE:Packaging_Patches_guidelines @@ -230,27 +210,6 @@ Obsoletes: xorg-x11-sdk %description sdk This package contains the X.Org Server SDK. -%if %vnc - -%package -n xorg-x11-Xvnc -Summary: VNC Server for the X Window System -Group: System/X11/Servers/XF86_4 -Requires: xkbcomp -Requires: xkeyboard-config -Requires: xorg-x11-fonts-core -Provides: XFree86-Xvnc -Provides: vnc:/usr/X11R6/bin/Xvnc -Obsoletes: XFree86-Xvnc -%ifarch ia64 -Provides: vnc-x86 -Obsoletes: vnc-x86 -%endif - -%description -n xorg-x11-Xvnc -An X Window System server for Virtual Network Computing (VNC). - -%endif - %prep %setup -q -n xorg-server-%{dirsuffix} -a4 # Early verification if the ABI Defines are correct. Let's not waste build cycles if the Provides are wrong at the end. @@ -259,18 +218,7 @@ cp %{SOURCE96} . %patch0 -p1 %patch2 %patch16 -p1 -%if %vnc -### Needs to be rebased -#%patch17 -p1 -#%patch18 -p1 -#%patch19 -p1 -#%patch20 -p1 -#%patch21 -p1 -#%patch22 -p1 -#%patch23 -p1 -#%patch24 -p1 -%endif ### Needs to be rebased #%patch45 -p0 %patch77 @@ -332,9 +280,6 @@ autoreconf -fi %if 0%{?suse_version} > 1120 --enable-config-udev \ %endif -%endif -%if %vnc - --disable-xcliplist \ %endif --with-log-dir="/var/log" \ --with-os-name="openSUSE" \ @@ -382,14 +327,6 @@ install -m 644 $RPM_SOURCE_DIR/modprobe.nvidia %{buildroot}%{_sysconfdir}/modpro %else rm -f %{buildroot}%{_datadir}/aclocal/*.m4 %endif -%if %vnc -mkdir -p %{buildroot}%{_sysconfdir}/sysconfig/SuSEfirewall2.d/services -cat > %{buildroot}%{_sysconfdir}/sysconfig/SuSEfirewall2.d/services/%{name} << EOF -## Name: VNC Server -## Description: Opens ports for VNC Server -TCP="5801 5901" -EOF -%endif %ifarch s390 s390x rm -f %{buildroot}%{_sysconfdir}/X11/10-evdev.conf make -C hw/xfree86/parser @@ -505,12 +442,5 @@ exit 0 %{_datadir}/aclocal/*.m4 %endif %{_sysconfdir}/rpm/macros.xorg-server -%if %vnc - -%files -n xorg-x11-Xvnc -%defattr(-, root, root) -%{_sysconfdir}/sysconfig/SuSEfirewall2.d/services/%{name} -#%{_bindir}/Xvnc -%endif %changelog